feat(eve): agents - support direct invocation - #2585
Conversation
Signed-off-by: Andrew Barba <barba@hey.com>
Bundle + Package Summary:
|
| Area | Warning | Details |
|---|---|---|
| Runtime | Total function bytes | 18.37 MB -> 21.37 MB; +2.99 MB |
Delta vs main (9e1ce53)
| Area | Metric | Baseline | Current | Delta |
|---|---|---|---|---|
| Package | Packed tarball | 8.23 MB | 8.23 MB | +2.5 kB |
| Package | Unpacked publish size | 31.01 MB | 31.05 MB | +38.8 kB |
| Package | Installed footprint | 75.22 MB | 75.26 MB | +38.8 kB |
| Package | Published files | 3507 | 3519 | +12 |
| Package | Installed files | 7222 | 7234 | +12 |
| Package | Installed package instances | 35 | 35 | 0 |
| Package | Distinct installed package names | 34 | 34 | 0 |
| Package | Installed dependency edges | 53 | 53 | 0 |
| Package | Installed optional peer edges | 47 | 47 | 0 |
| Runtime | Unique function payloads | 2 | 2 | 0 |
| Runtime | Total function bytes | 18.37 MB | 21.37 MB | +2.99 MB |
| Runtime | Public routes | 16 | 16 | 0 |
Changed function payloads vs main (9e1ce53) (2)
| Function | Status | Baseline | Current | Delta | Route changes |
|---|---|---|---|---|---|
functions/__server.func |
changed | 9.19 MB | 10.68 MB | +1.50 MB |
none |
functions/.well-known/workflow/v1/flow.func |
changed | 9.19 MB | 10.68 MB | +1.50 MB |
none |
eve init install
| Metric | Baseline | Current | Delta |
|---|---|---|---|
| Installed footprint | 113.66 MB | 113.70 MB | +38.8 kB |
| Installed packages | 120 | 120 | 0 |
| dependencies | 4 | 4 | 0 |
| devDependencies | 2 | 2 | 0 |
| Dependency package bytes | 45.62 MB | 45.65 MB | +38.8 kB |
| devDependency package bytes | 5.04 MB | 5.04 MB | 0 B ➖ |
Build Metadata
- Preset:
vercel - Nitro:
nitro@3.0.260610-beta - Output directory:
apps/fixtures/weather-agent/.vercel/output - Build metadata timestamp: 2026-08-26T10:42:28.872Z
- Route aliases: 16 public, 1 internal (17 total aliases)
- Vercel routes in config: 19
- Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down
Package Details
- Package:
eve@0.45.0 - Package directory:
packages/eve - Tarball: 8.23 MB (
eve-0.45.0.tgz) - Unpacked payload: 31.05 MB across 3519 published files
- Installed footprint: 75.26 MB across 7234 installed files
- Installed root package: 29.70 MB
- Installed dependencies: 45.57 MB
- Installed package instances: 35
- Distinct installed package names: 34
- Installed dependency edges: 53
- Installed optional peer edges: 47
- Runtime dependencies: 2
- Peer dependencies: 5 (4 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: 29.70 MB (39.5%)@rolldown/binding-linux-x64-gnu: 19.91 MB (26.5%)ai: 6.77 MB (9.0%)zod: 5.07 MB (6.7%)undici: 3.50 MB (4.7%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js [##############..........] 9.76 MB 31.4%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [####....................] 2.44 MB 7.9%
🟠 dist/src/compiled/experimental-ai-sdk-code-mo... [##......................] 1.51 MB 4.9%
🟡 dist/src/compiled/_chunks/workflow/undici-Dzn... [#.......................] 512.7 kB 1.7%
🟡 dist/src/compiled/_chunks/node/undici-CUIybhQ... [#.......................] 508.8 kB 1.6%
🔴 Other published files [########################] 16.32 MB 52.6%
Installed footprint breakdown
Installed package size
🔴 eve [########################] 29.70 MB 39.5%
🔴 @rolldown/binding-linux-x64-gnu [################........] 19.91 MB 26.5%
🔴 ai [#####...................] 6.77 MB 9.0%
🔴 zod [####....................] 5.07 MB 6.7%
🟠 undici [###.....................] 3.50 MB 4.7%
🟠 nitro [##......................] 2.41 MB 3.2%
🔴 Other installed packages [######..................] 7.91 MB 10.5%
Runtime dependencies (2)
| Package | Range | Notes |
|---|---|---|
nitro |
3.0.260610-beta |
|
undici |
8.9.0 |
Peer dependencies (5)
| Package | Range | Notes |
|---|---|---|
@opentelemetry/api |
^1.0.0 |
optional peer |
ai |
catalog: |
|
braintrust |
^3.0.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: 113.70 MB across 9130 installed files
- Installed packages: 120 total (114 transitive-only)
- dependencies: 4 direct packages totaling 45.65 MB
- devDependencies: 2 direct packages totaling 5.04 MB
- Other transitive package files: 63.01 MB
Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.
Heavy installed dependencies
eve: 29.70 MB (26.1%)@typescript/typescript-linux-x64: 27.95 MB (24.6%)@rolldown/binding-linux-x64-gnu: 19.91 MB (17.5%)zod: 9.02 MB (7.9%)ai: 6.77 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 eve [########################] 29.70 MB 26.1%
🔴 @typescript/typescript-linux-x64 [#######################.] 27.95 MB 24.6%
🔴 @rolldown/binding-linux-x64-gnu [################........] 19.91 MB 17.5%
🔴 zod [#######.................] 9.02 MB 7.9%
🔴 ai [#####...................] 6.77 MB 6.0%
🟠 undici [###.....................] 3.50 MB 3.1%
🔴 Other installed packages [##############..........] 16.85 MB 14.8%
dependencies (4)
| Package | Range | Installed size | Share |
|---|---|---|---|
@vercel/connect |
1.0.0 |
167.9 kB | 0.1% |
ai |
^7.0.58 |
6.77 MB | 6.0% |
eve |
file:eve-0.45.0.tgz |
29.70 MB | 26.1% |
zod |
4.4.3 |
9.02 MB | 7.9% |
devDependencies (2)
| Package | Range | Installed size | Share |
|---|---|---|---|
@types/node |
24.x |
2.54 MB | 2.2% |
typescript |
7.0.2 |
2.50 MB | 2.2% |
Function Drill-Down
Payload Size Graph
Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func [########################] 10.68 MB 50.0%
🔴 functions/__server.func [########################] 10.68 MB 50.0%
Top Function Payloads
🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 10.68 MB
| Metric | Value |
|---|---|
| Public routes | /.well-known/workflow/v1/flow |
| Runtime | nodejs24.x |
| Handler | index.mjs |
| Payload | 10.68 MB |
| Function files | 10.68 MB across 99 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 3.52 MB (33.0%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [#####################...] 3.52 MB 33.0%
🟡 _libs/undici.mjs [######..................] 980.5 kB 9.2%
🟡 _chunks/sandbox.mjs [#####...................] 781.9 kB 7.3%
🟡 _chunks/frames-Dl2Hcma4.mjs [####....................] 678.7 kB 6.4%
🟡 _chunks/chatgpt-model.mjs [####....................] 666.7 kB 6.2%
🟠 Other bundled files [########################] 4.05 MB 37.9%
🧾 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 • 15 public routes, 1 internal alias • 10.68 MB
| Metric | Value |
|---|---|
| Public routes | //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.68 MB |
| Function files | 10.68 MB across 99 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 3.52 MB (33.0%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [#####################...] 3.52 MB 33.0%
🟡 _libs/undici.mjs [######..................] 980.5 kB 9.2%
🟡 _chunks/sandbox.mjs [#####...................] 781.9 kB 7.3%
🟡 _chunks/frames-Dl2Hcma4.mjs [####....................] 678.7 kB 6.4%
🟡 _chunks/chatgpt-model.mjs [####....................] 666.7 kB 6.2%
🟠 Other bundled files [########################] 4.05 MB 37.9%
🧾 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: 2.33 s -> 2.49 s (+155.0 ms) vs
main (9e1ce53). - Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (9e1ce53)`
| Phase | Baseline | Current | Delta |
|---|---|---|---|
extension.check |
1.1 ms | 1.2 ms | +0.1 ms |
project.resolve |
0.3 ms | 0.4 ms | +0.1 ms |
workspace.create |
0.7 ms | 0.7 ms | 0.0 ms |
host.prepare |
394.1 ms | 357.1 ms | -37.0 ms |
vercel.service-prefix.resolve |
2.5 ms | 2.1 ms | -0.4 ms |
nitro.create |
263.0 ms | 379.5 ms | +116.5 ms |
sandbox.prewarm |
161.9 ms | 247.0 ms | +85.1 ms |
nitro.cache.prepare |
0.2 ms | 0.2 ms | 0.0 ms |
nitro.prepare |
0.8 ms | 0.7 ms | -0.1 ms |
nitro.public-assets |
0.7 ms | 0.7 ms | 0.0 ms |
nitro.prerender |
0.5 ms | 0.5 ms | 0.0 ms |
nitro.bundle |
1.46 s | 1.45 s | -8.5 ms |
nitro.cache.write |
0.3 ms | 0.3 ms | 0.0 ms |
vercel.workflow-function.materialize |
43.5 ms | 42.9 ms | -0.6 ms |
agent-summary.emit |
0.7 ms | 0.7 ms | 0.0 ms |
nitro.close |
0.1 ms | 0.1 ms | 0.0 ms |
output.publish |
3.4 ms | 3.4 ms | 0.0 ms |
workspace.remove |
2.1 ms | 2.1 ms | 0.0 ms |
| -d '{"agent":"researcher/critic","message":"Review this evidence."}' | ||
| ``` | ||
|
|
||
| Every later message without `agent` continues as `researcher/critic`. To select a descendant for only one turn in an existing session, include `agent` on that message: |
There was a problem hiding this comment.
This is non-obvious semantic that is indicative of coupling in the wrong place. It introduces implicit statefulness that it's not clear we want?
- when you create a session targeting a subagent, will you never want to share with other agents? it seems like yes
- do you want an a) set of agent capabilities coordinated by an orchestrator or b) a shared session-bound storage that a set of independent agents operate against?
There was a problem hiding this comment.
Pull request overview
Adds a root-relative agent selector that lets applications and channels route a turn (or session default) directly to a statically declared local descendant agent, without requiring delegation through the root model. This threads the selection through eve’s HTTP API, TypeScript client, fixed sessions, cross-channel sends, and the durable turn/session workflow (including sandbox snapshot partitioning and HITL/authorization resumption).
Changes:
- Introduces a shared resolver + stable error contract for
agentpath selection and exposes selection across HTTP, client, sessions, and channel surfaces. - Extends durable session inbox + turn workflow inputs to carry a selected node id per turn, including migration/encoding updates and buffering partitioning.
- Updates sandbox persistence to key snapshots by sandbox owner node id and adds scenario + e2e coverage for direct routing behavior.
Reviewed changes
Copilot reviewed 80 out of 80 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| research/direct-agent-invocation.md | Research plan for routing semantics |
| packages/eve/test/scenarios/direct-agent-invocation.scenario.test.ts | End-to-end scenario coverage |
| packages/eve/test/scenarios/dev-server-harness.ts | Allow NODE_ENV override in harness |
| packages/eve/src/shared/channel-definition.ts | Add agent to receive input |
| packages/eve/src/runtime/agent-target.ts | Resolver + typed error contract |
| packages/eve/src/runtime/agent-target.test.ts | Unit tests for resolver |
| packages/eve/src/public/definitions/channel.ts | Export AgentTargetError types |
| packages/eve/src/public/channels/index.ts | Re-export AgentTargetError |
| packages/eve/src/internal/nitro/routes/schedule-task.ts | Wire resolver into schedule runtime |
| packages/eve/src/internal/nitro/routes/runtime-stack.ts | Add resolver to runtime bundle |
| packages/eve/src/internal/nitro/routes/channel-route-context.ts | Store/read resolver in route args |
| packages/eve/src/internal/nitro/routes/channel-dispatch.ts | Plumb resolver + agentNodeId create |
| packages/eve/src/harness/types.ts | Add per-owner sandboxStates |
| packages/eve/src/harness/messages.ts | Prevent coalescing across targets |
| packages/eve/src/execution/workflow-steps.ts | Select bundles per-turn + pending routing |
| packages/eve/src/execution/workflow-runtime.ts | createSession supports agentNodeId |
| packages/eve/src/execution/workflow-entry.ts | Resume pending agent on responses |
| packages/eve/src/execution/wire/session-inbox-wire.v2.ts | New wire v2 w/ agentNodeId |
| packages/eve/src/execution/wire/session-inbox-wire.v2.test.ts | Wire v2 tests + snapshots |
| packages/eve/src/execution/wire/session-inbox-wire.v1.test.ts | Update “future version” coverage |
| packages/eve/src/execution/wire/session-inbox-wire.ts | Add v1→v2 migration + decode agentNodeId |
| packages/eve/src/execution/wire/session-inbox-wire-v1-to-v2.ts | Migration: v1 to v2 |
| packages/eve/src/execution/wire/session-inbox-encoder.ts | Encode v2 + reject v1 targeted sends |
| packages/eve/src/execution/wire/session-inbox-contract.ts | Advertise supported versions 1,2 |
| packages/eve/src/execution/wire/snapshots/session-inbox-wire.v2.test.ts.snap | Snapshot for v2 schema |
| packages/eve/src/execution/turn-workflow.ts | Carry agentNodeId/defaultBundle through workflow |
| packages/eve/src/execution/turn-execution-cursor.ts | Persist default bundle across steps |
| packages/eve/src/execution/turn-agent-routing.ts | Bundle selection + pending agent tracking |
| packages/eve/src/execution/session.ts | Persist/hydrate sandboxStates |
| packages/eve/src/execution/session-command-inbox.test.ts | Expect wire version 2 |
| packages/eve/src/execution/runtime-context.ts | Initialize default sandbox owner node id |
| packages/eve/src/execution/pending-turn-agent.ts | Restore pending agent for responses |
| packages/eve/src/execution/pending-turn-agent.test.ts | Unit tests for pending agent restoration |
| packages/eve/src/execution/parked-delivery-wait.ts | Partition buffered deliveries by target |
| packages/eve/src/execution/parked-delivery-wait.test.ts | Test buffered partitioning |
| packages/eve/src/execution/durable-session-store.ts | Add sandboxStates to durable schema |
| packages/eve/src/execution/durable-session-migrations/turn-workflow.ts | Bump turn workflow input to v2 |
| packages/eve/src/execution/durable-session-migrations/turn-workflow.test.ts | Migration tests updated |
| packages/eve/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.ts | Migration adds agentNodeId/defaultBundle |
| packages/eve/src/execution/durable-session-migrations/turn-workflow-v0-to-v1.ts | Typing cleanup for migration |
| packages/eve/src/eve-channel/types.ts | Expose normalized ctx.eve.agent |
| packages/eve/src/eve-channel/support.ts | Plumb agent into onMessage ctx |
| packages/eve/src/eve-channel/request.ts | Parse/validate agent + op identity domain |
| packages/eve/src/eve-channel/request.test.ts | Tests for parsing + identity behavior |
| packages/eve/src/eve-channel/index.ts | Resolve target + serialize stable errors |
| packages/eve/src/context/run-step.ts | Provider commit now receives ctx |
| packages/eve/src/context/providers/sandbox.ts | Partition sandbox snapshots by owner |
| packages/eve/src/context/providers/sandbox.test.ts | Tests for alternating-agent snapshots |
| packages/eve/src/context/provider.ts | Commit signature includes ctx |
| packages/eve/src/context/keys.ts | Add DefaultSandboxOwnerNodeId + PendingTurnAgent |
| packages/eve/src/compiler/extension-compatibility.ts | Bump tool/channel/schedule epochs |
| packages/eve/src/client/types.ts | agent on send options only (not respond) |
| packages/eve/src/client/sessions.test.ts | Client serialization tests for agent |
| packages/eve/src/client/session.ts | Reject agent with inputResponses (client) |
| packages/eve/src/channel/types.ts | Carry agentNodeId in commands/deliveries |
| packages/eve/src/channel/session.ts | Fixed sessions accept agent + resolve before dispatch |
| packages/eve/src/channel/session.test.ts | Fixed-session routing tests |
| packages/eve/src/channel/schedule.ts | Plumb resolver into schedule to(...) |
| packages/eve/src/channel/cross-channel-receive.ts | Cross-channel sends carry agent |
| packages/eve/src/channel/cross-channel-receive.test.ts | Tests for propagation via receive |
| packages/eve/src/channel/compiled-channel.ts | Receive input includes agent |
| packages/eve/src/channel/channel-operations.ts | Operations accept request-scoped agent/resolver |
| packages/eve/src/channel/channel-address.ts | Address-level routing + agent constraints |
| packages/eve/src/channel/channel-address.test.ts | Routing + inputResponses rejection test |
| packages/eve/extension-contracts/reports/tool/v19.json | Generated capability report |
| packages/eve/extension-contracts/reports/schedule/v4.json | Generated capability report |
| packages/eve/extension-contracts/reports/channel/v10.json | Generated capability report |
| packages/eve/extension-contracts/entrypoints/channel.ts | Export AgentTargetError in entrypoint |
| packages/eve/extension-contracts/compatibility/tool/v18.ts | Compatibility fixture for tool epoch |
| packages/eve/extension-contracts/compatibility/schedule/v3.ts | Compatibility fixture for schedule epoch |
| packages/eve/extension-contracts/compatibility/channel/v9.ts | Compatibility fixture for channel epoch |
| e2e/fixtures/agent-subagents/evals/direct-invocation.eval.ts | E2E coverage for direct invocation |
| e2e/fixtures/agent-subagents/agent/subagents/echo-marker/subagents/nested-marker/instructions.md | Nested marker instructions |
| e2e/fixtures/agent-subagents/agent/subagents/echo-marker/subagents/nested-marker/agent.ts | Nested marker agent definition |
| e2e/fixtures/agent-subagents/agent/channels/direct.ts | Fixture channel exercising agent routing |
| docs/subagents/index.mdx | Document direct invocation on subagents |
| docs/guides/client/messages.mdx | Document client agent usage |
| docs/channels/eve.mdx | Document HTTP agent selector + errors |
| docs/channels/custom.mdx | Document custom channel dispatch w/ agent |
| .changeset/direct-agent-routing.md | Release note for new selector |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const payload = normalizeSendInput(sendInput); | ||
| const configuredAgent = options.agent ?? input.agent; | ||
| if (configuredAgent !== undefined && payload.inputResponses !== undefined) { | ||
| throw new Error( | ||
| "Cannot select an agent when delivering inputResponses. Input responses resume the agent that requested them.", | ||
| ); | ||
| } | ||
| const requestedAgent = payload.message === undefined ? undefined : configuredAgent; | ||
| const agentTarget = resolveRequestedAgent(input.resolveAgentTarget, requestedAgent); |
Summary
Closes #393. This adds one root-relative
agentselector across the eve HTTP API, TypeScript client, fixed sessions, and channel sends so applications can invoke a statically declared descendant without asking the parent model to delegate.Creating a session with
agentmakes that descendant the session default; setting it on an existing session selects the descendant for one turn and then returns to the original default:The same selector is available to channels, including
from(threadId).send(message, { agent })and cross-channel sends, which supports adapters implementing commands such as/researcher investigate this. Selected turns keep the same session ID, continuation, auth, channel state, and model history while using the descendant's model, instructions, tools, skills, hooks, connections, and sandbox; HITL responses resume the selected descendant automatically. V1 intentionally accepts only entirely static local paths, returns stable errors for malformed, missing, dynamic, or remote targets, and emits ordinary session/channel events rather than synthetic subagent lifecycle events.Reviewer focus
The durable boundary now carries an internal node ID in versioned session-inbox and turn-workflow payloads. Buffered deliveries are partitioned by target, pending HITL retains the selected node, and sandbox snapshots are keyed by sandbox owner so alternating root and descendant turns do not overwrite one another; the session's original bundle remains its durable default.
Validation
The eve unit suite passed with 7,123 tests and one skip. A built-app scenario covers shared history, targeted defaults, nested paths, target-specific instructions/tools/hooks/sandbox, HITL recovery, mixed-target queueing and steering, channel event flow, and rejection cases; the expanded
agent-subagentsE2E fixture typechecks, while its real-model eval will run only in CI.Checklist
CONTRIBUTING.mdevepackagegit commit --signoff)Diff size
Docs — 6 files ·
+223 / -3Documents the HTTP, client, subagent, and channel authoring surfaces, records the implementation plan for #393, and adds release metadata.
Implementation — 51 files ·
+741 / -76The selector crosses the public boundaries, durable workflow inputs, runtime bundle selection, and sandbox persistence. The implementation reuses one resolver and the existing session workflow; this category also includes the three generated extension-capability reports required by the additive API changes.
Tests — 23 files ·
+1195 / -5Most of the test diff is the built-app scenario and E2E fixture needed to exercise routing across real HTTP, client, channel, HITL, queue/steer, and sandbox lifecycles. Unit coverage owns parsing, resolver errors, wire migration, operation identity, delivery partitioning, pending-agent recovery, and sandbox ownership.