mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +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:
|
||||
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"}
|
||||
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 = 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/"):
|
||||
context_note = (
|
||||
f"[The user sent a text document: '{display_name}'. "
|
||||
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:
|
||||
context_note = (
|
||||
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.]"
|
||||
)
|
||||
message_text = f"{context_note}\n\n{message_text}"
|
||||
|
|
|
|||
|
|
@ -374,6 +374,34 @@ def get_cache_directory_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(
|
||||
container_base: str = "/root/.hermes",
|
||||
) -> List[Dict[str, str]]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue