fix(exec): isolate exec session managers
This commit is contained in:
@@ -28,6 +28,7 @@ from nanobot.agent.model_runtime import ModelRuntimeResolver
|
||||
from nanobot.agent.runner import _MAX_INJECTIONS_PER_TURN, AgentRunner, AgentRunSpec
|
||||
from nanobot.agent.subagent import SubagentManager
|
||||
from nanobot.agent.tools.context import RequestContext, bind_request_context, reset_request_context
|
||||
from nanobot.agent.tools.exec_session import ExecSessionManager
|
||||
from nanobot.agent.tools.file_state import FileStateStore, bind_file_states, reset_file_states
|
||||
from nanobot.agent.tools.message import MessageTool
|
||||
from nanobot.agent.tools.registry import ToolRegistry
|
||||
@@ -355,6 +356,7 @@ class AgentLoop:
|
||||
# One file-read/write tracker per logical session. The tool registry is
|
||||
# shared by this loop, so tools resolve the active state via contextvars.
|
||||
self._file_state_store = FileStateStore()
|
||||
self._exec_session_manager = ExecSessionManager()
|
||||
self.runner = AgentRunner()
|
||||
self.subagents = SubagentManager(
|
||||
workspace=workspace,
|
||||
@@ -540,6 +542,7 @@ class AgentLoop:
|
||||
bus=self.bus,
|
||||
subagent_manager=self.subagents,
|
||||
cron_service=self.cron_service,
|
||||
exec_session_manager=self._exec_session_manager,
|
||||
sessions=self.sessions,
|
||||
provider_snapshot_loader=provider_snapshot_loader,
|
||||
image_generation_provider_configs=self._image_generation_provider_configs,
|
||||
|
||||
@@ -19,6 +19,7 @@ from nanobot.agent.tools.context import (
|
||||
bind_request_context,
|
||||
reset_request_context,
|
||||
)
|
||||
from nanobot.agent.tools.exec_session import ExecSessionManager
|
||||
from nanobot.agent.tools.file_state import FileStates
|
||||
from nanobot.agent.tools.loader import ToolLoader
|
||||
from nanobot.agent.tools.registry import ToolRegistry
|
||||
@@ -143,6 +144,7 @@ class SubagentManager:
|
||||
else defaults.fail_on_tool_error
|
||||
)
|
||||
self.runner = AgentRunner()
|
||||
self._exec_session_manager = ExecSessionManager()
|
||||
self._llm_wall_timeout_for_session = llm_wall_timeout_for_session
|
||||
self._running_tasks: dict[str, asyncio.Task[None]] = {}
|
||||
self._task_statuses: dict[str, SubagentStatus] = {}
|
||||
@@ -204,6 +206,7 @@ class SubagentManager:
|
||||
ctx = ToolContext(
|
||||
config=cfg,
|
||||
workspace=str(root.resolve()),
|
||||
exec_session_manager=self._exec_session_manager,
|
||||
file_state_store=FileStates(),
|
||||
workspace_sandbox=workspace_sandbox_status(
|
||||
restrict_to_workspace=cfg.restrict_to_workspace,
|
||||
|
||||
@@ -71,6 +71,7 @@ class ToolContext:
|
||||
bus: Any | None = None
|
||||
subagent_manager: Any | None = None
|
||||
cron_service: Any | None = None
|
||||
exec_session_manager: Any | None = None
|
||||
sessions: Any | None = None
|
||||
file_state_store: Any = field(default=None)
|
||||
provider_snapshot_loader: Callable[[], Any] | None = None
|
||||
|
||||
@@ -250,11 +250,7 @@ class ExecSessionManager:
|
||||
session = self._sessions.get(session_id)
|
||||
if session is None:
|
||||
raise KeyError(session_id)
|
||||
if (
|
||||
owner_session_key
|
||||
and session.owner_session_key
|
||||
and session.owner_session_key != owner_session_key
|
||||
):
|
||||
if session.owner_session_key and session.owner_session_key != owner_session_key:
|
||||
raise KeyError(session_id)
|
||||
|
||||
if chars:
|
||||
@@ -296,9 +292,7 @@ class ExecSessionManager:
|
||||
owner_session_key=session.owner_session_key,
|
||||
)
|
||||
for session_id, session in sorted(self._sessions.items())
|
||||
if not owner_session_key
|
||||
or not session.owner_session_key
|
||||
or session.owner_session_key == owner_session_key
|
||||
if session.owner_session_key == owner_session_key
|
||||
]
|
||||
|
||||
async def _cleanup_locked(self) -> None:
|
||||
@@ -442,7 +436,7 @@ class WriteStdinTool(Tool):
|
||||
|
||||
@classmethod
|
||||
def create(cls, ctx: Any) -> Tool:
|
||||
return cls()
|
||||
return cls(manager=getattr(ctx, "exec_session_manager", None))
|
||||
|
||||
@property
|
||||
def exclusive(self) -> bool:
|
||||
@@ -586,7 +580,7 @@ class ListExecSessionsTool(Tool):
|
||||
|
||||
@classmethod
|
||||
def create(cls, ctx: Any) -> Tool:
|
||||
return cls()
|
||||
return cls(manager=getattr(ctx, "exec_session_manager", None))
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
|
||||
@@ -188,6 +188,7 @@ class ExecTool(Tool):
|
||||
allowed_env_keys=cfg.allowed_env_keys,
|
||||
allow_patterns=cfg.allow_patterns,
|
||||
deny_patterns=cfg.deny_patterns,
|
||||
session_manager=getattr(ctx, "exec_session_manager", None),
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
||||
Reference in New Issue
Block a user