open-swe/agent/utils/sandbox_state.py
Brace Sproul bd52e5e09d
chore: Drop monorepo (#1029)
* chore: Drop monorepo

* cr
2026-03-06 16:10:34 -08:00

46 lines
1.4 KiB
Python

"""Shared sandbox state used by server and middleware."""
from __future__ import annotations
import asyncio
import logging
from typing import Any
from langgraph.config import get_config
from ..integrations.langsmith import create_langsmith_sandbox
logger = logging.getLogger(__name__)
# Thread ID -> SandboxBackend mapping, shared between server.py and middleware
SANDBOX_BACKENDS: dict[str, Any] = {}
async def get_sandbox_id_from_metadata(thread_id: str) -> str | None:
"""Fetch sandbox_id from thread metadata."""
try:
config = get_config()
except Exception:
logger.exception("Failed to read thread metadata for sandbox")
return None
return config.get("metadata", {}).get("sandbox_id")
async def get_sandbox_backend(thread_id: str) -> Any | None:
"""Get sandbox backend from cache, or connect using thread metadata."""
sandbox_backend = SANDBOX_BACKENDS.get(thread_id)
if sandbox_backend:
return sandbox_backend
sandbox_id = await get_sandbox_id_from_metadata(thread_id)
if not sandbox_id:
raise ValueError(f"Missing sandbox_id in thread metadata for {thread_id}")
sandbox_backend = await asyncio.to_thread(create_langsmith_sandbox, sandbox_id)
SANDBOX_BACKENDS[thread_id] = sandbox_backend
return sandbox_backend
def get_sandbox_backend_sync(thread_id: str) -> Any | None:
"""Sync wrapper for get_sandbox_backend."""
return asyncio.run(get_sandbox_backend(thread_id))