Skip to content

fix(eve): support lazy session sandbox access in workflow steps - #3535

Draft
ruiconti wants to merge 10 commits into
mainfrom
ruiconti/felix-workflow-tools
Draft

ruiconti wants to merge 10 commits into
mainfrom
ruiconti/felix-workflow-tools

Conversation

@ruiconti

@ruiconti ruiconti commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Authored workflow steps cannot access the session sandbox. Steps can now call ctx.getSandbox() without a tool option. Regular tools and workflow steps use the same getter implementation and the session's saved sandbox state. Each workflow step binds a lazy SandboxAccess in its context and reconstructs access when a later step runs.

The owning session initializes the sandbox on first access, persists its reconnect state, and returns it to the step. Blocking and background requests use one internal session handler, and both use the existing provider to resolve sandbox identity. Concurrent steps share initialization state; retries reuse a durable response. First access in each step adds an owner round trip. Sandbox handles stay inside steps, and the session retains lifecycle ownership. Workflow bodies, dynamic workflow tools, and extension workflow tools do not gain sandbox access.

The implementation uses the provider start/resume contract from #3271 and resumes immutable provider session state. Missing native state is handled by the provider's resume contract.

Closes #3201. Builds on the prototype in #3156. Approval ordering remains separate in #3198 and #3202; this PR has no changes under harness/.

Validation

The latest validation passed 78 focused unit tests, eight sandbox runtime integration cases, and three test-harness integration cases after merging main through fa92e5ec3. Blocking and background cases prove that a regular tool can write a file, separate workflow steps can update it, and a later regular tool can read the update, with one initialization. Other cases cover concurrent access, retries, initialization failures, ownership rejection, cancellation, and inbox delivery across a simulated handoff gap. Two deterministic sandbox fixture evals remain for CI; they have not run locally.

Checklist

  • This change was requested or approved by a maintainer
  • I ran the relevant checks from CONTRIBUTING.md
  • I added tests and documentation where relevant
  • I added a changeset if this touches the published eve package
  • DCO sign-off passes for every commit (git commit --signoff)

Diff size

Docs — 6 files · +78 / -3

Documents lazy access, step and ownership boundaries, and release behavior.

Implementation — 18 files · +336 / -38

Adds lazy context binding, session-owned initialization, and durable step responses through one internal request handler. Reuses the ordinary tool getter, provider metadata resolution, and cancellation wrapper. Includes generated tool contract metadata; the public channel contract is unchanged.

Tests — 19 files · +942 / -34

Exercises access shared across regular and workflow tools, reconnection, concurrency, retries, ownership rejection, cancellation, and handoff-gap delivery. Includes two fixture evals, compatibility fixtures, and a test provider that preserves files across reconnects.

Adapt the fix from #3202 to current main and cover approval and denial for both workflow execution modes.

Signed-off-by: Rui Conti <ruiconti@gmail.com>
Implement #3201 using the existing authored-step context boundary. Adapt the sandbox reference transport and runtime tests from Felix Arntz’s experimental #3156.

Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Bundle + Package Summary: apps/fixtures/weather-agent

Key takeaways

  • No notable deltas vs main (fa92e5e).

Delta vs main (fa92e5e)

Area Metric Baseline Current Delta
Package Packed tarball 8.59 MB 8.59 MB +3.5 kB ⚠️
Package Unpacked publish size 32.00 MB 32.01 MB +11.0 kB ⚠️
Package Installed footprint 78.17 MB 78.19 MB +11.0 kB ⚠️
Package Published files 3771 3779 +8
Package Installed files 7731 7739 +8
Package Installed package instances 33 33 0
Package Distinct installed package names 32 32 0
Package Installed dependency edges 51 51 0
Package Installed optional peer edges 9 9 0
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 21.97 MB 21.98 MB +15.2 kB ⚠️
Runtime Public routes 18 18 0
Changed function payloads vs main (fa92e5e) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 10.98 MB 10.99 MB +7.6 kB ⚠️ none
functions/.well-known/workflow/v1/flow.func changed 10.98 MB 10.99 MB +7.6 kB ⚠️ none

