fix(agent): resolve message media against active workspace

Made-with: Cursor
This commit is contained in:
Xubin Ren 2026-04-27 06:29:04 +00:00 committed by Xubin Ren
parent 9b3e2524ac
commit 9b6f3d7abc
3 changed files with 25 additions and 2 deletions

View File

@ -368,7 +368,7 @@ class AgentLoop:
WebSearchTool(config=self.web_config.search, proxy=self.web_config.proxy)
)
self.tools.register(WebFetchTool(proxy=self.web_config.proxy))
self.tools.register(MessageTool(send_callback=self.bus.publish_outbound))
self.tools.register(MessageTool(send_callback=self.bus.publish_outbound, workspace=self.workspace))
self.tools.register(SpawnTool(manager=self.subagents))
if self.cron_service:
self.tools.register(

View File

@ -2,6 +2,7 @@
import os
from contextvars import ContextVar
from pathlib import Path
from typing import Any, Awaitable, Callable
from nanobot.agent.tools.base import Tool, tool_parameters
@ -35,8 +36,10 @@ class MessageTool(Tool):
default_channel: str = "",
default_chat_id: str = "",
default_message_id: str | None = None,
workspace: str | Path | None = None,
):
self._send_callback = send_callback
self._workspace = Path(workspace).expanduser() if workspace is not None else get_workspace_path()
self._default_channel: ContextVar[str] = ContextVar("message_default_channel", default=default_channel)
self._default_chat_id: ContextVar[str] = ContextVar("message_default_chat_id", default=default_chat_id)
self._default_message_id: ContextVar[str | None] = ContextVar(
@ -149,7 +152,7 @@ class MessageTool(Tool):
if p.startswith(("http://", "https://")) or os.path.isabs(p):
resolved.append(p)
else:
resolved.append(str(get_workspace_path() / p))
resolved.append(str(self._workspace / p))
media = resolved
metadata = dict(self._default_metadata.get()) if same_target else {}

View File

@ -110,6 +110,26 @@ async def test_message_tool_resolves_relative_media_paths() -> None:
assert sent[0].media == [expected]
@pytest.mark.asyncio
async def test_message_tool_resolves_relative_media_paths_from_active_workspace(tmp_path) -> None:
sent: list[OutboundMessage] = []
async def _send(msg: OutboundMessage) -> None:
sent.append(msg)
workspace = tmp_path / "workspace"
tool = MessageTool(send_callback=_send, workspace=workspace)
await tool.execute(
content="see attached",
channel="telegram",
chat_id="1",
media=["output/image.png"],
)
assert sent[0].media == [str(workspace / "output/image.png")]
@pytest.mark.asyncio
async def test_message_tool_passes_through_absolute_media_paths() -> None:
sent: list[OutboundMessage] = []