# Changelog - Page 2

New features, breaking changes, and fixes in eve, release by release.

## v0.81.0 {#0.81.0}



### Minor Changes

- Add `github.attribution(ctx)` to `eve/extensions/git` and the deprecated `code({ github })` config. When it returns a `{ name, email }` co-author, the `gh` tool ends every `gh-signed-commit` message and `gh pr create` body with that person's `Co-authored-by` trailer.

### Patch Changes

- An approval answer that is neither Approve nor Cancel now gets feedback instead of being dropped, and a repeated answer to an approval that was already decided is discarded before the requester check, so it no longer warns whoever's delivery carried it.
- Stop reading the parent session's event stream once the remote subagent stream route finds the child's `agent.started` binding. Opening a remote subagent stream no longer replays the rest of a long parent session on every request and retry.
- MCP connections close their remote session when the step that opened it ends, instead of leaking one session per step until the process exits. A step that ends while its connection is still connecting, or a sign-in that finishes after its step, can still leave one session open. HTTP MCP connections keep at most one inbound SSE stream per session: the stream opens only after the session exists, and reconnecting never opens a second one while a stream is attached, so servers that allow a single stream no longer answer `409`. Ending a session is bounded best effort: its `DELETE` gives up after 5 seconds, so a server that stops answering doesn't stall the step.
- The first answer to a tool approval now decides it. A repeated answer, for example from a double click, no longer leaves the session waiting when the tool has an approval response policy, and no longer overrides an earlier answer when it doesn't: Cancel followed by Approve stays cancelled. The note sent with the deciding answer, such as why it was cancelled, still reaches the model. An unauthenticated answer to a call that has a requester is rejected with feedback instead of settling it, so it can't pre-empt the requester's own answer. When the call has no requester, an unauthenticated answer is recorded as the anonymous principal that `none()` gives unauthenticated callers.
- Resolve MCP credentials before each request so live clients use refreshed tokens after expiry. Retry a rejected bearer once through the token provider before requesting sign-in, while preserving existing permission errors.
- Pressing a human-in-the-loop button whose session is no longer active, for example after its run was cancelled outside eve, now retires the prompt the same way on Slack, Teams, Telegram, Discord, and Chat SDK: its buttons are replaced with `No longer active`, as a resolved prompt reads, and the person who pressed is told to send a new message: privately on Slack, Discord, Chat SDK and Telegram, and on Teams by the retired card itself, or the reply to an invoke. Before, the press was only logged (or, on Chat SDK, thrown) and the prompt stayed live.
- A sign-in that fails with `retryable: false` now stops the turn from starting the same sign-in again. A later tool call in the same turn that needs the same grant for the same principal gets that failure back instead of a new `authorization.required`, and the next turn asks again. `authorization.required` and `authorization.completed` now carry `grant` and the connection principal's identity (no attributes), and a `failed` `authorization.completed` carries `retryable`. A failure without `retryable`, from an older eve, is treated as retryable.
- A call a sign-in stopped now waits in its step and runs itself once the sign-in calls back, instead of the model being asked again. `authorization.completed` is reported by that call's outcome, just before its `action.result`: `authorized` when the call returns, `failed` (with the error's `reason`, such as `access_denied`) when it throws. Steering a held turn fails the waiting call and declines its sign-in, and cancel stops it with the turn. A turn needing a sign-in now makes one model call fewer. A session already waiting on a sign-in when this ships keeps reporting `authorized` when its callback arrives.
- Connections or tools that share a `toolResultFrom` fallback identity, such as two MCP connections with the same URL and description, no longer log the "could not assign a unique toolResultFrom identity" warning at startup. eve now warns once, only when a `toolResultFrom` lookup actually needs that ambiguous fallback.
- Concurrent builds that need the same new Vercel sandbox template no longer fail with a 400 "sandbox with the name already exists" error. Each build now prepares its template in a private, non-persistent sandbox and records the finished snapshot under the shared template name only after the snapshot exists, so a build that fails, is killed, or times out never leaves half-prepared work where another build would reuse it.



## v0.80.1 {#0.80.1}



### Patch Changes

- Compaction now keeps the start and end of an oversized tool result instead of only its start, so failures, errors, and the `bash` exit code at the end of the output survive.
- Hosted builds now fail with a clear error when the build output imports a `build.externalDependencies` package, or a subpath of one, that Node's ESM resolver does not resolve to a file inside the output. Previously the build succeeded and the deployed function crashed at boot with `ERR_MODULE_NOT_FOUND` (for example when only a workspace package installed the dependency) or `ERR_PACKAGE_PATH_NOT_EXPORTED` (when the copied version does not export the imported subpath). The error names the import and the app `package.json` to add the package to.
- Publish framework-neutral tracing as `@vercel/agent-runs` with singular `createAgentRun` and `AgentRun` APIs; eve still bundles it without a new runtime dependency. Also fix a development-server build failure in npm-installed apps when generating source maps.
- Reject OpenAPI path parameter values equal to `.` or `..` before sending requests, so URL normalization cannot change the intended route. This validation also applies to application-provided arguments.



