Skip to content

fix(eve): classify input requests by framework-owned kind - #1319

Merged
ruiconti merged 1 commit into
rui/fix-session-limit-continuationfrom
rui/input-request-kind
Jul 29, 2026
Merged

fix(eve): classify input requests by framework-owned kind#1319
ruiconti merged 1 commit into
rui/fix-session-limit-continuationfrom
rui/input-request-kind

Conversation

@ruiconti

Copy link
Copy Markdown
Contributor

Input requests come from three producers — ask_question, AI SDK tool approvals, and the session-limit continuation gate — but consumers classified them by option shape, display hints, and tool names. Those heuristics drift: shape-sniffing misclassified the session-limit prompt as a tool approval, and the TUI rendered it through the y/n approval flow where its continue/stop options could not be answered.

What

  • Add a required InputRequest.kind discriminator (question / tool-approval / session-limit), stamped by each producer.
  • Classify, route, and render by kind across the harness, clients, and channels: classifyInputRequest becomes an exhaustive switch, the TUI renders non-approvals in the question pane (answering with the request's own option ids), and Slack/Teams HITL use the same predicate.
  • Carry kind through the invocation-facing contract (eve invoke landed on main building requests without it).

Breaking

kind is a required field, so the extension compatibility contracts bump: dynamicTool v5, hook v3, dynamicInstructions v2, dynamicSkill v2.

Stack

Based on #1262. #1273 (descendant Stop cancellation, which routes by kind) and #1312 (TUI regression coverage) layer on this.

@vercel

vercel Bot commented Jul 29, 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 Jul 29, 2026 8:55pm
eve-docs-4759 Ready Ready Preview, v0 Jul 29, 2026 8:55pm

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

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

Key takeaways

  • No notable deltas vs rui/fix-session-limit-continuation (1cfc900).

Delta vs rui/fix-session-limit-continuation (1cfc900)

Area Metric Baseline Current Delta
Package Packed tarball 7.62 MB 7.62 MB +239 B ⚠️
Package Unpacked publish size 28.78 MB 28.78 MB +1.4 kB ⚠️
Package Installed footprint 91.08 MB 91.08 MB +1.4 kB ⚠️
Package Published files 2865 2865 0
Package Installed files 6652 6652 0
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 16.75 MB 16.75 MB +616 B ⚠️
Runtime Public routes 11 11 0
Changed function payloads vs rui/fix-session-limit-continuation (1cfc900) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 8.37 MB 8.38 MB +308 B ⚠️ none
functions/.well-known/workflow/v1/flow.func changed 8.38 MB 8.38 MB +308 B ⚠️ none

eve init install

Metric Baseline Current Delta
Installed footprint 129.48 MB 129.48 MB +1.4 kB ⚠️
Installed packages 130 130 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 43.11 MB 43.11 MB +1.4 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-29T20:59:02.200Z
  • 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.13
  • Package directory: packages/eve
  • Tarball: 7.62 MB (eve-0.27.13.tgz)
  • Unpacked payload: 28.78 MB across 2865 published files
  • Installed footprint: 91.08 MB across 6652 installed files
  • Installed root package: 27.42 MB
  • Installed dependencies: 63.66 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.42 MB (30.1%)
  • @rolldown/binding-linux-x64-gnu: 19.28 MB (21.2%)
  • @rolldown/binding-wasm32-wasi: 10.66 MB (11.7%)
  • ai: 6.53 MB (7.2%)
  • @napi-rs/wasm-runtime: 6.39 MB (7.0%)
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.54 MB 43.6%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 27.42 MB 30.1%
🔴 @rolldown/binding-linux-x64-gnu [#################.......] 19.28 MB 21.2%
🔴 @rolldown/binding-wasm32-wasi   [#########...............] 10.66 MB 11.7%
🔴 ai                              [######..................] 6.53 MB 7.2%
🔴 @napi-rs/wasm-runtime           [######..................] 6.39 MB 7.0%
🔴 zod                             [####....................] 5.07 MB 5.6%
🔴 Other installed packages        [##############..........] 15.73 MB 17.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.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: 129.48 MB across 8520 installed files
  • Installed packages: 130 total (124 transitive-only)
  • dependencies: 4 direct packages totaling 43.11 MB
  • devDependencies: 2 direct packages totaling 5.04 MB
  • Other transitive package files: 81.33 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 (21.6%)
  • eve: 27.42 MB (21.2%)
  • @rolldown/binding-linux-x64-gnu: 19.28 MB (14.9%)
  • @rolldown/binding-wasm32-wasi: 10.66 MB (8.2%)
  • zod: 9.02 MB (7.0%)
Installed footprint breakdown
Installed package size
🔴 @typescript/typescript-linux-x64 [########################] 27.95 MB 21.6%
🔴 eve                              [########################] 27.42 MB 21.2%
🔴 @rolldown/binding-linux-x64-gnu  [#################.......] 19.28 MB 14.9%
🔴 @rolldown/binding-wasm32-wasi    [#########...............] 10.66 MB 8.2%
🔴 zod                              [########................] 9.02 MB 7.0%
🔴 ai                               [######..................] 6.53 MB 5.0%
🔴 @napi-rs/wasm-runtime            [#####...................] 6.39 MB 4.9%
🔴 Other installed packages         [###################.....] 22.23 MB 17.2%
dependencies (4)
Package Range Installed size Share
@vercel/connect 0.4.2 135.8 kB 0.1%
ai ^7.0.38 6.53 MB 5.0%
eve file:eve-0.27.13.tgz 27.42 MB 21.2%
zod 4.4.3 9.02 MB 7.0%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.54 MB 2.0%
typescript 7.0.2 2.50 MB 1.9%
Function Drill-Down

Payload Size Graph

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

Top Function Payloads

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

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                       [#######################.] 2.28 MB 27.2%
🟠 _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.38 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.38 MB
Function files 8.38 MB across 44 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 2.28 MB (27.2%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                       [########################] 2.28 MB 27.2%
🟠 _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.94 s -> 2.04 s (+109.2 ms) vs rui/fix-session-limit-continuation (1cfc900).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `rui/fix-session-limit-continuation (1cfc900)`
Phase Baseline Current Delta
extension.check 9.4 ms 8.5 ms -0.9 ms
project.resolve 1.5 ms 3.5 ms +2.0 ms
workspace.create 1.1 ms 1.3 ms +0.2 ms
host.prepare 173.6 ms 259.7 ms +86.1 ms
vercel.service-prefix.resolve 2.0 ms 2.2 ms +0.2 ms
nitro.create 197.2 ms 189.4 ms -7.8 ms
sandbox.prewarm 233.7 ms 237.8 ms +4.1 ms
nitro.cache.prepare 0.3 ms 0.2 ms -0.1 ms
nitro.prepare 0.8 ms 0.7 ms -0.1 ms
nitro.public-assets 0.8 ms 0.8 ms 0.0 ms
nitro.prerender 0.6 ms 0.5 ms -0.1 ms
nitro.bundle 1.28 s 1.31 s +25.8 ms
nitro.cache.write 0.4 ms 0.4 ms 0.0 ms
vercel.workflow-function.materialize 23.6 ms 23.8 ms +0.2 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.7 ms 3.3 ms -0.4 ms
workspace.remove 2.3 ms 2.2 ms -0.1 ms

Input requests come from three producers -- ask_question, AI SDK tool
approvals, and the session-limit continuation gate -- but consumers
classified them by option shape, display hints, and tool names. Those
heuristics drift: a prompt with its own options misclassified as an
approval, and the TUI rendered the session-limit prompt through the y/n
approval flow where its continue/stop options were unanswerable.

Add a required InputRequest.kind discriminator (question, tool-approval,
session-limit) stamped by each producer, and classify, route, and render
by it across the harness, clients, and channels. The invocation-facing
contract carries kind as well.

Extension compatibility contracts bump: dynamicTool v5, hook v3,
dynamicInstructions v2, dynamicSkill v2.

Signed-off-by: Rui Conti <ruiconti@gmail.com>
@ruiconti
ruiconti merged commit 98d17c7 into main Jul 29, 2026
381 of 476 checks passed
@ruiconti
ruiconti deleted the rui/input-request-kind branch July 29, 2026 21:50
ncosentino added a commit to ncosentino/eve-client that referenced this pull request Aug 1, 2026
Closes #25.

## Upstream change

[vercel/eve#1319](vercel/eve#1319) — `fix(eve):
classify input requests by framework-owned kind`, merged as
[`98d17c789bdc`](vercel/eve@98d17c7).

Verified directly against upstream rather than the radar summary:

- `packages/eve/src/runtime/input/types.ts` adds a **required** `kind`
to `inputRequestSchema`, typed as `z.enum(["question", "session-limit",
"tool-approval"])`.
- `packages/eve/src/client/message-action-parts.ts` and
`message-reducer-types.ts` carry it into the client-facing input request
so consumers route by the discriminator instead of shape-sniffing
options, display hints, or tool names.

First released in eve **0.28.0** — confirmed by unpacking the npm
tarballs: `0.27.13` has no `"session-limit"` literal, `0.28.0` does.

## Changes

- `EveInputRequestKind` models `Question`, `ToolApproval`,
`SessionLimit`, and `Unknown`.
- `EveInputRequest.Kind` projects the discriminator;
`EveInputRequest.RawKind` preserves the wire value.
- The two `Unknown` cases stay distinguishable: a newer eve sending an
unmodelled kind keeps its value in `RawKind`, while a server that
predates the discriminator reports `null`.
- A `kind` that is present but not a string throws
`EveProtocolException` rather than impersonating a legacy server —
consistent with how the parser already rejects a malformed `options`
value.
- `docs/attachments-and-input.md` and `docs/compatibility.md` document
routing and the two `Unknown` cases.

## Validation

| Gate | Result |
|---|---|
| `dotnet format --verify-no-changes` | clean |
| `dotnet build -c Release` | 0 warnings, 0 errors |
| `dotnet test -c Release` | **88 passed**, 0 failed, 0 skipped (79
pre-existing + 9 new) |
| `npm run test:client` (real eve `0.27.6` server) | passed |
| `mkdocs build --strict` | built |

New coverage: all three kinds; a `session-limit` request carrying a
`confirmation` hint, `continue`/`stop` options, and a tool name — the
exact shape the old heuristic misclassified; a `question` carrying
approve/deny options; an unmodelled future kind; an absent kind; a
non-string kind; multiple requests in one event keeping their own kinds;
and an assertion that the nested `action.kind` is never read as the
request discriminator.

The pinned eve `0.27.6` fixture gains an approval-gated tool
(`agent/tools/request_approval.ts` with `approval: always()`), and the
mock model emits a matching tool call. The compatibility probe therefore
drives a **real** `input.requested` pause, asserts the legacy projection
(`Kind == Unknown`, `RawKind == null`), then answers the approval and
verifies the turn resumes.

## Disclosed gaps

**HIGH — none.**

**MEDIUM**

- The compatibility baseline is intentionally **not** advanced.
`EveProtocol.ReferenceEveVersion` stays `0.27.6`, because the issue
requires all changes through the upstream release to land first, and eve
0.28.0 also carries the stream-event-id change tracked by #24. Advancing
the pinned fixture should be a separate PR once both are merged.
- Because the pinned fixture is `0.27.6`, discriminator **presence** is
verified only against synthetic payloads. Only the legacy-tolerance half
is verified against a real server.
- `session-limit` cannot be produced by the pinned fixture, so it is
covered by contract tests only.

**LOW**

- `EveInputRequestKind` is a plain enum. Adding a future kind is
additive and non-breaking, but a caller switching exhaustively today
will fall through to `Unknown`; `RawKind` is the documented escape
hatch.
- The fixture tool uses a plain JSON Schema `inputSchema` rather than
Zod, so no new fixture dependency and no lockfile change was needed.

Copilot-Session: 6f397bc8-d45e-4945-a1f7-eb8d8d91a4fc
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.

2 participants