Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5499,6 +5499,7 @@ async def _prepare_inbound_message_text(

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):
Expand All @@ -5519,16 +5520,21 @@ async def _prepare_inbound_message_text(
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}"
Expand Down
30 changes: 30 additions & 0 deletions tools/credential_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,36 @@ 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).
"""
from hermes_constants import get_hermes_dir
from tools.terminal_tool import get_effective_backend

# Only Docker backend requires translation at this time. Other backends
# (Modal, Daytona, Vercel) use different mount semantics and will be
# addressed separately if needed.
if get_effective_backend() != "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]]:
Expand Down
Loading