fix(eve): persist text streams as deltas - #2867
Conversation
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Bundle + Package Summary:
|
| Area | Metric | Baseline | Current | Delta |
|---|---|---|---|---|
| Package | Packed tarball | 8.62 MB | 8.62 MB | +2.6 kB |
| Package | Unpacked publish size | 32.46 MB | 32.48 MB | +21.9 kB |
| Package | Installed footprint | 77.62 MB | 77.64 MB | +21.9 kB |
| Package | Published files | 3769 | 3775 | +6 |
| Package | Installed files | 7615 | 7621 | +6 |
| 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 | 20.31 MB | 20.32 MB | +7.9 kB |
| Runtime | Public routes | 18 | 18 | 0 |
Changed function payloads vs main (23a4b59) (2)
| Function | Status | Baseline | Current | Delta | Route changes |
|---|---|---|---|---|---|
functions/__server.func |
changed | 10.16 MB | 10.16 MB | +4.0 kB |
none |
functions/.well-known/workflow/v1/flow.func |
changed | 10.16 MB | 10.16 MB | +4.0 kB |
none |
eve init install
| Metric | Baseline | Current | Delta |
|---|---|---|---|
| Installed footprint | 116.06 MB | 116.08 MB | +21.9 kB |
| Installed packages | 120 | 120 | 0 |
| dependencies | 4 | 4 | 0 |
| devDependencies | 2 | 2 | 0 |
| Dependency package bytes | 48.52 MB | 48.54 MB | +21.9 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-09-02T21:09:29.791Z
- 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.49.0 - Package directory:
packages/eve - Tarball: 8.62 MB (
eve-0.49.0.tgz) - Unpacked payload: 32.48 MB across 3775 published files
- Installed footprint: 77.64 MB across 7621 installed files
- Installed root package: 31.02 MB
- Installed dependencies: 46.63 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: 31.02 MB (39.9%)@rolldown/binding-linux-x64-gnu: 19.31 MB (24.9%)ai: 6.98 MB (9.0%)zod: 6.41 MB (8.3%)undici: 3.50 MB (4.5%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js [#############...........] 9.76 MB 30.1%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [###.....................] 2.27 MB 7.0%
🟠 dist/src/compiled/@ai-sdk/code-mode/index.js [#.......................] 1.03 MB 3.2%
🟡 dist/src/compiled/@vercel/blob/index.js [#.......................] 901.8 kB 2.8%
🟡 dist/src/compiled/_chunks/workflow/undici-Dfx... [#.......................] 512.5 kB 1.6%
🔴 Other published files [########################] 18.01 MB 55.4%
Installed footprint breakdown
Installed package size
🔴 eve [########################] 31.02 MB 39.9%
🔴 @rolldown/binding-linux-x64-gnu [###############.........] 19.31 MB 24.9%
🔴 ai [#####...................] 6.98 MB 9.0%
🔴 zod [#####...................] 6.41 MB 8.3%
🟠 undici [###.....................] 3.50 MB 4.5%
🟠 nitro [##......................] 2.41 MB 3.1%
🔴 Other installed packages [######..................] 8.00 MB 10.3%
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: 116.08 MB across 9517 installed files
- Installed packages: 120 total (114 transitive-only)
- dependencies: 4 direct packages totaling 48.54 MB
- devDependencies: 2 direct packages totaling 5.04 MB
- Other transitive package files: 62.50 MB
Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.
Heavy installed dependencies
eve: 31.02 MB (26.7%)@typescript/typescript-linux-x64: 27.95 MB (24.1%)@rolldown/binding-linux-x64-gnu: 19.31 MB (16.6%)zod: 10.37 MB (8.9%)ai: 6.98 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 eve [########################] 31.02 MB 26.7%
🔴 @typescript/typescript-linux-x64 [######################..] 27.95 MB 24.1%
🔴 @rolldown/binding-linux-x64-gnu [###############.........] 19.31 MB 16.6%
🔴 zod [########................] 10.37 MB 8.9%
🔴 ai [#####...................] 6.98 MB 6.0%
🟠 undici [###.....................] 3.50 MB 3.0%
🔴 Other installed packages [#############...........] 16.94 MB 14.6%
dependencies (4)
| Package | Range | Installed size | Share |
|---|---|---|---|
@vercel/connect |
1.0.0 |
167.9 kB | 0.1% |
ai |
^7.0.82 |
6.98 MB | 6.0% |
eve |
file:eve-0.49.0.tgz |
31.02 MB | 26.7% |
zod |
4.5.4 |
10.37 MB | 8.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.16 MB 50.0%
🔴 functions/__server.func [########################] 10.16 MB 50.0%
Top Function Payloads
🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 10.16 MB
| Metric | Value |
|---|---|
| Public routes | /.well-known/workflow/v1/flow |
| Runtime | nodejs24.x |
| Handler | index.mjs |
| Payload | 10.16 MB |
| Function files | 10.16 MB across 111 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 2.15 MB (21.1%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [##########..............] 2.15 MB 21.1%
🟡 _libs/undici.mjs [#####...................] 980.5 kB 9.7%
🟡 _chunks/decode_jwt-Col8JOnf.mjs [###.....................] 702.6 kB 6.9%
🟡 _chunks/rename-with-retry.mjs [###.....................] 695.6 kB 6.8%
🟡 _chunks/frames-CZ9eHShe.mjs [###.....................] 679.1 kB 6.7%
🔴 Other bundled files [########################] 4.96 MB 48.8%
🧾 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.16 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.16 MB |
| Function files | 10.16 MB across 111 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 2.15 MB (21.1%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [##########..............] 2.15 MB 21.1%
🟡 _libs/undici.mjs [#####...................] 980.5 kB 9.7%
🟡 _chunks/decode_jwt-Col8JOnf.mjs [###.....................] 702.6 kB 6.9%
🟡 _chunks/rename-with-retry.mjs [###.....................] 695.6 kB 6.8%
🟡 _chunks/frames-CZ9eHShe.mjs [###.....................] 679.1 kB 6.7%
🔴 Other bundled files [########################] 4.96 MB 48.8%
🧾 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.81 s -> 2.68 s (-121.9 ms) vs
main (23a4b59). - Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (23a4b59)`
| Phase | Baseline | Current | Delta |
|---|---|---|---|
extension.check |
12.7 ms | 1.1 ms | -11.6 ms |
project.resolve |
0.4 ms | 0.4 ms | 0.0 ms |
workspace.create |
0.7 ms | 0.8 ms | +0.1 ms |
host.prepare |
543.9 ms | 475.0 ms | -68.9 ms |
vercel.service-prefix.resolve |
1.8 ms | 1.9 ms | +0.1 ms |
nitro.create |
495.0 ms | 484.3 ms | -10.7 ms |
sandbox.prewarm |
261.5 ms | 247.7 ms | -13.8 ms |
nitro.cache.prepare |
0.2 ms | 0.3 ms | +0.1 ms |
nitro.prepare |
0.7 ms | 0.7 ms | 0.0 ms |
nitro.public-assets |
0.7 ms | 0.7 ms | 0.0 ms |
nitro.prerender |
0.4 ms | 0.5 ms | +0.1 ms |
nitro.bundle |
1.44 s | 1.42 s | -16.9 ms |
nitro.cache.write |
0.3 ms | 0.3 ms | 0.0 ms |
vercel.workflow-function.materialize |
43.0 ms | 42.6 ms | -0.4 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.1 ms | 3.3 ms | +0.2 ms |
workspace.remove |
1.9 ms | 1.8 ms | -0.1 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>
|
Why do we have an offset vs just using the chunk which is closer to what providers and ai sdk use? |
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
The reasoning was to provide a way for clients, during reconnect midstream, to distinguish if the current
But these are theoretical and not consistent with other |
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
…#533) ## Summary The hourly sweep in `apps/worker/src/runtime/workflow-world-reaper.ts` only ever pruned `workflow_stream_chunks` in the legacy `eveland_wf_*` per-project databases that `@workflow/world-postgres` deployments used. No legacy Deployment remains: every build bakes in `@evelandhq/workflow-world`, whose dispatcher runs its own bounded stream and graph retention every minute, so the worker-side sweep had nothing left to scan. Removed: - `workflow-world-reaper.ts`, `workflow-stream-retention.ts` and their tests; the scheduler wiring and shutdown hook in `worker.ts`. - `EVELAND_WORKFLOW_SWEEP_INTERVAL_MS`, `EVELAND_WORKFLOW_STREAM_RETENTION_MS`, `EVELAND_WORKFLOW_SWEEP_BATCH_SIZE` from config diagnostics, the systemd env example and both reference docs. Untouched: the `WORKFLOW_POSTGRES_URL` legacy bootstrap/drop path, which is tied to release attestation's `workflow_world_kind` and the delete-project flow; that is a separate data-model cleanup. Context: vercel/eve#1441 (source fix landed as vercel/eve#2867), #213. ## Test plan - [x] `pnpm typecheck` (worker, core), `pnpm lint` - [x] `pnpm --filter ./packages/core test` and `pnpm --filter ./apps/worker test` against a local Postgres 17 with `EVELAND_POSTGRES_TEST_URL`
Summary
Before
{ "messageDelta": "Revenue", "messageSoFar": "Revenue" } { "messageDelta": " increased", "messageSoFar": "Revenue increased" } { "messageDelta": " by 12%", "messageSoFar": "Revenue increased by 12%" }After
{ "messageDelta": "Revenue" } { "messageDelta": " increased" } { "messageDelta": " by 12%" }reasoning.appendedandaction.input.appendednow have the same shape: each event persists only the new chunk plus its existing turn, step, and call coordinates. Empty tool-input starts no longer emit an append event; the first append contains actual input text.Consumers that need text-so-far accumulate chunks in stream order. The default reducer, TUI, Slack, Chat SDK, and Next.js trace consumer now do that locally. Slack still posts final answers from
message.completed; its progressive reasoning accumulator resets at reasoning completion and turn/step boundaries.The durable event index remains the reconnect cursor, and stable event IDs deduplicate replay overlap. The protocol does not add a second text position or block-boundary mechanism.
The stream version advances from 24 to 25. The client and server normalize v21-v24 cumulative message/reasoning events and v24 tool-input offsets into the current delta-only shape. Missing deltas and append fields that contradict the declared version fail at the decode boundary. Published extensions whose capability contract changed must be rebuilt and republished.
Provider retries remain append-only: events emitted by an interrupted attempt stay durable. A later completed event can replace provisional text in replaceable consumers; the TUI now replaces its still-live block before committing the completed text. A block completed before its attempt later fails cannot be retracted without adding attempt identity.
Reproduction
The same 159-call, 414,436-event sequence was encoded with the cumulative and delta-only formats:
reasoningSoFarpayloadmessageSoFarpayloadThe cumulative stream was 133.46 times the delta-only size; the new stream is 0.75% of the previous size. These are serialized eve protocol bytes before Workflow framing, not billed Workflow Data Written.
Validation
The matched replay sends the same chunk sequence through the cumulative and current eve emitters and protocol encoders. The delta full branch passed 7,758 unit tests and 711 integration tests. The final TUI repair passes 298 focused TUI tests, both provider-retry integration tests, and eve typecheck; CI remains the authoritative full-commit result.
Tests cover delta accumulation and coalescing, provider retry output, legacy replay, reconnects across stream versions, malformed v25 events, and built-in client, Chat SDK, Slack, TUI, ACP, and trace consumers. The TUI regression asserts that discarded retry text is absent from the committed transcript and the recovered answer appears once.
Checklist
CONTRIBUTING.mdevepackagegit commit --signoff)Diff size
Docs — 4 files ·
+112 / -8Explains the delta-only wire format, consumer migration, reconnect semantics, and retry limitation.
Implementation — 29 files ·
+627 / -190Removes cumulative snapshots and tool-input offsets, normalizes supported historical streams, validates the v25 shape, and migrates first-party consumers. Eight generated capability reports record the breaking author-facing event contract.
Tests — 30 files ·
+933 / -129Covers byte scaling, accumulation, coalescing, retry behavior, legacy replay, reconnects, malformed events, and first-party consumer behavior.