feat(eve): keep local tracing on with authored instrumentation - #1306
Draft
chadhietala wants to merge 3 commits into
Draft
feat(eve): keep local tracing on with authored instrumentation#1306chadhietala wants to merge 3 commits into
chadhietala wants to merge 3 commits into
Conversation
`eve dev` gated its zero-config trace writer on the absence of `agent/instrumentation.ts`, so adding an exporter for Honeycomb or Datadog cost you `.eve/traces/v1` and the whole `eve trace` loop. eve now adopts the authored provider instead of competing with it. The global registered by `setGlobalTracerProvider` is a `ProxyTracerProvider`, so eve swaps its delegate for one that observes every tracer it hands out. The authored exporter keeps receiving everything it did before and additionally sees eve's `agent.*` spans; eve spools the same spans to disk. When nothing is registered, eve registers its own provider exactly as before. The dev plugin is ordered after the authored instrumentation plugin so a provider exists to adopt, and a failed registration probe now warns and installs nothing rather than throwing — a development convenience must not take down a dev server whose instrumentation is otherwise fine. Production is untouched. Signed-off-by: Chad Hietala <chadhietala@gmail.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
chadhietala
marked this pull request as draft
July 29, 2026 00:31
Contributor
Bundle + Package Summary:
|
| Area | Metric | Baseline | Current | Delta |
|---|---|---|---|---|
| Package | Packed tarball | 7.59 MB | 7.61 MB | +16.1 kB |
| Package | Unpacked publish size | 28.70 MB | 28.75 MB | +52.3 kB |
| Package | Installed footprint | 69.82 MB | 69.88 MB | +52.3 kB |
| Package | Published files | 2854 | 2863 | +9 |
| Package | Installed files | 6327 | 6336 | +9 |
| Runtime | Unique function payloads | 2 | 2 | 0 |
| Runtime | Total function bytes | 16.70 MB | 16.72 MB | +26.6 kB |
| Runtime | Public routes | 11 | 11 | 0 |
Changed function payloads vs main (c27b44a) (2)
| Function | Status | Baseline | Current | Delta | Route changes |
|---|---|---|---|---|---|
functions/__server.func |
changed | 8.35 MB | 8.36 MB | +13.3 kB |
none |
functions/.well-known/workflow/v1/flow.func |
changed | 8.35 MB | 8.36 MB | +13.3 kB |
none |
eve init install
| Metric | Baseline | Current | Delta |
|---|---|---|---|
| Installed footprint | 108.23 MB | 108.28 MB | +52.3 kB |
| Installed packages | 123 | 123 | 0 |
| dependencies | 4 | 4 | 0 |
| devDependencies | 2 | 2 | 0 |
| Dependency package bytes | 43.02 MB | 43.07 MB | +52.2 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-07-29T01:41:10.886Z
- Route aliases: 11 public, 1 internal (12 total aliases)
- Vercel routes in config: 14
- Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down
Package Details
- Package:
eve@0.27.11 - Package directory:
packages/eve - Tarball: 7.61 MB (
eve-0.27.11.tgz) - Unpacked payload: 28.75 MB across 2863 published files
- Installed footprint: 69.88 MB across 6336 installed files
- Installed root package: 27.39 MB
- Installed dependencies: 42.48 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: 27.39 MB (39.2%)@rolldown/binding-linux-x64-gnu: 18.96 MB (27.1%)ai: 6.52 MB (9.3%)zod: 5.07 MB (7.3%)nitro: 2.41 MB (3.4%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js [########################] 13.15 MB 45.7%
🟠 dist/src/compiled/experimental-ai-sdk-code-mo... [###.....................] 1.51 MB 5.2%
🟡 dist/src/compiled/@vercel/sandbox/index.js [#.......................] 632.5 kB 2.2%
🟡 dist/src/compiled/_chunks/workflow/undici-DWL... [#.......................] 502.4 kB 1.7%
🟡 dist/src/compiled/@chat-adapter/slack/index.js [#.......................] 440.5 kB 1.5%
🔴 Other published files [#######################.] 12.52 MB 43.5%
Installed footprint breakdown
Installed package size
🔴 eve [########################] 27.39 MB 39.2%
🔴 @rolldown/binding-linux-x64-gnu [#################.......] 18.96 MB 27.1%
🔴 ai [######..................] 6.52 MB 9.3%
🔴 zod [####....................] 5.07 MB 7.3%
🟠 nitro [##......................] 2.41 MB 3.4%
🟠 undici [##......................] 1.86 MB 2.7%
🔴 Other installed packages [#######.................] 7.67 MB 11.0%
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: 108.28 MB across 8204 installed files
- Installed packages: 123 total (117 transitive-only)
- dependencies: 4 direct packages totaling 43.07 MB
- devDependencies: 2 direct packages totaling 5.04 MB
- Other transitive package files: 60.17 MB
Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.
Heavy installed dependencies
@typescript/typescript-linux-x64: 27.95 MB (25.8%)eve: 27.39 MB (25.3%)@rolldown/binding-linux-x64-gnu: 18.96 MB (17.5%)zod: 9.02 MB (8.3%)ai: 6.52 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 @typescript/typescript-linux-x64 [########################] 27.95 MB 25.8%
🔴 eve [########################] 27.39 MB 25.3%
🔴 @rolldown/binding-linux-x64-gnu [################........] 18.96 MB 17.5%
🔴 zod [########................] 9.02 MB 8.3%
🔴 ai [######..................] 6.52 MB 6.0%
🟠 @types/node [##......................] 2.54 MB 2.3%
🔴 Other installed packages [##############..........] 15.90 MB 14.7%
dependencies (4)
| Package | Range | Installed size | Share |
|---|---|---|---|
@vercel/connect |
0.4.2 |
135.8 kB | 0.1% |
ai |
^7.0.38 |
6.52 MB | 6.0% |
eve |
file:eve-0.27.11.tgz |
27.39 MB | 25.3% |
zod |
4.4.3 |
9.02 MB | 8.3% |
devDependencies (2)
| Package | Range | Installed size | Share |
|---|---|---|---|
@types/node |
24.x |
2.54 MB | 2.3% |
typescript |
7.0.2 |
2.50 MB | 2.3% |
Function Drill-Down
Payload Size Graph
Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func [########################] 8.36 MB 50.0%
🔴 functions/__server.func [########################] 8.36 MB 50.0%
Top Function Payloads
🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 8.36 MB
| Metric | Value |
|---|---|
| Public routes | /.well-known/workflow/v1/flow |
| Runtime | nodejs24.x |
| Handler | index.mjs |
| Payload | 8.36 MB |
| Function files | 8.36 MB across 44 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 2.26 MB (27.1%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [#######################.] 2.26 MB 27.1%
🟠 _chunks/runtime-artifacts.mjs [################........] 1.59 MB 19.0%
🟡 _libs/undici.mjs [##########..............] 980.5 kB 11.7%
🟡 _chunks/sandbox.mjs [########................] 768.8 kB 9.2%
🟡 _libs/@ai-sdk/gateway+[...].mjs [####....................] 432.8 kB 5.2%
🟠 Other bundled files [########################] 2.33 MB 27.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 • 10 public routes, 1 internal alias • 8.36 MB
| Metric | Value |
|---|---|
| Public routes | //eve/v1/callback/[token]/eve/v1/connections/[name]/callback/[token]/eve/v1/health/eve/v1/info/eve/v1/session/eve/v1/session/[sessionId]/eve/v1/session/[sessionId]/cancel/eve/v1/session/[sessionId]/stream/eve/v1/session/reset |
| Internal aliases | /__server |
| Runtime | nodejs24.x |
| Handler | index.mjs |
| Payload | 8.36 MB |
| Function files | 8.36 MB across 44 files |
| Traced dependencies | 0 B |
| Signal | 🟠 Bundled file index.mjs is 2.26 MB (27.1%) |
🟠 🔎 Dependency Analysis
📦 Bundled files:
Bundled file size
🟠 index.mjs [#######################.] 2.26 MB 27.1%
🟠 _chunks/runtime-artifacts.mjs [################........] 1.59 MB 19.0%
🟡 _libs/undici.mjs [##########..............] 980.5 kB 11.7%
🟡 _chunks/sandbox.mjs [########................] 768.8 kB 9.2%
🟡 _libs/@ai-sdk/gateway+[...].mjs [####....................] 432.8 kB 5.2%
🟠 Other bundled files [########################] 2.32 MB 27.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: 1.95 s -> 1.79 s (-158.0 ms) vs
main (c27b44a). - Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (c27b44a)`
| Phase | Baseline | Current | Delta |
|---|---|---|---|
extension.check |
1.1 ms | 11.1 ms | +10.0 ms |
project.resolve |
0.6 ms | 1.0 ms | +0.4 ms |
workspace.create |
0.7 ms | 5.2 ms | +4.5 ms |
host.prepare |
282.2 ms | 173.9 ms | -108.3 ms |
vercel.service-prefix.resolve |
2.0 ms | 1.7 ms | -0.3 ms |
nitro.create |
203.1 ms | 177.5 ms | -25.6 ms |
sandbox.prewarm |
172.5 ms | 183.0 ms | +10.5 ms |
nitro.cache.prepare |
0.3 ms | 0.3 ms | 0.0 ms |
nitro.prepare |
0.8 ms | 0.8 ms | 0.0 ms |
nitro.public-assets |
0.7 ms | 0.7 ms | 0.0 ms |
nitro.prerender |
0.5 ms | 0.6 ms | +0.1 ms |
nitro.bundle |
1.25 s | 1.20 s | -49.8 ms |
nitro.cache.write |
0.4 ms | 0.3 ms | -0.1 ms |
vercel.workflow-function.materialize |
21.4 ms | 22.1 ms | +0.7 ms |
agent-summary.emit |
0.5 ms | 0.5 ms | 0.0 ms |
nitro.close |
0.1 ms | 0.1 ms | 0.0 ms |
output.publish |
3.3 ms | 3.3 ms | 0.0 ms |
workspace.remove |
2.0 ms | 2.0 ms | 0.0 ms |
De-ASI-INTERFACE
approved these changes
Jul 29, 2026
`trace.getTracerProvider()` returns a `ProxyTracerProvider` whether or not anyone registered one: with nothing registered the API hands back its own standby proxy rather than a no-op. The duck-typed check saw `setDelegate` on that standby, wrapped the no-op delegate, and skipped `registerOTel` — so on the zero-config path, which is the common one, no processor was ever attached and no context manager registered. Every `eve dev` run without an authored `instrumentation.ts` logged "eve could not observe OpenTelemetry spans" and wrote nothing. Compare delegates instead. A fresh proxy's delegate is the shared no-op singleton, so a delegate that differs from it is the one an author registered. The unit test for the no-provider case passed over a fake that had no `getDelegate` at all, which is not what an unclaimed process looks like. It now also covers a real `ProxyTracerProvider` with no delegate set. Signed-off-by: Chad Hietala <chadhietala@gmail.com>
Review of the always-on local tracing change surfaced five defects. Adoption swapped a proxy's delegate after authored `setup()` had run, which is too late: `ProxyTracerProvider.getTracer` hands out the delegate's concrete tracer once a delegate exists, so any tracer the authored setup created — an auto-instrumentation's, say — kept a direct reference eve could never reach. eve now claims the global `@opentelemetry/api` registry slot from a plugin that runs *before* authored instrumentation, so every tracer the author's provider hands out is observed from the start. It does not create the registry object: that object carries the version of whichever API instance registers first and `registerGlobal` refuses a mismatched write, so eve decorates the author's own object when it arrives. Adoption stays as the fallback for a slot eve cannot claim. Also fixed: - Startup no longer depends on the authored sampler. The old probe started a real span and required its processor to see it, so an `always_off` or ratio sampler made `eve dev` boot probabilistically. eve now checks only for a context manager, using a span the API owns outright. - Spans are observed through a `Proxy` rather than by assigning over `span.end`, which threw on a frozen or accessor-backed span. A span whose `end` cannot be substituted at all is declined rather than crashed on. - `setup` may be `async` and is awaited before anything else looks for a tracer provider. It typechecked as `async` before but its promise was dropped, letting eve's own setup win the race and starve the authored exporter. - Observed tracers are no longer cached on an interpolated `name@version` key, which ignored `options.schemaUrl` and could collide. Signed-off-by: Chad Hietala <chadhietala@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Local dev tracing was gated on the absence of
agent/instrumentation.ts. Adding an exporter for Honeycomb or Datadog cost you.eve/traces/v1,eve trace ls, andeve trace <id>— the whole local inspection loop.This makes the two coexist in
eve dev.What changed
eve adopts the authored provider instead of competing with it. The global that
trace.setGlobalTracerProviderregisters is aProxyTracerProvider, so eve swaps its delegate for one that observes every tracer it hands out. The authored exporter keeps receiving everything it received before, and additionally sees eve'sagent.*spans, which it never got. eve spools the same spans to.eve/traces/v1.When no provider is registered — no authored file, or an authored
setup()that registers nothing — eve falls through toregisterOTelexactly as today.The proxy is matched structurally rather than with
instanceof: authoredinstrumentation.tsresolves@opentelemetry/apifrom the agent's own dependencies while eve uses its vendored copy, so the two hold different classes. Only theglobalThisregistry is shared.harness/adopt-global-tracer-provider.ts(new) — wraps the delegate's tracers and spans;startActiveSpanis reimplemented overstartSpanso span creation is always interceptable, and the shadowedspan.endis idempotent and runs the realendfirst so the author's own processors see a finished span.create-application-nitro.ts— the dev gate is gone. The local plugin isunshifted when there is no authored plugin (today's ordering, unchanged) andpushed after it when there is, so a provider exists to adopt.local-instrumentation-runtime.ts—adoptGlobalTracerProvider(processor)or elseregisterOTel. A failed registration probe now warns and installs nothing instead of throwing: a dev-only convenience should not take down a dev server whose authored instrumentation is otherwise fine.@opentelemetry/api.d.ts— the vendored declaration widens by the minimum:TracerProvider,ProxyTracerProvider,trace.getTracerProvider(),Span.isRecording?(),end(endTime?).tool-loop.tsalready composedintegrations: [bridgeIntegration, createOtelIntegration()]for the both-present case, so the turn-time path needed no change.AgentTraceSpanProcessoris duck-typed and already filters theworkflowinstrumentation scope, so local traces stay free of Workflow spans even though the adopted provider may carry auto-instrumentation.Scope
eve devonly. Production is untouched, and the authored public API (defineInstrumentation,setup()callingregisterOTel) does not change.EVE_TRACES=offremains the opt-out.Tests
adopt-global-tracer-provider.test.ts— spans reachonStart/onEnd; the innerendruns exactly once and beforeonEnd; sampled-out spans are skipped;startActiveSpanreturns the callback's value; one tracer pername@version; a non-proxy global declines.local-instrumentation-runtime-conflict.scenario.test.ts— inverted from asserting the throw. Registers via the agent's own@vercel/otelfirst, then asserts the authored processor still receivesagent.sessionand eve writes a segment under.eve/traces/v1/<traceId>.create-application-nitro.scenario.test.ts— dev plugin ordering: the local plugin follows the authored one when present.