## v0.80.0 {#0.80.0}



### Minor Changes

- `git({ github })` accepts an optional `authorize` callback that runs once per `gh` tool invocation with the caller, declared repository, and repository-scoped token; returning `false` blocks the command. It gates caller/repository access, not individual API requests or operations, and allowed commands use the app token's permissions rather than the caller's GitHub permissions.
- Dropped traces and policies excluding either content direction now request Workflow data deletion when the run ends; set `experimental.workflow.retention: "default"` to retain completed transcripts independently of tracing. Expired session-history reads return `410 session_expired` before streaming, including when the World retains purged chunk records.

### Patch Changes

- Root sessions now accept empty model responses with `finishReason: "stop"` without retrying them or reporting a model-call failure. Recovery for delegated sessions, incomplete streams, and empty non-`stop` responses is unchanged.
- Scheduled sessions and their locally delegated tasks can now use dynamic scheduling tools and the schedule client to manage schedules, including conditional updates or disabling future occurrences. Collection scope authorization and tool approval policies still apply.
- eve now vendors chat 4.42.0 and requires the optional `chat` peer at `^4.42.0`. chat 4.41 broke Workflow DevKit workflows in host apps (vercel/chat#969).
- Dynamic schedule collections can defer their generated management tools to the catalog with `tool: "deferred"`, keeping them out of the model's initial tool list while still making them searchable and callable.
- Dynamic tools now capture locals bound by an array rest element (`const [first, ...rest] = ...`) or a rest parameter (`(...args) =>`). Before, the hoisted callback threw `ReferenceError` and the resolver's tools were dropped.
- Add experimental MCP connection event callback definitions and preserve the Connect runtime events bridge while keeping compiler metadata serializable.
- Add experimental Connect-managed event subscriptions and per-connection webhook receivers. Durable event handlers run independently of conversation sessions; only an explicit `attachSession(...).send(...)` enters a session. Each watch saves its binding before subscribing, and each delivery runs independently under that binding. Subscribe with `ttlMs` in milliseconds or `null` to watch until stopped; `expiresAt` is returned as the calculated deadline. Requires `@vercel/connect@2.5.2` or later.
  
  Return immediately from the durable sleep tool when steering has already interrupted its execution.
- Keep a session's deadline stable across workflow replay and compaction handoffs.
- `web_fetch` now converts HTML pages served without a `Content-Type` header instead of returning truncated raw source.



## v0.79.2 {#0.79.2}



### Patch Changes

- An agent or `serve` tool call with an empty `taskId` now starts a new task instead of failing with `UNKNOWN_TASK`. Some models send `""` for the optional `taskId` rather than omitting it.
- `eve start` no longer keeps the server's stdout and stderr in memory after startup. Output is still forwarded, and an unexpected exit no longer repeats the full log history in its error.
- Keep successful tool calls completed when their output includes `code` and `message` fields.
- `ctx.cancel()` in a `message.received` hook now cancels the turn when the message is a plain-text answer to a pending `ask_question` or `ctx.ask()` question. The question resolves as `cancelled` and the tool call never receives the text. Before, eve logged a warning and delivered the answer. `ctx.cancel()` in an `action.partial` hook for a workflow tool's report now cancels the turn waiting on that tool too.
- Attachments no longer fail a step when the session's sandbox cannot be resumed, for example when a follow-up lands on another replica. Earlier attachments and tool-result files in history reach the model as a "FileNotFound" note, and new inbound attachments and tool-returned files become a "could not be stored" note. Tools that use the sandbox still report the resume error.
- Fail fast with an actionable error when the project has an unsupported `microsandbox` version (such as 0.7), instead of every sandbox operation throwing `isInstalled is not a function`.
- Start built, managed eve agents when a local production Next.js server loads its configuration, so `next start` can serve eve routes.
- Keep every property name in `eve__search` tool signatures that run past the length cap. A long signature now drops its property descriptions before any property name, so the model no longer misses fields a large MCP tool such as Linear's `save_issue` supports.
- Compaction no longer re-caps a tool result it already capped. A capped result now fits the size limit it was measured against, so later compactions leave it as it is instead of nesting another truncation notice and keeping less of the original content. A summary written after a cap also sees the whole content the capped result kept.
- Teams group chats and channels no longer show connection sign-in links or confirmation codes in the shared thread. The card now has a **Sign in** button, and Teams shows the link only to the person who has to sign in, so another member can't connect their own account under the requester's identity.
- Snapshot retained tracing arguments and errors so later mutations cannot introduce private content into telemetry or checkpoints. Apply accepted delegation capture ceilings when re-entering durable turns, including through `resume()`.
- When a tool throws, the error on its `tool.call.failed` instrumentation event now keeps the thrown error's `name`, such as `QuotaError`, instead of always reading `Error`. The `action.result` stream event reports the same name as `error.name`.
- Parse a workflow tool's result as JSON when its run completes, the way a local tool's result already is. A tool that returns `ctx.ask()`'s answer directly, after the person picked an option, no longer fails the turn with `Cannot convert undefined or null to object`: undefined properties are omitted, a tool that returns nothing reports `null`, and the same applies to `ctx.reply()` in `serve` tools. A result JSON can't carry, such as a `Date` or `Map`, now fails the call with a serialization error instead of reaching the model as `{}`.



## v0.79.1 {#0.79.1}



### Patch Changes

- Approved `defineTool` calls can read who approved them: `ctx.approval.responder` is the approver and `ctx.approval.responder.getToken(provider)` resolves their token, while the call still runs as the requester.
- The Braintrust eval reporter no longer aborts the run when an eval produces no agent output. Those evals are now logged with an empty output.
- Allow `eve/client` to use an `AbortSignal` that does not implement `throwIfAborted`, including the signal provided by React Native.
- Sync dynamic skill files to the sandbox about 7× faster by writing them concurrently.
- Connection sign-in callback URLs no longer include `VERCEL_AUTOMATION_BYPASS_SECRET`, so the secret stays out of the links shown to users and the `redirect_uri` sent to providers. On a deployment behind Deployment Protection, the person signing in now passes protection on their own, for example through Vercel Authentication or a Deployment Protection Exception.
- Record `agent.input.messages.omitted` on model spans when the oldest prompt messages are dropped to fit the 32 KB content cap, so a long conversation no longer looks like it starts partway through.
- Reading a session stream whose history passed the World's retention now returns `410` with `code: "session_expired"` instead of a retryable `503` or `404`. The TypeScript client fails on the first response instead of retrying for about 38 seconds.
- Pass `followIdle: false` to `useEveAgent()` (React, Vue, and Svelte) or `EveAgentStore` to close the session stream while the session is idle instead of reconnecting it indefinitely. The stream reopens from its cursor on the next send, answer, or resume, and a prewarmed session opens no stream until its first message.
- Propagate configured trace context at each AI Gateway model request.
- Self-modification now rejects target branch names Git rejects: path components starting with `.` (such as `.hidden` or `feature/.hidden`) and names containing the DEL character.
- Let a message sent with `turnPolicy: "queue"` right after a tool approval or sign-in appears steer the held turn again. A message that arrived while the step raising the request was still finishing was treated as sent before the request, so it stayed queued behind a turn that could not end until the person acted.
- Honor explicit OpenTelemetry trace policies that enable inputs or outputs for DMs, private channels, and unknown audiences. Default capture remains audience-aware, and inherited capture limits and destination redaction still apply.
- Expose the live Vercel Sandbox name on `VercelSandboxSession` so tools can create Vercel git-credential-broker grants scoped to their session sandbox.
- Memory provider tools are now offered on a turn whose message carries a file attachment. Before, the agent lost its memory tools on exactly that turn.
- `eve build` now works for apps with mounted extensions on filesystems without hard-link support, such as some NFS and FUSE mounts. It no longer fails with `Unknown system error -524` while writing the authored module map.
- OpenAPI connections whose operation names collide at 64 characters now keep the suffixed tool names within the 64-character provider limit.
- Prewarm new Web Chat sessions when the user starts typing, so durable session startup overlaps with composing the first message.
- Keep a message sent with `turnPolicy: "queue"` before a tool approval or sign-in was requested in the queue, so it can no longer answer a prompt the person had not seen. Messages sent after the prompt still steer the held turn.
- Import skills with structured or non-string metadata without failing, treating metadata outside eve's modeled shape like other unmodeled frontmatter.
- Vercel sandbox creation now reads `VERCEL_TOKEN`, `VERCEL_TEAM_ID`/`VERCEL_ORG_ID`, and `VERCEL_PROJECT_ID` from the environment, like sandbox lookup and deletion already do. A CI runner without a linked project can now create sandboxes.
- Labeled assertions now report to Braintrust and Datadog under their label, so `t.score(x).label("grounding")` logs as `grounding` instead of `score [grounding]` or `score_grounding`. Display names in the console and run artifacts are unchanged, and labeled metrics start a new series under the bare label.
- Keep the answer a turn already wrote when it waits on tasks and resumes without new text, so `MessageResponse` results, `eve invoke`, and eval turns no longer report an empty message.
- Connections that share a host, such as Jira and Confluence on one Atlassian domain, no longer trigger the "could not assign a unique toolResultFrom identity" warning, and `toolResultFrom` now accepts OpenAPI connections, including ones without a `baseUrl`.
- `eve build` now reports why an extension mount failed to resolve, for example an extension that requires an unsupported tool contract or a package that isn't installed. Before, the build stopped with `Selected module binding "extensions/<name>.ts" has no compile or runtime usage.` and hid the cause.



[Previous](/changelog.md)

[Next](/changelog/page/3.md)