Skip to content

feat(platform): add durable files shared across agent sessions - #5268

Merged
mmabrouk merged 1 commit into
big-agentsfrom
feat/agent-mounts-v2
Jul 13, 2026
Merged

feat(platform): add durable files shared across agent sessions#5268
mmabrouk merged 1 commit into
big-agentsfrom
feat/agent-mounts-v2

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

Session mounts keep files for one conversation. Agents still had nowhere to keep a note or artifact that another conversation could read.

This adds one durable S3-backed folder per agent. The folder is keyed by the workflow artifact id, shared across that agent's sessions, and visible in the Session Inspector. The PR is stacked directly on Mount File Viewer (#5204). It contains no Daytona Secret Delivery changes.

Changes

The API adds agent-mount sign and query endpoints beside the existing session-mount endpoints. Signing the same artifact id returns the same mount; different agents receive isolated mounts.

The runner mounts the durable folder separately from the session cwd and exposes it as agent-files/. A short system-prompt segment tells the harness that the session cwd is conversation storage and agent-files/ is shared agent storage. The runner keeps the author's AGENTS.md and CLAUDE.md unchanged.

The Session Inspector shows one Agent files section with Session (this conversation) nested inside it. Refresh invalidates both mount metadata and cached file listings.

The QA pass also fixed two local mount failure paths. A missing FUSE device now falls back only after process termination and detach are confirmed, and util-linux exit code 32 is correctly recognized as not mounted. The runner never recursively deletes a path whose mount state is uncertain.

Tests / notes

  • Runner focused suite: 170 tests passed across agent mounts, mount lifecycle, orchestration, workspace, and session pooling.
  • Runner TypeScript type-check passed.
  • API agent-mount unit suite: 8 tests passed.
  • Canonical web unit layer passed: 4 annotation files, 57 entity files, 16 playground files, 10 entity-ui files, and 9 shared files.
  • Prettier and the pre-push web lint suite passed.
  • Live QA: one session wrote agent-files/user-qa.txt; a different session on the same agent read the exact value. The mount API returned the same file and content.

What to QA

  • In an agent conversation, write sample.txt in the cwd. A new conversation should not see it because it belongs to the first session.
  • Write agent-files/shared-notes.md. A new conversation for the same agent should read it.
  • Open Session Inspector > Mounts. Agent files should contain the shared file, with Session (this conversation) nested underneath.
  • Use Terminal and Write in a Claude run. Both should work; Claude's private .claude runtime directory must not appear as agent storage.
  • Regression: run an agent without an artifact id. It should continue without creating an agent mount.

Review order

  1. API sign/query behavior and tenant scoping.
  2. Runner signing, mounting, discovery guidance, and cleanup invariants.
  3. Session Inspector artifact-id plumbing and nested mount presentation.

This PR should merge after #5204 because its web diff extends Mount File Viewer.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds artifact-scoped agent mounts across the API, sandbox runner, and session inspector. The change includes deterministic mount lookup, local and remote mount setup, stronger detach safety, workflow artifact propagation, and agent-file rendering.

Changes

Agent mount API

