diff --git a/src/frontend/dashboard/server.py b/src/frontend/dashboard/server.py index c3d3bac..4bb2d1a 100644 --- a/src/frontend/dashboard/server.py +++ b/src/frontend/dashboard/server.py @@ -621,7 +621,8 @@ async def _with_client( self, username: str = "", timeout_seconds: float | None = None ) -> AutomationIPCClient: owner_id = username.strip() or "root" - source = "web" if username.strip() else "dashboard" + # Memory paths and session IDs use the web: prefix; keep IPC source aligned. + source = "web" kwargs: Dict[str, Any] = { "source": source, "owner_id": owner_id, @@ -736,9 +737,7 @@ async def chat(self, text: str, *, session_id: str | None = None, username: str "token_usage": usage, "turn_count": turn_count, } - result = await client.run_turn( - AgentRunInput(text=text, metadata={"source": "dashboard"}) - ) + result = await client.run_turn(AgentRunInput(text=text)) usage = await client.get_token_usage() turn_count = await client.get_turn_count() return { @@ -841,7 +840,7 @@ async def _on_ask_user_notify( async def _runner() -> None: try: holder["result"] = await client.run_turn( - AgentRunInput(text=text, metadata={"source": "dashboard"}), + AgentRunInput(text=text), hooks=hooks, ) except Exception as exc: # noqa: BLE001 diff --git a/src/system/kernel/core_pool.py b/src/system/kernel/core_pool.py index d219e14..615eb90 100644 --- a/src/system/kernel/core_pool.py +++ b/src/system/kernel/core_pool.py @@ -78,7 +78,7 @@ def _resolve_core_owner( sid = (session_id or "").strip() src = (source or "").strip() or "cli" uid = (user_id or "").strip() or "root" - if not sid.startswith(("feishu:", "sub:", "cron:", "shuiyuan:")): + if not sid.startswith(("feishu:", "sub:", "cron:", "shuiyuan:", "web:")): return src, uid inferred_s, inferred_u = _infer_owner_from_session_id(sid) if src == "cli": diff --git a/tests/test_core_owner_resolve.py b/tests/test_core_owner_resolve.py index 8327104..96328f4 100644 --- a/tests/test_core_owner_resolve.py +++ b/tests/test_core_owner_resolve.py @@ -35,3 +35,11 @@ def test_resolve_fills_feishu_user_when_root_placeholder(): def test_resolve_leaves_cli_session_alone(): assert _resolve_core_owner("cli:root", "cli", "root") == ("cli", "root") + + +def test_resolve_overrides_cli_default_for_web_session(): + assert _resolve_core_owner("web:alice", "cli", "root") == ("web", "alice") + + +def test_resolve_keeps_explicit_web_owner(): + assert _resolve_core_owner("web:alice", "web", "alice") == ("web", "alice") diff --git a/tests/test_kernel_runtime.py b/tests/test_kernel_runtime.py index 8b35b2b..a64b322 100644 --- a/tests/test_kernel_runtime.py +++ b/tests/test_kernel_runtime.py @@ -61,6 +61,17 @@ def test_memory_owner_agent_msg_uses_session_id_not_frontend_tag() -> None: assert memory_owner_for_kernel_acquire(req3) == ("cli", "root") +def test_dashboard_web_session_memory_owner_matches_history_path() -> None: + """Dashboard IPC uses source=web; gateway must not override to dashboard:*.""" + req = KernelRequest.create( + text="hi", + session_id="web:alice", + frontend_id="web", + metadata={"source": "web", "user_id": "alice"}, + ) + assert memory_owner_for_kernel_acquire(req) == ("web", "alice") + + @pytest.mark.asyncio async def test_kernel_propagates_return_status_in_metadata() -> None: from agent_core.kernel_interface.action import ReturnAction