Skip to content

feat(eve): workflow-tool subagents with per-call background launch and task_join - #2167

Closed
ruiconti wants to merge 12 commits into
rui/subagent-workflow-tool-spike-basefrom
rui/subagent-workflow-tool-spike
Closed

ruiconti wants to merge 12 commits into
rui/subagent-workflow-tool-spike-basefrom
rui/subagent-workflow-tool-spike

Conversation

@ruiconti

@ruiconti ruiconti commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Related to #1084. Two layers on the frozen base (tasks-v4/03-runtime at 37314a9f):

  1. Subagents as workflow tools — with experimental.tasks, local and remote subagents are framework-owned defineTool(...) definitions whose execute values are separately compiled Workflow functions. Unchanged from the prior revision of this PR.
  2. Per-call detach/join (new) — the sync/background choice moves from the agent-global flag to each call; a new task_join lets a turn block on a background task; a plain workflow-backed tool can be task-backed. Design and evidence live in SPIKE.md at the repo root.

Layer 2 — per-call launch mode

Before → after: experimental.tasks made every delegation settle with a task receipt, decided per batch → the model chooses per call. background: true on a subagent call takes the receipt path; omitted means the call dispatches on the plain foreground wire and the turn parks on its result. Mixed batches work in one turn: receipts seed the wait loop's initial results while foreground keys resolve from the inbox.

Two boundaries worth review:

  • Continuations (agentId resumes) always take the task path regardless of the flag — AGENT_BUSY session exclusivity is enforced there, and a foreground resume of a task-owned session would bypass it.
  • Interrupt-sourced batches (dynamic workflow) carry no model arguments, so they now default to foreground under tasks agents. This is a behavior change from the prior revision, where they all became tasks.

The flag lives on a new tasks schema variant, so persistent-session-only agents don't see dead surface.

Layer 2 — task_join

Before → after: a turn could not block on a task; the model paced itself with task_sleep + re-peek → task_join(taskId) settles immediately when the task is ready, otherwise the call's key stays pending and the turn's wait races its inbox against a 2s durable sleep, polling the task view per tick.

"Ready" is terminal or input_required: input wakes are message-less deliveries the driver buffers mid-turn, so a terminal-only join deadlocks against a task waiting on a human.

Every answer to a pending call — child-reported or framework-written — now enters the wait through one function, acceptResult in turn-workflow.ts. That is the seam a future mid-flight detach reuses: same entry point, fed a synthesized {taskId, status: "working"} receipt for a still-pending foreground call. PendingTaskJoin carries its result key precomputed because framework-tool modules cannot enter the workflow body bundle (their import graph reaches Node builtins).

Layer 2 — tool tasks

A plain defineTool whose execute is a compiled Workflow function dispatches as a kind: "tool" task: a framework executor run starts the tool's Workflow, awaits it, and reports the terminal outcome to the task run, which stays the sole lifecycle writer. Not wired into model-facing dispatch — the integration test drives dispatchToolTask directly; this layer proves the seam, nothing more. TaskMetadata.kind widened to "subagent" | "tool"; tool tasks never project into <agents>.

Layer 1 — subagents as workflow tools (prior revision, unchanged)

Task-mode delegation ran inside one parent dispatch step → task dispatch selects the local or remote framework tool definition and starts its compiler-assigned Workflow before re-entering the existing durable task lifecycle. Definitions under runtime/framework-tools/subagent; executors under execution, keeping definition-time schema and branding code out of the compiled Workflow program (payload delta at the time: +13,891 bytes per function vs. ~2.09 MB for the combined shape). The durable task run remains the sole lifecycle writer; local HITL uses the child continuation hook, remote HITL the task callback capability.

Known residuals

  • The wrapper Workflow start() inside a retryable step is at-least-once; identities stay deterministic but no wrapper-run idempotency key is persisted. The tool-task executor shares this.
  • A joined task's own :ready: notification still replays as a user-visible delivery next turn; dedup needs the driver's seenTaskDeliveries machinery.
  • A join on a task whose run died pends until turn cancellation; timeout policy is future work.
  • e2e eval anchors are out of scope here — fixture-tasks lives on rui/child-task-send.