eve init install

Metric Baseline Current Delta
Installed footprint 116.40 MB 116.41 MB +11.0 kB ⚠️
Installed packages 98 98 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 49.49 MB 49.50 MB +11.0 kB ⚠️
devDependency package bytes 5.04 MB 5.04 MB 0 B ➖
Build Metadata
  • Preset: vercel
  • Nitro: nitro@3.0.260903-beta
  • Output directory: apps/fixtures/weather-agent/.vercel/output
  • Build metadata timestamp: 2026-09-22T17:11:10.390Z
  • Route aliases: 18 public, 1 internal (19 total aliases)
  • Vercel routes in config: 21
  • Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down

Package Details

  • Package: eve@0.63.1
  • Package directory: packages/eve
  • Tarball: 8.59 MB (eve-0.63.1.tgz)
  • Unpacked payload: 32.01 MB across 3779 published files
  • Installed footprint: 78.19 MB across 7739 installed files
  • Installed root package: 31.36 MB
  • Installed dependencies: 46.83 MB
  • Installed package instances: 33
  • Distinct installed package names: 32
  • Installed dependency edges: 51
  • Installed optional peer edges: 9
  • Runtime dependencies: 2
  • Peer dependencies: 7 (6 optional)

Installed footprint is measured from an isolated temporary npm install of the packed tarball.
Graph metrics read only package.json files in package directories directly beneath a node_modules boundary, including nested boundaries. Each directory is one package instance; distinct names come from those manifests. Dependency edges count each unique name in dependencies or optionalDependencies per instance; optional peer edges count peerDependencies marked optional.

