diff --git a/haiku_rag_slim/haiku/rag/skills/_tools.py b/haiku_rag_slim/haiku/rag/skills/_tools.py index 22c17b8b..28821d00 100644 --- a/haiku_rag_slim/haiku/rag/skills/_tools.py +++ b/haiku_rag_slim/haiku/rag/skills/_tools.py @@ -240,7 +240,7 @@ def create_skill_tools( tools["get_document"] = get_document if "execute_code" in tool_names: - _sandbox: list[Any] = [] # mutable container for closure; holds [Sandbox] or [] + _sandbox_state: dict[str, Any] = {} # {run_id, sandbox} — reset per invocation async def execute_code(ctx: RunContext[SkillRunDeps], code: str) -> str: """Execute Python code in a sandboxed interpreter. @@ -249,7 +249,8 @@ def create_skill_tools( and a virtual filesystem at /documents/ with document content and structure (metadata.json, content.txt, items.jsonl per document). - Use print() to output results. Variables persist between calls. + Use print() to output results. Variables persist between calls + within the same skill invocation. Args: code: Python code to execute. @@ -257,15 +258,17 @@ def create_skill_tools( from haiku.rag.agents.analysis.dependencies import AnalysisContext from haiku.rag.agents.analysis.sandbox import Sandbox - if not _sandbox: + rid = ctx.run_id or "" + if _sandbox_state.get("run_id") != rid: state = _get_state(ctx, state_type) doc_filter = state.document_filter if state else None context = AnalysisContext(filter=doc_filter) - _sandbox.append( - Sandbox(db_path=db_path, config=config, context=context) + _sandbox_state["run_id"] = rid + _sandbox_state["sandbox"] = Sandbox( + db_path=db_path, config=config, context=context ) - sandbox = _sandbox[0] + sandbox = _sandbox_state["sandbox"] result = await sandbox.execute(code) state = _get_state(ctx, state_type)