mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-15 04:12:25 +00:00
fix(gateway): translate inbound document host paths to container paths for Docker backend
When terminal.backend is docker, inbound documents uploaded via messaging platforms (Telegram, Slack, Discord, Feishu, Email, etc.) are cached at a host path under ~/.hermes/cache/documents, but the container sandbox only sees them at the auto-mounted /root/.hermes/cache/documents path. This PR adds to_agent_visible_cache_path() in tools/credential_files.py (the natural sibling to get_cache_directory_mounts()) and calls it at the document-context-injection site in gateway/run.py so the agent always receives a path it can open directly, matching the mount layout already established by get_cache_directory_mounts() (#4846). Scope: only Docker backend for now; other backends use different mount semantics and are left unchanged until verified. Fixes #18787
This commit is contained in:
parent
d4de7d4179
commit
7c0766e06a
2 changed files with 36 additions and 2 deletions
|
|
@ -5757,6 +5757,7 @@ class GatewayRunner:
|
||||||
|
|
||||||
if event.media_urls and event.message_type == MessageType.DOCUMENT:
|
if event.media_urls and event.message_type == MessageType.DOCUMENT:
|
||||||
import mimetypes as _mimetypes
|
import mimetypes as _mimetypes
|
||||||
|
from tools.credential_files import to_agent_visible_cache_path
|
||||||
|
|
||||||
_TEXT_EXTENSIONS = {".txt", ".md", ".csv", ".log", ".json", ".xml", ".yaml", ".yml", ".toml", ".ini", ".cfg"}
|
_TEXT_EXTENSIONS = {".txt", ".md", ".csv", ".log", ".json", ".xml", ".yaml", ".yml", ".toml", ".ini", ".cfg"}
|
||||||
for i, path in enumerate(event.media_urls):
|
for i, path in enumerate(event.media_urls):
|
||||||
|
|
@ -5777,16 +5778,21 @@ class GatewayRunner:
|
||||||
display_name = parts[2] if len(parts) >= 3 else basename
|
display_name = parts[2] if len(parts) >= 3 else basename
|
||||||
display_name = re.sub(r'[^\w.\- ]', '_', display_name)
|
display_name = re.sub(r'[^\w.\- ]', '_', display_name)
|
||||||
|
|
||||||
|
# Translate host cache path to in-container path if running under Docker backend.
|
||||||
|
# This ensures the agent receives a path it can open inside its sandbox, as the
|
||||||
|
# cache directories are auto-mounted at /root/.hermes/cache/* by get_cache_directory_mounts().
|
||||||
|
agent_path = to_agent_visible_cache_path(path)
|
||||||
|
|
||||||
if mtype.startswith("text/"):
|
if mtype.startswith("text/"):
|
||||||
context_note = (
|
context_note = (
|
||||||
f"[The user sent a text document: '{display_name}'. "
|
f"[The user sent a text document: '{display_name}'. "
|
||||||
f"Its content has been included below. "
|
f"Its content has been included below. "
|
||||||
f"The file is also saved at: {path}]"
|
f"The file is also saved at: {agent_path}]"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
context_note = (
|
context_note = (
|
||||||
f"[The user sent a document: '{display_name}'. "
|
f"[The user sent a document: '{display_name}'. "
|
||||||
f"The file is saved at: {path}. "
|
f"The file is saved at: {agent_path}. "
|
||||||
f"Ask the user what they'd like you to do with it.]"
|
f"Ask the user what they'd like you to do with it.]"
|
||||||
)
|
)
|
||||||
message_text = f"{context_note}\n\n{message_text}"
|
message_text = f"{context_note}\n\n{message_text}"
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,34 @@ def get_cache_directory_mounts(
|
||||||
return mounts
|
return mounts
|
||||||
|
|
||||||
|
|
||||||
|
def to_agent_visible_cache_path(
|
||||||
|
host_path: str,
|
||||||
|
container_base: str = "/root/.hermes",
|
||||||
|
) -> str:
|
||||||
|
"""Translate a host cache path to its mounted path inside the sandbox.
|
||||||
|
|
||||||
|
Returns the input unchanged if it is not under any auto-mounted cache
|
||||||
|
directory, or if the active terminal backend does not require path
|
||||||
|
translation (only Docker for now).
|
||||||
|
"""
|
||||||
|
# Only Docker backend requires translation at this time. Other backends
|
||||||
|
# (Modal, Daytona, Vercel) use different mount semantics and will be
|
||||||
|
# addressed separately if needed. Backend is identified by TERMINAL_ENV
|
||||||
|
# (same env var tools/terminal_tool.py reads in _get_environment_config).
|
||||||
|
if os.environ.get("TERMINAL_ENV", "local") != "docker":
|
||||||
|
return host_path
|
||||||
|
|
||||||
|
path = Path(host_path)
|
||||||
|
for mount in get_cache_directory_mounts(container_base=container_base):
|
||||||
|
host_dir = Path(mount["host_path"])
|
||||||
|
try:
|
||||||
|
rel = path.relative_to(host_dir)
|
||||||
|
return str(Path(mount["container_path"]) / rel)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
return host_path
|
||||||
|
|
||||||
|
|
||||||
def iter_cache_files(
|
def iter_cache_files(
|
||||||
container_base: str = "/root/.hermes",
|
container_base: str = "/root/.hermes",
|
||||||
) -> List[Dict[str, str]]:
|
) -> List[Dict[str, str]]:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue