galaxis-agent/agent/utils/sandbox_state.py

47 lines
1.4 KiB
Python
Raw Normal View History

2026-03-20 14:38:07 +09:00
"""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 .sandbox import create_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_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))