Validation

Unit (631 files, 6,616 passed, 1 skipped) and integration (90 files, 646 passed) suites green; typecheck, lint, format, and invariant guards pass. The three integration tests named in SPIKE.md are the demo: mixed-batch dispatch, join over a real child/task run (pending → poll-settled → immediate), and the tool task reaching completed and joining.

Checklist

  • I linked an issue with prior discussion confirming this change is wanted
  • 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)

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

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
eve-docs Ready Ready Preview Aug 18, 2026 4:26pm
eve-docs-4759 Ready Ready Preview, v0 Aug 18, 2026 4:26pm
eve-pkg Ready Ready Preview Aug 18, 2026 4:26pm

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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

Key takeaways

  • No notable deltas vs rui/subagent-workflow-tool-spike-base (37314a9).

Delta vs rui/subagent-workflow-tool-spike-base (37314a9)

Area Metric Baseline Current Delta
Package Packed tarball 8.01 MB 8.01 MB +3.2 kB ⚠️
Package Unpacked publish size 29.89 MB 29.90 MB +14.7 kB ⚠️
Package Installed footprint 73.42 MB 73.43 MB +14.7 kB ⚠️
Package Published files 3236 3250 +14
Package Installed files 6944 6958 +14
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 17.54 MB 17.57 MB +27.6 kB ⚠️
Runtime Public routes 16 16 0
Changed function payloads vs rui/subagent-workflow-tool-spike-base (37314a9) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 8.77 MB 8.79 MB +13.8 kB ⚠️ none
functions/.well-known/workflow/v1/flow.func changed 8.77 MB 8.79 MB +13.8 kB ⚠️ none

eve init install

Metric Baseline Current Delta
Installed footprint 111.83 MB 111.84 MB +14.7 kB ⚠️
Installed packages 121 121 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 44.39 MB 44.40 MB +14.7 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-18T17:08:56.383Z
  • 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.35.0
  • Package directory: packages/eve
  • Tarball: 8.01 MB (eve-0.35.0.tgz)
  • Unpacked payload: 29.90 MB across 3250 published files
  • Installed footprint: 73.43 MB across 6958 installed files
  • Installed root package: 28.55 MB
  • Installed dependencies: 44.88 MB
  • Runtime dependencies: 2
  • Peer dependencies: 5 (4 optional)

Installed footprint is measured from an isolated temporary npm install of the packed tarball.

