Source code for dataguy.context_manager
# context_manager.py
import builtins
import types
import pandas as pd
import numpy as np
[docs]
class ContextManager:
"""
Tracks a concise Python execution context for LLM prompts:
- Non-private module imports
- Relevant variables (DataFrames, arrays, primitives, lists, dicts)
- Recent executed code history
"""
[docs]
def __init__(self, max_code_history=100):
self.imported_packages = set()
self.variables = {}
self.code_history = []
self.max_code_history = max_code_history
def update_from_globals(self, globals_dict):
"""
Rebuilds the context from the given globals dictionary,
keeping only non-private modules and meaningful variables.
"""
# Reset previous context
self.imported_packages.clear()
self.variables.clear()
# 1) Track non-private module imports
for name, obj in globals_dict.items():
if isinstance(obj, types.ModuleType) and not name.startswith('_'):
self.imported_packages.add(name)
# 2) Track only “interesting” variables
for name, obj in globals_dict.items():
# Skip private names, builtins, modules, and callables
if (
name.startswith('_') or
name in builtins.__dict__ or
isinstance(obj, types.ModuleType) or
callable(obj)
):
continue
# Keep DataFrame, ndarray, list, dict, primitives
if isinstance(obj, (pd.DataFrame, np.ndarray, list, dict, int, float, str, bool)):
t = type(obj).__name__
# Show shape for arrays/DataFrames
if hasattr(obj, 'shape'):
self.variables[name] = f"{t}{obj.shape}"
else:
self.variables[name] = t
def add_code(self, code: str):
"""
Appends executed code lines to history (up to max length).
"""
lines = code.strip().split('\n')
self.code_history.extend(lines)
if len(self.code_history) > self.max_code_history:
self.code_history = self.code_history[-self.max_code_history:]
def get_context_summary(self) -> str:
"""
Returns a markdown-like summary:
- Imports
- Variables
- Recent code history
"""
lines = ["# CONTEXT", ""]
# Imports
lines.append("## Imports")
lines.append(", ".join(sorted(self.imported_packages)) or "None")
# Variables
lines.append("\n## Variables")
if self.variables:
for k, v in sorted(self.variables.items()):
lines.append(f"- {k}: {v}")
else:
lines.append("None")
# Code history
lines.append("\n## Code History")
if self.code_history:
lines.append("```python")
lines.extend(self.code_history)
lines.append("```")
else:
lines.append("None")
return "\n".join(lines)