fix(agent): admit and sync gateway-staged attachments on remote execution backends (#110174)
Desktop paste/file attachments land in Hermes-managed staging dirs on the GATEWAY (composer-pastes/ for large text pastes, attachments/ for dropped files), but on the Remote SSH topology the workspace root (TERMINAL_CWD) is a path on the SSH HOST - the two filesystems are fully disjoint, as the issue thread confirms. Two gaps combined to reject every staged attachment with "path is outside the allowed workspace": - _resolve_path admitted only allowed_root + composer-paste roots, so a gateway-staged attachments/ path was refused outright. Admit the _CACHE_DIRS staging roots (attachments/, images/, cache/*, composer-pastes/) via a helper that asks get_cache_directory_mounts - the gateway's OWN payload is never a workspace escape, and the path-traversal and credential-deny guards in _ensure_reference_path_allowed still run after. Anything else outside the workspace stays blocked. - composer-pastes/ was missing from _CACHE_DIRS, so its bytes never reached the remote: ssh/daytona/vercel_sandbox sync via iter_sync_files -> iter_cache_files, and to_agent_visible_cache_path only translates mounted dirs - a paste attached on a fresh session dangled on the remote host. Tests cover the disjoint-filesystem SSH topology end-to-end (text inlines, binary renders the synced ~/.hermes path), the still-refused stranger path, local-backend unchanged, and the composer-pastes mount+sync enumeration. Consolidates PR #110387 by Finn763 (the _agent_staged_path guard widening and the SSH-topology tests, adapted to the current _ensure_reference_path_allowed ordering) with PR #103412 by ericmaddox (whose mapping insight is subsumed by the _CACHE_DIRS entry, which fixes both the sync and the translation). Co-authored-by: ericmaddox <ericmaddox@users.noreply.github.com>
This commit is contained in:
@@ -258,6 +258,13 @@ _CACHE_DIRS: list[tuple[str, str]] = [
|
||||
# Mount it so the agent's file tools can read dropped binaries (zip/pdf/...) from inside sandbox
|
||||
# containers instead of dangling host paths (#76577).
|
||||
("attachments", "attachments"),
|
||||
# Desktop stages a large plain-text paste as a `.txt` under this Hermes-managed dir
|
||||
# (apps/desktop/electron/composer-paste.ts; `COMPOSER_PASTES_DIRNAME` in
|
||||
# agent/context_references.py) and attaches it as `@file:`. Without a mount/sync
|
||||
# entry, remote execution backends (ssh/daytona/vercel_sandbox) never received the
|
||||
# bytes and `to_agent_visible_cache_path` left the gateway-host path dangling on
|
||||
# the remote host (#110174). No legacy alias, so both tuple slots match.
|
||||
("composer-pastes", "composer-pastes"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user