fix: bind webui cron jobs to visible session

This commit is contained in:
chengyongru 2026-06-12 00:28:12 +08:00
parent 29f1473940
commit e46a99ced9
2 changed files with 54 additions and 0 deletions

View File

@ -528,6 +528,12 @@ class AgentLoop:
effective_key = UNIFIED_SESSION_KEY
else:
effective_key = f"{channel}:{chat_id}"
effective_key = self._tool_context_session_key(
channel=channel,
chat_id=chat_id,
metadata=metadata,
session_key=effective_key,
)
request_ctx = RequestContext(
channel=channel,
@ -542,6 +548,24 @@ class AgentLoop:
if tool and isinstance(tool, ContextAware):
tool.set_context(request_ctx)
def _tool_context_session_key(
self,
*,
channel: str,
chat_id: str,
metadata: dict | None,
session_key: str,
) -> str:
"""Return the session key tools should use for ownership-scoped resources."""
if (
self._unified_session
and channel == "websocket"
and (metadata or {}).get("webui") is True
and chat_id
):
return f"websocket:{chat_id}"
return session_key
@staticmethod
def _runtime_chat_id(msg: InboundMessage) -> str:
"""Return the chat id shown in runtime metadata for the model."""

View File

@ -4,6 +4,7 @@ import asyncio
import pytest
from nanobot.agent.loop import AgentLoop
from nanobot.agent.tools.context import RequestContext
from nanobot.agent.tools.cron import CronTool
from nanobot.agent.tools.message import MessageTool
@ -243,6 +244,35 @@ async def test_cron_tool_basic_set_context_and_execute(tmp_path) -> None:
assert jobs[0].payload.session_key == "wechat:user-789"
@pytest.mark.asyncio
async def test_webui_cron_tool_uses_visible_session_under_unified_session(tmp_path) -> None:
"""WebUI-created automations should attach to the visible thread, not unified memory."""
tool = CronTool(CronService(tmp_path / "jobs.json"))
class _Tools:
tool_names = ["cron"]
def get(self, name: str):
return tool if name == "cron" else None
loop = object.__new__(AgentLoop)
loop._unified_session = True
loop.tools = _Tools()
loop._set_tool_context(
"websocket",
"chat-123",
metadata={"webui": True},
session_key="unified:default",
)
result = await tool.execute(action="add", message="standup", every_seconds=300)
assert result.startswith("Created job")
jobs = tool._cron.list_jobs()
assert len(jobs) == 1
assert jobs[0].payload.session_key == "websocket:chat-123"
@pytest.mark.asyncio
async def test_cron_tool_no_context_returns_error(tmp_path) -> None:
"""Without set_context, add should fail with a clear error."""