Layer / File(s) Summary
Agent mount contracts and persistence
api/oss/src/core/mounts/*, api/oss/src/dbs/postgres/mounts/dao.py, api/oss/src/apis/fastapi/mounts/models.py
Adds UUID-based agent slug generation, mount lookup by slug, request validation, and idempotent agent mount service operations.
Agent mount routes and validation
api/oss/src/apis/fastapi/mounts/router.py
Adds /agents/sign and /agents/query handlers and maps invalid artifact IDs to HTTP 422 responses.
Agent mount behavioral coverage
api/oss/tests/pytest/{unit,acceptance}/mounts/*
Covers slugging, signing, querying, idempotency, archive/resign behavior, and invalid artifact IDs.

Sandbox agent mounts

Layer / File(s) Summary
Agent mount helpers and guidance
services/runner/src/engines/sandbox_agent/agent-mount*.ts, services/runner/tests/unit/agent-mount.test.ts
Adds credential signing, README seeding, agent-files symlink management, remote helpers, and Claude prompt guidance.
Sandbox agent mount integration
services/runner/src/engines/sandbox_agent.ts
Activates agent mounts locally or on Daytona, injects mount metadata into sessions, exposes Pi environment data, and cleans up local mounts.
Mount detach safety and fallback
services/runner/src/engines/sandbox_agent/mount.ts, workspace.ts, related tests
Requires confirmed detach before fallback, strengthens geesefs shutdown, classifies mountpoint failures, and preserves unsafe durable CWDs.
Keep-alive defaults and validation
services/runner/src/engines/sandbox_agent/session-pool.ts, related tests
Makes local keep-alive enabled by default and expands boolean environment parsing.

Session inspector agent mounts

Layer / File(s) Summary
Workflow artifact context propagation
web/oss/src/components/AgentChatSlice/*, web/oss/src/components/SessionInspector/*, web/packages/agenta-entities/.../molecule.ts
Derives workflow artifact IDs and passes them through session rail and inspector controls.
Inspector state and agent mount data
web/oss/src/components/SessionInspector/{store.ts,api.ts,api.test.ts}, web/oss/src/components/SessionInspector/tabs/MountsTab.tsx
Stores artifact context, queries agent mounts, refreshes related data, and renders agent files with nested session mounts.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SessionInspector
  participant MountsAPI
  participant MountsService
  participant MountsDatabase
  SessionInspector->>MountsAPI: POST /mounts/agents/query
  MountsAPI->>MountsService: fetch agent mount
  MountsService->>MountsDatabase: fetch active mount by slug
  MountsDatabase-->>MountsService: mount or empty result
  MountsService-->>MountsAPI: mount response
  MountsAPI-->>SessionInspector: agent mount data
Loading
sequenceDiagram
  participant SandboxAgent
  participant MountsAPI
  participant AgentMount
  participant SandboxSession
  SandboxAgent->>MountsAPI: sign agent mount credentials
  MountsAPI-->>SandboxAgent: mount credentials
  SandboxAgent->>AgentMount: mount, seed README, link agent-files
  AgentMount->>SandboxSession: expose mounted path and session metadata
  SandboxSession-->>SandboxAgent: session initialized
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.53% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: durable files shared across agent sessions.
Description check ✅ Passed The description is directly related to the agent-mount, Session Inspector, and mount-fallback changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agent-mounts-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 13, 2026 3:30am

Request Review

@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jul 13, 2026
@CLAassistant

CLAassistant commented Jul 13, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@mmabrouk
mmabrouk force-pushed the feat/mount-file-viewer branch from e2a2de7 to e2b5d74 Compare July 13, 2026 02:25
@mmabrouk mmabrouk added the needs-review Agent updated; awaiting Mahmoud's review label Jul 13, 2026
@mmabrouk

Copy link
Copy Markdown
Member Author

🤖 The AI agent says: @coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

@mmabrouk Got it, I'll review the changes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

@mmabrouk Review already triggered — I'll post results shortly.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

@mmabrouk Review already in progress — I'll post the results shortly.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
web/oss/src/components/SessionInspector/api.ts (1)

49-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Zod boundary validation for the agent-mount response.

The coding guideline requires safeParseWithLogging from @agenta/entities/shared at the API boundary so backend drift is caught early. fetchAgentMount trusts the response shape without schema validation. When migrating to the Fern client, keep a local Zod schema to detect drift.

As per coding guidelines: "Keep Zod validation at the API boundary even when using Fern-generated types, because local schemas still detect backend drift. Use safeParseWithLogging from @agenta/entities/shared for boundary validation."

Source: Coding guidelines

api/oss/src/core/mounts/interfaces.py (1)

39-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the archived-exclusion contract on the interface, not just the implementation.

fetch_mount_by_slug silently excludes archived mounts in the Postgres DAO, while fetch_mount (by id, same interface) does not. This asymmetric contract is only documented in dao.py's docstring — the abstract interface gives no hint of it, so any future DAO implementation or new caller could reasonably assume symmetric behavior with fetch_mount.

📝 Proposed docstring addition
     `@abstractmethod`
     async def fetch_mount_by_slug(
         self,
         *,
         project_id: UUID,
         #
         slug: str,
-    ) -> Optional[Mount]: ...
+    ) -> Optional[Mount]:
+        """Fetch by slug. Unlike `fetch_mount`, must exclude archived (deleted_at) rows."""
+        ...
api/oss/src/apis/fastapi/mounts/router.py (1)

49-108: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider collapsing the exception→status mapping into a table.

handle_mount_exceptions now has 10 near-identical except ... raise HTTPException(status_code=..., detail=e.message) from e blocks, and this PR adds another one for MountArtifactIdInvalid. A {ExceptionType: status_code} dict + single except MountError as e lookup would remove the repetition and make future additions (e.g. this PR's) a one-line change.

♻️ Proposed refactor sketch
+_MOUNT_EXCEPTION_STATUS = {
+    MountDataInvalid: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountPathInvalid: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountNameInvalid: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountArtifactIdInvalid: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountSlugConflict: status.HTTP_409_CONFLICT,
+    MountSlugReserved: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountImmutableField: status.HTTP_422_UNPROCESSABLE_ENTITY,
+    MountFileNotFound: status.HTTP_404_NOT_FOUND,
+    MountNotFound: status.HTTP_404_NOT_FOUND,
+    MountStorageUnavailable: status.HTTP_503_SERVICE_UNAVAILABLE,
+}
+
 async def wrapper(*args, **kwargs):
     try:
         return await func(*args, **kwargs)
-    except MountDataInvalid as e:
-        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=e.message) from e
-    ... (repeat for each type) ...
+    except MountError as e:
+        status_code = _MOUNT_EXCEPTION_STATUS.get(type(e), status.HTTP_400_BAD_REQUEST)
+        raise HTTPException(status_code=status_code, detail=e.message) from e
services/runner/src/engines/sandbox_agent.ts (2)

695-705: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Sign session and agent-mount credentials in parallel.

signMount (line ~688) and signAgentMount are independent network calls (each bounded by its own 10s timeout) but are awaited sequentially, doubling worst-case latency added to acquireEnvironment when both a session mount and an agent mount apply.

⚡ Proposed fix
-  let mountCreds: MountCredentials | null =
-    presignedMount !== undefined
-      ? presignedMount
-      : sessionForMount && runCred
-        ? await signMount(sessionForMount, {
-            apiBase: apiBase(),
-            authorization: runCred,
-            log: logger,
-          })
-        : null;
-
   const artifactId = request.runContext?.workflow?.artifact?.id?.trim();
   const signAgentMount =
     deps.signAgentMountCredentials ?? signAgentMountCredentials;
-  const agentMountCreds: MountCredentials | null =
-    artifactId && runCred
-      ? await signAgentMount(artifactId, {
-          apiBase: apiBase(),
-          authorization: runCred,
-          log: logger,
-        })
-      : null;
+  const [mountCreds, agentMountCreds]: [
+    MountCredentials | null,
+    MountCredentials | null,
+  ] = await Promise.all([
+    presignedMount !== undefined
+      ? Promise.resolve(presignedMount)
+      : sessionForMount && runCred
+        ? signMount(sessionForMount, {
+            apiBase: apiBase(),
+            authorization: runCred,
+            log: logger,
+          })
+        : Promise.resolve(null),
+    artifactId && runCred
+      ? signAgentMount(artifactId, {
+          apiBase: apiBase(),
+          authorization: runCred,
+          log: logger,
+        })
+      : Promise.resolve(null),
+  ]);

1251-1295: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Tunnel endpoint discovery can run twice per acquisition.

When both a session durable-cwd mount and an agent mount apply on Daytona, discoverTunnelEndpoint is called independently here and again at Lines 1200-1204, each an external HTTP call to the ngrok API. Since both mounts target the same object-store deployment in practice, consider discovering the tunnel endpoint once and reusing it for both mount attempts to save a round trip per run.

services/runner/src/engines/sandbox_agent/session-pool.ts (1)

2-13: 🚀 Performance & Scalability | 🔵 Trivial

Monitor resource impact of the new default-on keep-alive.

Flipping local keep-alive to enabled-by-default means every deployment that previously relied on the implicit off default (without explicitly setting AGENTA_RUNNER_SESSION_KEEPALIVE) now parks warm sessions/processes up to poolMax for the idle TTL. Worth confirming host memory budgets and poolMax/TTL defaults are sized for this in production before rollout, and that dashboards/alerts cover pool occupancy.

Also applies to: 106-106


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: df22824f-2fce-4f1f-961b-d64cc1b18ece

📥 Commits

Reviewing files that changed from the base of the PR and between e2b5d74 and a2f87f3.

📒 Files selected for processing (29)
  • api/oss/src/apis/fastapi/mounts/models.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/mounts/types.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/tests/pytest/acceptance/mounts/test_agent_mounts_basics.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • services/runner/src/engines/sandbox_agent.ts
  • services/runner/src/engines/sandbox_agent/agent-mount-guidance.ts
  • services/runner/src/engines/sandbox_agent/agent-mount.ts
  • services/runner/src/engines/sandbox_agent/mount.ts
  • services/runner/src/engines/sandbox_agent/session-pool.ts
  • services/runner/src/engines/sandbox_agent/workspace.ts
  • services/runner/tests/unit/agent-mount.test.ts
  • services/runner/tests/unit/sandbox-agent-mount.test.ts
  • services/runner/tests/unit/sandbox-agent-orchestration.test.ts
  • services/runner/tests/unit/sandbox-agent-workspace.test.ts
  • services/runner/tests/unit/session-pool.test.ts
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/components/SessionRail.tsx
  • web/oss/src/components/SessionInspector/PanelSessionInspectorButton.tsx
  • web/oss/src/components/SessionInspector/SessionInspectorButton.tsx
  • web/oss/src/components/SessionInspector/SessionInspectorDrawer.tsx
  • web/oss/src/components/SessionInspector/api.test.ts
  • web/oss/src/components/SessionInspector/api.ts
  • web/oss/src/components/SessionInspector/store.ts
  • web/oss/src/components/SessionInspector/tabs/MountsTab.tsx
  • web/packages/agenta-entities/src/workflow/state/molecule.ts

Comment thread services/runner/src/engines/sandbox_agent.ts Outdated
Comment thread services/runner/src/engines/sandbox_agent.ts
Comment thread web/oss/src/components/SessionInspector/api.ts
@mmabrouk
mmabrouk force-pushed the feat/agent-mounts-v2 branch from a2f87f3 to d14e72e Compare July 13, 2026 03:12
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Jul 13, 2026
@mmabrouk
mmabrouk force-pushed the feat/mount-file-viewer branch from ffc70be to 0bdb6ec Compare July 13, 2026 03:15
@mmabrouk
mmabrouk force-pushed the feat/agent-mounts-v2 branch from d14e72e to 1831f47 Compare July 13, 2026 03:15
@mmabrouk

Copy link
Copy Markdown
Member Author

🤖 The AI agent says: Pre-merge sanity QA passed on the clean PR tip (Daytona Secret Delivery absent): Terminal write/read with no EROFS, exact agent-mount persistence, session isolation, cold cross-session recall, a real local keep-warm hit-continue, API file listing/read, and rendered Session Inspector nesting. The lower Mount File Viewer accessibility feedback is also fixed and live keyboard-tested.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (8)
api/oss/src/core/mounts/service.py (3)

207-226: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant/inconsistent slugify call vs. sibling get_or_create_session_mount.

slug_name = slugify_mount_name(name) is computed here but the raw name (not slug_name) is passed to mint_agent_slug, which slugifies again internally. get_or_create_session_mount instead passes the already-computed slug_name into mint_session_slug. Functionally equivalent (slugify is idempotent) but inconsistent style/duplicate work.

♻️ Align with session-mount pattern
         slug_name = slugify_mount_name(name)
         mount_create = MountCreate(
-            slug=mint_agent_slug(artifact_id=artifact_id, name=name),
+            slug=mint_agent_slug(artifact_id=artifact_id, name=slug_name),
             name=slug_name,
         )

207-226: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Missing # grouping separators between identity and payload params.

Other service methods in this file (fetch_mount, get_or_create_session_mount call sites) group identity params (project_id/user_id) from payload params with a # separator for readability. The new get_or_create_agent_mount/fetch_agent_mount signatures omit this.

As per coding guidelines, "Prefer keyword-only parameters using *, and use grouped sections in function signatures and calls with # separators for readability."

Also applies to: 255-268

Source: Coding guidelines


207-226: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

"default" name literal duplicated across layers.

The default agent-mount name "default" is hardcoded independently in models.py (AgentMountQueryRequest), here (twice), and in router.py's Query(default="default"). Consider a shared constant (similar to _SESSION_CWD_NAME) to keep these in sync if the default ever changes.

Also applies to: 255-268

api/oss/src/apis/fastapi/mounts/router.py (1)

313-354: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Missing # grouping separators in new handler calls.

Sibling handlers (e.g. create_mount) separate identity args (project_id/user_id) from payload args with a # comment for readability; the new sign_agent_mount_credentials/query_agent_mount service calls don't follow this.

As per coding guidelines, "use grouped sections in function signatures and calls with # separators for readability."

Example diff
         mount = await self.mounts_service.get_or_create_agent_mount(
             project_id=UUID(request.state.project_id),
             user_id=UUID(str(request.state.user_id)),
+            #
             artifact_id=artifact_id,
             name=name,
         )

Source: Coding guidelines

services/runner/src/engines/sandbox_agent.ts (2)

677-705: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Sign session-mount and agent-mount credentials in parallel.

signMount and signAgentMount are independent network calls (each with its own 10s timeout) but are awaited sequentially. On the common path where a run has both a sessionId and a workflow artifact.id, this adds unnecessary latency to every turn's environment acquisition.

⚡ Proposed fix to sign both concurrently
-  let mountCreds: MountCredentials | null =
-    presignedMount !== undefined
-      ? presignedMount
-      : sessionForMount && runCred
-        ? await signMount(sessionForMount, {
-            apiBase: apiBase(),
-            authorization: runCred,
-            log: logger,
-          })
-        : null;
-
   const artifactId = request.runContext?.workflow?.artifact?.id?.trim();
   const signAgentMount =
     deps.signAgentMountCredentials ?? signAgentMountCredentials;
-  const agentMountCreds: MountCredentials | null =
-    artifactId && runCred
-      ? await signAgentMount(artifactId, {
-          apiBase: apiBase(),
-          authorization: runCred,
-          log: logger,
-        })
-      : null;
+  const [mountCredsResult, agentMountCreds]: [
+    MountCredentials | null,
+    MountCredentials | null,
+  ] = await Promise.all([
+    presignedMount !== undefined
+      ? Promise.resolve(presignedMount)
+      : sessionForMount && runCred
+        ? signMount(sessionForMount, {
+            apiBase: apiBase(),
+            authorization: runCred,
+            log: logger,
+          })
+        : Promise.resolve(null),
+    artifactId && runCred
+      ? signAgentMount(artifactId, {
+          apiBase: apiBase(),
+          authorization: runCred,
+          log: logger,
+        })
+      : Promise.resolve(null),
+  ]);
+  let mountCreds: MountCredentials | null = mountCredsResult;

1251-1295: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Redundant tunnel-endpoint discovery for the agent mount on Daytona.

This block re-runs storeReachableFromSandbox/discoverTunnelEndpoint independently of the durable-cwd remote-mount block immediately above (~1194-1250), even though both mounts almost certainly point at the same underlying object-store endpoint. When a tunnel is required, this issues a second, redundant HTTP call to the tunnel-discovery API per run.

Consider reusing the endpoint already discovered for the durable cwd mount when environment.mountCreds and environment.agentMountCreds share the same endpoint, falling back to a fresh discovery only otherwise.

services/runner/src/engines/sandbox_agent/mount.ts (1)

394-409: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Root-cause mount failure is discarded if the shutdown of the failed attempt itself fails.

await attempt?.stop(); is unguarded. If stop() throws (e.g. geesefs won't die after SIGTERM/SIGKILL — see the "refuses fallback..." test), the original failure (why geesefs actually failed to mount: bad creds, unreachable store, etc.) is lost; only the generic stop-failure message surfaces. That's the more actionable diagnostic for on-call debugging.

♻️ Preserve original failure context when stop() also fails
   // Never detach/fallback while a failed geesefs attempt may still attach later.
-  await attempt?.stop();
+  try {
+    await attempt?.stop();
+  } catch (stopErr) {
+    const origDetail = String(
+      failure instanceof Error ? failure.message : failure,
+    ).slice(0, 300);
+    throw new Error(
+      `${stopErr instanceof Error ? stopErr.message : stopErr} ` +
+        `(original mount failure: ${origDetail})`,
+    );
+  }
   const detached = await unmountStorage(cwd, { ...deps.unmountDeps, log });
services/runner/src/engines/sandbox_agent/session-pool.ts (1)

74-80: 🚀 Performance & Scalability | 🔵 Trivial

Default flip to keep-alive-on: confirm pool capacity/memory budget accounts for it.

Flipping the local-session default from off to on means idle sessions now park (holding harness process + native memory) for up to the TTL by default in every deployment that doesn't explicitly set AGENTA_RUNNER_SESSION_KEEPALIVE=off, rather than opting in. The boolEnv/readKeepaliveConfig logic itself is correct and well-tested against the new default.

Worth confirming DEFAULT_POOL_MAX/host memory budgets were sized with default-on in mind across all deployment environments, not just ones that previously opted in explicitly.

Also applies to: 106-106


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: df22824f-2fce-4f1f-961b-d64cc1b18ece

📥 Commits

Reviewing files that changed from the base of the PR and between e2b5d74 and a2f87f3.

📒 Files selected for processing (29)
  • api/oss/src/apis/fastapi/mounts/models.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/mounts/types.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/tests/pytest/acceptance/mounts/test_agent_mounts_basics.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • services/runner/src/engines/sandbox_agent.ts
  • services/runner/src/engines/sandbox_agent/agent-mount-guidance.ts
  • services/runner/src/engines/sandbox_agent/agent-mount.ts
  • services/runner/src/engines/sandbox_agent/mount.ts
  • services/runner/src/engines/sandbox_agent/session-pool.ts
  • services/runner/src/engines/sandbox_agent/workspace.ts
  • services/runner/tests/unit/agent-mount.test.ts
  • services/runner/tests/unit/sandbox-agent-mount.test.ts
  • services/runner/tests/unit/sandbox-agent-orchestration.test.ts
  • services/runner/tests/unit/sandbox-agent-workspace.test.ts
  • services/runner/tests/unit/session-pool.test.ts
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/components/SessionRail.tsx
  • web/oss/src/components/SessionInspector/PanelSessionInspectorButton.tsx
  • web/oss/src/components/SessionInspector/SessionInspectorButton.tsx
  • web/oss/src/components/SessionInspector/SessionInspectorDrawer.tsx
  • web/oss/src/components/SessionInspector/api.test.ts
  • web/oss/src/components/SessionInspector/api.ts
  • web/oss/src/components/SessionInspector/store.ts
  • web/oss/src/components/SessionInspector/tabs/MountsTab.tsx
  • web/packages/agenta-entities/src/workflow/state/molecule.ts

@mmabrouk
mmabrouk force-pushed the feat/mount-file-viewer branch from daae705 to b6c4947 Compare July 13, 2026 03:29
@mmabrouk
mmabrouk force-pushed the feat/agent-mounts-v2 branch from 18910b7 to 51140f8 Compare July 13, 2026 03:29
@mmabrouk
mmabrouk changed the base branch from feat/mount-file-viewer to big-agents July 13, 2026 03:32
@mmabrouk
mmabrouk merged commit 238fb4f into big-agents Jul 13, 2026
24 checks passed
@mmabrouk
mmabrouk deleted the feat/agent-mounts-v2 branch July 13, 2026 03:42
@mmabrouk mmabrouk mentioned this pull request Jul 13, 2026
12 tasks
ardaerzin added a commit that referenced this pull request Jul 14, 2026
Align with big-agents: agent mounts v2 + durable files shared across sessions,
mount file viewer, plus LLM-provider layout, usage/analytics and evaluator fixes.

Conflict resolution:
- Backend mounts (core/apis) + runner sandbox_agent + backend mounts tests: took
  big-agents. Our side was a cherry-pick of #5247 'for local testing' (stale preview
  shims, e.g. plain timing log, AGENT_MOUNT_ENV_VAR) that big-agents finalized in
  #5268 (agent-mounts-v2) + durable-files. session-continuity import is preserved.
- FE inspector: kept our unified Inspector (AgentChatSlice/components/Inspector) and
  removed Mahmoud's POC mount viewer per his note — SessionInspectorDrawer/Button,
  tabs/MountsTab, assets/mountBrowser. Session files already surface through the Drives
  UI (ContextRail/FilesDrawer/DriveFileCard). Kept ours for SessionRail and
  PanelSessionInspectorButton (opens the unified InspectorDrawer); api/store/StatesTab/
  StreamsTab stay (reused by our Inspector).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend feature needs-review Agent updated; awaiting Mahmoud's review size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants