fix(eve): project execution-denied tool results to provider-safe outputs at the model-call boundary - #1764
Conversation
…uts at the model-call boundary When a HITL tool approval is denied, eve persists an execution-denied tool-result marker into the session transcript. On the next turn the marker was replayed to the AI SDK provider adapter unrecognised, and OpenAI 400s the request (Missing required parameter: input[N].output), permanently wedging the session. Down-project the marker to a provider-safe error-text output on the model-call boundary only. Persisted history and action.result projection keep the authoritative execution-denied shape for UI and telemetry. Fixes vercel#1658 Signed-off-by: Sarthak Singh <sarthaksingh126@gmail.com> Signed-off-by: iroiro147 <sarthak.singh@mastersunion.org>
|
@iroiro147 is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
|
Note on the failures (≈44 jobs): these are the known fork-secret gap, not a regression from this change. GitHub strips repository/org secrets from runs whose head is a fork, so This matches the known blocker class tracked on eve#1725 / eve#1754 (test-tui fork-gap). Local gates before opening:
If a maintainer re-runs this on a branch with secrets available it should go green; otherwise the e2e-vercel failures are expected on fork PRs until the workflow is adjusted to skip them when secrets are absent. |
Absolutely this is only for maintainers |
Summary
Fixes #1658.
When a HITL tool approval is denied, eve persists an
execution-deniedtool-result marker into the session transcript so the UI can render the denial and theaction.resultprojection stays authoritative. On the next turn, that marker was replayed to the AI SDK provider adapter unrecognised, and OpenAI 400s the request:… permanently wedging the session — every subsequent turn replays the same marker and fails the same way.
Fix
Down-project the marker to a provider-safe
error-textoutput on the model-call boundary only (newmaterializeExecutionDeniedToolResultsForModel(messages)inharness/model-call-messages.ts, wired intotool-loop.tsjust before the agent call). Persisted history and theaction.resultprojection keep the authoritativeexecution-deniedshape with the original reason — the wire is translated, not the record.Tests
model-call-messages.test.ts: 6 unit tests covering rewrite ofexecution-denied, reason embedding, pass-through by reference when nothing matches, and non-interference with other tool-result output shapes.tool-loop.test.ts: the model now observeserror-textfor a denied approval while persisted parts keepexecution-denied.Local gates
pnpm --filter eve exec vitest run --config vitest.unit.config.ts src/harness/...→ all passtsc --noEmit→ clean (afterpnpm --filter eve build:compiledfor#compiled/*imports)oxlint --fix <files>→ cleanoxfmt <files>→ cleanpnpm guard:invariants→ okCI status note
e2e-verceljobs fail on fork PRs becauseVERCEL_TOKEN/VERCEL_ORG_ID/VERCEL_PROJECT_IDsecrets are not exposed to fork runs — the fixture-deploy step exits withNo existing credentials found. That matches the known fork-secret gap class (see also eve#1725 discussion). All other gates (local e2e, integration, scenario, tui, CI, bundle) pass.