reset sandbox per skill invocation to prevent state leaks

This commit is contained in:
Yiorgis Gozadinos 2026-04-20 12:18:14 +03:00
parent 167c837514
commit 9d921b13fe
No known key found for this signature in database

View file

@ -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)