Heavy installed dependencies

  • eve: 28.55 MB (38.9%)
  • @rolldown/binding-linux-x64-gnu: 19.41 MB (26.4%)
  • ai: 6.69 MB (9.1%)
  • zod: 5.07 MB (6.9%)
  • undici: 3.50 MB (4.8%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js       [#################.......] 10.19 MB 34.1%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [####....................] 2.42 MB 8.1%
🟠 dist/src/compiled/experimental-ai-sdk-code-mo... [##......................] 1.51 MB 5.0%
🟡 dist/src/compiled/_chunks/node/undici-CUIybhQ... [#.......................] 508.8 kB 1.7%
🟡 dist/src/compiled/_chunks/workflow/undici-CUI... [#.......................] 508.8 kB 1.7%
🔴 Other published files                            [########################] 14.76 MB 49.4%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 28.55 MB 38.9%
🔴 @rolldown/binding-linux-x64-gnu [################........] 19.41 MB 26.4%
🔴 ai                              [######..................] 6.69 MB 9.1%
🔴 zod                             [####....................] 5.07 MB 6.9%
🟠 undici                          [###.....................] 3.50 MB 4.8%
🟠 nitro                           [##......................] 2.41 MB 3.3%
🔴 Other installed packages        [#######.................] 7.81 MB 10.6%
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.0.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: 111.84 MB across 8834 installed files
  • Installed packages: 121 total (115 transitive-only)
  • dependencies: 4 direct packages totaling 44.40 MB
  • devDependencies: 2 direct packages totaling 5.04 MB
  • Other transitive package files: 62.40 MB

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

Heavy installed dependencies

  • eve: 28.55 MB (25.5%)
  • @typescript/typescript-linux-x64: 27.95 MB (25.0%)
  • @rolldown/binding-linux-x64-gnu: 19.41 MB (17.4%)
  • zod: 9.02 MB (8.1%)
  • ai: 6.69 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 eve                              [########################] 28.55 MB 25.5%
🔴 @typescript/typescript-linux-x64 [#######################.] 27.95 MB 25.0%
🔴 @rolldown/binding-linux-x64-gnu  [################........] 19.41 MB 17.4%
🔴 zod                              [########................] 9.02 MB 8.1%
🔴 ai                               [######..................] 6.69 MB 6.0%
🟠 undici                           [###.....................] 3.50 MB 3.1%
🔴 Other installed packages         [##############..........] 16.72 MB 14.9%
dependencies (4)
Package Range Installed size Share
@vercel/connect 0.4.3 141.0 kB 0.1%
ai ^7.0.58 6.69 MB 6.0%
eve file:eve-0.35.0.tgz 28.55 MB 25.5%
zod 4.4.3 9.02 MB 8.1%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.54 MB 2.3%
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     [########################] 8.79 MB 50.0%
🔴 functions/__server.func                         [########################] 8.79 MB 50.0%

Top Function Payloads

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

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                     [#################.......] 1.97 MB 22.4%
🟠 _chunks/runtime-artifacts.mjs [###############.........] 1.66 MB 18.9%
🟡 _libs/undici.mjs              [#########...............] 980.5 kB 11.2%
🟡 _chunks/sandbox.mjs           [#######.................] 777.7 kB 8.9%
🟡 _chunks/frames-CTpeJYEQ.mjs   [######..................] 671.5 kB 7.6%
🟠 Other bundled files           [########################] 2.72 MB 31.0%

🧾 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 • 8.79 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 8.79 MB
Function files 8.79 MB across 50 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 1.97 MB (22.4%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                     [#################.......] 1.97 MB 22.4%
🟠 _chunks/runtime-artifacts.mjs [###############.........] 1.66 MB 18.9%
🟡 _libs/undici.mjs              [#########...............] 980.5 kB 11.2%
🟡 _chunks/sandbox.mjs           [#######.................] 777.7 kB 8.9%
🟡 _chunks/frames-CTpeJYEQ.mjs   [######..................] 671.5 kB 7.6%
🟠 Other bundled files           [########################] 2.72 MB 31.0%

🧾 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.11 s -> 2.19 s (+87.0 ms) vs rui/subagent-workflow-tool-spike-base (37314a9).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `rui/subagent-workflow-tool-spike-base (37314a9)`
Phase Baseline Current Delta
extension.check 1.1 ms 1.1 ms 0.0 ms
project.resolve 0.5 ms 0.4 ms -0.1 ms
workspace.create 0.5 ms 0.6 ms +0.1 ms
host.prepare 290.8 ms 204.0 ms -86.8 ms
vercel.service-prefix.resolve 2.0 ms 1.6 ms -0.4 ms
nitro.create 217.7 ms 238.7 ms +21.0 ms
sandbox.prewarm 394.8 ms 360.5 ms -34.3 ms
nitro.cache.prepare 0.2 ms 0.2 ms 0.0 ms
nitro.prepare 0.6 ms 0.7 ms +0.1 ms
nitro.public-assets 0.6 ms 0.6 ms 0.0 ms
nitro.prerender 0.4 ms 0.4 ms 0.0 ms
nitro.bundle 1.11 s 1.17 s +56.4 ms
nitro.cache.write 0.3 ms 0.2 ms -0.1 ms
vercel.workflow-function.materialize 68.8 ms 41.2 ms -27.6 ms
agent-summary.emit 0.4 ms 0.5 ms +0.1 ms
nitro.close 0.1 ms 0.1 ms 0.0 ms
output.publish 9.5 ms 168.4 ms +158.9 ms
workspace.remove 1.9 ms 1.6 ms -0.3 ms

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

Copy link
Copy Markdown
Contributor Author

Superseded by #2255, which rebases this work onto main instead of the frozen tasks-v4/03-runtime base. Per-call background launch, task_join, and tool-backed tasks land separately, stacked on #2255.

@ruiconti ruiconti closed this Aug 18, 2026
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.

1 participant