Heavy installed dependencies

  • eve: 31.36 MB (40.1%)
  • @rolldown/binding-linux-x64-gnu: 19.10 MB (24.4%)
  • ai: 7.66 MB (9.8%)
  • zod: 6.67 MB (8.5%)
  • undici: 3.51 MB (4.5%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js       [#############...........] 9.70 MB 30.3%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [###.....................] 2.29 MB 7.2%
🟠 dist/src/compiled/@ai-sdk/code-mode/index.js     [#.......................] 1.03 MB 3.2%
🟡 dist/src/compiled/@vercel/blob/index.js          [#.......................] 902.9 kB 2.8%
🟡 dist/src/compiled/_chunks/workflow/signal-exi... [#.......................] 514.5 kB 1.6%
🔴 Other published files                            [########################] 17.57 MB 54.9%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 31.36 MB 40.1%
🔴 @rolldown/binding-linux-x64-gnu [###############.........] 19.10 MB 24.4%
🔴 ai                              [######..................] 7.66 MB 9.8%
🔴 zod                             [#####...................] 6.67 MB 8.5%
🟠 undici                          [###.....................] 3.51 MB 4.5%
🟠 nitro                           [#.......................] 1.89 MB 2.4%
🔴 Other installed packages        [######..................] 7.98 MB 10.2%
Runtime dependencies (2)
Package Range Notes
nitro 3.0.260903-beta
undici 8.9.0
Peer dependencies (7)
Package Range Notes
@opentelemetry/api ^1.0.0 optional peer
ai catalog:
braintrust ^3.0.0 optional peer
chat ^4.41.0 optional peer
dd-trace ^6.13.0 optional peer
just-bash ^3.1.0 optional peer
microsandbox ^0.5.0 optional peer
eve init install drill-down

eve init install details

  • Command: eve init my-agent
  • Package manager: npm
  • Installed footprint: 116.41 MB across 9633 installed files
  • Installed packages: 98 total (92 transitive-only)
  • dependencies: 4 direct packages totaling 49.50 MB
  • devDependencies: 2 direct packages totaling 5.04 MB
  • Other transitive package files: 61.87 MB

Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.

Heavy installed dependencies

  • eve: 31.36 MB (26.9%)
  • @typescript/typescript-linux-x64: 27.95 MB (24.0%)
  • @rolldown/binding-linux-x64-gnu: 19.10 MB (16.4%)
  • zod: 10.29 MB (8.8%)
  • ai: 7.66 MB (6.6%)
Installed footprint breakdown
Installed package size
🔴 eve                              [########################] 31.36 MB 26.9%
🔴 @typescript/typescript-linux-x64 [#####################...] 27.95 MB 24.0%
🔴 @rolldown/binding-linux-x64-gnu  [###############.........] 19.10 MB 16.4%
🔴 zod                              [########................] 10.29 MB 8.8%
🔴 ai                               [######..................] 7.66 MB 6.6%
🟠 undici                           [###.....................] 3.51 MB 3.0%
🔴 Other installed packages         [#############...........] 16.54 MB 14.2%
dependencies (4)
Package Range Installed size Share
@vercel/connect 2.2.0 188.7 kB 0.2%
ai ^7.0.105 7.66 MB 6.6%
eve file:eve-0.63.1.tgz 31.36 MB 26.9%
zod 4.5.4 10.29 MB 8.8%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.54 MB 2.2%
typescript 7.0.2 2.50 MB 2.1%
Function Drill-Down

Payload Size Graph

Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func     [########################] 10.99 MB 50.0%
🔴 functions/__server.func                         [########################] 10.99 MB 50.0%

Top Function Payloads

🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 10.99 MB
Metric Value
Public routes /.well-known/workflow/v1/flow
Runtime nodejs24.x
Handler index.mjs
Payload 10.99 MB
Function files 10.99 MB across 120 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 2.89 MB (26.3%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                        [##############..........] 2.89 MB 26.3%
🟡 _libs/undici.mjs                 [#####...................] 980.8 kB 8.9%
🟡 _chunks/sandbox.mjs              [####....................] 809.9 kB 7.4%
🟡 _chunks/signal-exit-B9U6kH7R.mjs [###.....................] 616.2 kB 5.6%
🟡 _chunks/oidc.mjs                 [###.....................] 570.8 kB 5.2%
🔴 Other bundled files              [########################] 5.12 MB 46.6%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x",
  "maxDuration": "max",
  "experimentalTriggers": [
    {
      "type": "queue/v2beta",
      "topic": "__eve776561746865722d6167656e74_wkf_workflow_*",
      "consumer": "default",
      "retryAfterSeconds": 5,
      "initialDelaySeconds": 0
    }
  ],
  "environment": {
    "WORKFLOW_PRECONDITION_GUARD": "1"
  }
}

🟠 functions/__server.func • 17 public routes, 1 internal alias • 10.99 MB
Metric Value
Public routes /
/.well-known/workflow/v1/webhook/[token]
/eve/v1/activity/[token]
/eve/v1/callback/[token]
/eve/v1/connections/[name]/callback/[attemptId]/[token]
/eve/v1/connections/[name]/callback/[token]
/eve/v1/health
/eve/v1/info
/eve/v1/session
/eve/v1/session/[parentSessionId]/subagents/[callId]/[childSessionId]/stream
/eve/v1/session/[sessionId]
/eve/v1/session/[sessionId]/cancel
/eve/v1/session/[sessionId]/clear
/eve/v1/session/[sessionId]/compact
/eve/v1/session/[sessionId]/reset
/eve/v1/session/[sessionId]/stream
/eve/v1/task-input/[token]
Internal aliases /__server
Runtime nodejs24.x
Handler index.mjs
Payload 10.99 MB
Function files 10.99 MB across 120 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 2.89 MB (26.3%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                        [##############..........] 2.89 MB 26.3%
🟡 _libs/undici.mjs                 [#####...................] 980.8 kB 8.9%
🟡 _chunks/sandbox.mjs              [####....................] 809.9 kB 7.4%
🟡 _chunks/signal-exit-B9U6kH7R.mjs [###.....................] 616.2 kB 5.6%
🟡 _chunks/oidc.mjs                 [###.....................] 570.8 kB 5.2%
🔴 Other bundled files              [########################] 5.12 MB 46.6%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x"
}

Build Timing: e2e/fixtures/agent-tools-sandbox

This is an informational timing measurement inside eve build, from preflight through publication. Output-size measurement and profile writing are excluded.

Build mode: deployable Vercel build with sandbox template prewarm included.

  • Build pipeline: 3.11 s -> 3.30 s (+195.7 ms) vs main (fa92e5e).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (fa92e5e)`
Phase Baseline Current Delta
extension.check 9.0 ms 0.4 ms -8.6 ms
project.resolve 0.4 ms 0.2 ms -0.2 ms
workspace.create 0.8 ms 0.4 ms -0.4 ms
host.prepare 568.3 ms 584.8 ms +16.5 ms
vercel.service-prefix.resolve 1.0 ms 2.6 ms +1.6 ms
nitro.create 196.9 ms 188.1 ms -8.8 ms
sandbox.prewarm 334.2 ms 455.2 ms +121.0 ms
nitro.cache.prepare 0.2 ms 0.2 ms 0.0 ms
nitro.prepare 0.5 ms 0.5 ms 0.0 ms
nitro.public-assets 0.6 ms 0.6 ms 0.0 ms
nitro.prerender 0.3 ms 0.3 ms 0.0 ms
nitro.bundle 1.86 s 1.90 s +35.4 ms
nitro.cache.write 0.4 ms 0.2 ms -0.2 ms
vercel.workflow-function.materialize 72.1 ms 90.3 ms +18.2 ms
agent-summary.emit 0.6 ms 1.2 ms +0.6 ms
nitro.close 0.1 ms 0.2 ms +0.1 ms
output.publish 6.7 ms 5.6 ms -1.1 ms
workspace.remove 3.0 ms 4.6 ms +1.6 ms

Comment thread packages/eve/src/harness/tool-loop.ts Outdated
);

if (mustWaitForApproval) {
let parkedSession = appendPendingApprovalCoordinationBatch({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Scope the approval wait to the matching calls. mustWaitForApproval becomes true when any coordinated request needs approval, but this batch stores all runtimeActions and tasks. An unguarded workflow or task-control action emitted in the same model response therefore waits until the unrelated approval settles. In particular, a task_cancel can be delayed indefinitely if nobody answers that approval. Partition the requests by approvalCallIds: dispatch the non-gated subset through the normal coordination slot immediately and retain only approval-matched requests here. Please cover a guarded workflow paired with both an unguarded workflow and task_cancel in one response.

expect(output).toContain("Attempt 1.");
});

it("reattaches an opted-in sandbox across workflow steps", async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Split these scenarios before expanding this suite. The new sandbox and approval cases take this file from 978 to 1,229 lines and combine distinct sandbox-lifecycle, capability-boundary, execution-mode, and approval concerns in one monolithic test module. Move the sandbox cases to a focused workflow-tool-sandbox.integration.test.ts, the approval/provisioning matrix to workflow-tool-approval.integration.test.ts, and share only the runtime/start/stream setup helpers.

Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
@vercel

vercel Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
eve-docs Ready Ready Preview, v0 Sep 22, 2026 5:11pm UTC
eve-pkg Ready Ready Preview, v0 Sep 22, 2026 5:11pm UTC

Signed-off-by: Rui Conti <ruiconti@gmail.com>
@vercel-security-reviewer

Copy link
Copy Markdown

Security review details

Comment thread packages/eve/src/harness/tool-loop.ts Outdated
Signed-off-by: Rui Conti <ruiconti@gmail.com>
@ruiconti ruiconti changed the title fix(eve): support approved workflow tools with session sandbox access fix(eve): support lazy session sandbox access in workflow steps Sep 19, 2026
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>

This branch was successfully deployed

2 active deployments
Preview – eve-docs — 6d63773a Deployed Sep 22, 2026 by vercel[bot]
Preview – eve-pkg — 6d63773a Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support sandbox access from workflow tool steps

1 participant