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 effective_key = UNIFIED_SESSION_KEY
else: else:
effective_key = f"{channel}:{chat_id}" 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( request_ctx = RequestContext(
channel=channel, channel=channel,
@ -542,6 +548,24 @@ class AgentLoop:
if tool and isinstance(tool, ContextAware): if tool and isinstance(tool, ContextAware):
tool.set_context(request_ctx) 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 @staticmethod
def _runtime_chat_id(msg: InboundMessage) -> str: def _runtime_chat_id(msg: InboundMessage) -> str:
"""Return the chat id shown in runtime metadata for the model.""" """Return the chat id shown in runtime metadata for the model."""

View File

@ -4,6 +4,7 @@ import asyncio
import pytest import pytest
from nanobot.agent.loop import AgentLoop
from nanobot.agent.tools.context import RequestContext from nanobot.agent.tools.context import RequestContext
from nanobot.agent.tools.cron import CronTool from nanobot.agent.tools.cron import CronTool
from nanobot.agent.tools.message import MessageTool 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" 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 @pytest.mark.asyncio
async def test_cron_tool_no_context_returns_error(tmp_path) -> None: async def test_cron_tool_no_context_returns_error(tmp_path) -> None:
"""Without set_context, add should fail with a clear error.""" """Without set_context, add should fail with a clear error."""