Skip to content

feat(vercel-ai-sdk): rewrite for AI SDK v6 with full event coverage#1626

Open
MyPrototypeWhat wants to merge 8 commits into
ag-ui-protocol:mainfrom
MyPrototypeWhat:feat/vercel-ai-sdk-v6
Open

feat(vercel-ai-sdk): rewrite for AI SDK v6 with full event coverage#1626
MyPrototypeWhat wants to merge 8 commits into
ag-ui-protocol:mainfrom
MyPrototypeWhat:feat/vercel-ai-sdk-v6

Conversation

@MyPrototypeWhat
Copy link
Copy Markdown

Summary

Rewrites the Vercel AI SDK integration for AI SDK v6 with full AG-UI event coverage. Resolves #933.

This is an independent implementation, not based on #1167 (which has been waiting on review for a while). See #1167 for context.

What this PR adds vs the v4 version on main

  • Tool input streaming: tool-input-delta → incremental TOOL_CALL_ARGS events so clients can pre-fill UI as args arrive
  • Full text/reasoning lifecycle with consistent message ids derived from AI SDK part ids
  • Anthropic encrypted-signature forwarding via REASONING_ENCRYPTED_VALUE
  • Multi-step (stopWhen: stepCountIs(N)) with per-step assistant-message rotation; tool calls link back via parentMessageId
  • Defensive synthesis for non-streaming providers (bare tool-call → fabricated START/ARGS/END) and missing tool results (cleanup-phase synthesis)
  • RUN_ERROR is terminal for stream-internal error / abort parts (no misleading RUN_FINISHED after a failed run)
  • Defensive tool-call dedup in the assistant message
  • Replaced the hand-rolled JSON-Schema → Zod converter with AI SDK's jsonSchema() helper (full JSON Schema support — oneOf/anyOf/enum/pattern — for free)
  • Split the previous single-file implementation into tool-converter.ts / message-converter.ts / stream-handler.ts / vercel-ai-sdk.ts
  • 70 tests using MockLanguageModelV3 from ai/test covering text, reasoning, tool streaming, tool dedup, invalid tool-calls, multi-step, abort, error part, defensive close, and cleanup synthesis

Test plan

  • pnpm test in integrations/vercel-ai-sdk/typescript — 70 tests pass (~490ms)
  • pnpm typecheck — clean
  • Dojo agentic_chat scenario re-enabled and wired (apps/dojo/src/agents.ts, menu.ts, scripts/generate-content-json.ts)

Coordination

Notified @iamrajhans on #1167.

Upgrades the Vercel AI SDK integration from v4 to v6 and re-enables it in
the Dojo. This rewrite goes well beyond a pure version bump:

- Streams tool input deltas: maps `tool-input-delta` → incremental
  `TOOL_CALL_ARGS` events so clients can pre-fill UI before the model
  finishes speaking (the AG-UI killer feature for tool calls).
- Full text/reasoning lifecycle: emits `TEXT_MESSAGE_START/CONTENT/END`
  using AI SDK's part ids directly. Same for `REASONING_*`. Forwards
  Anthropic encrypted reasoning signatures via `REASONING_ENCRYPTED_VALUE`.
- Defensive synthesis for non-streaming providers: if a model emits a
  final `tool-call` without prior `tool-input-start`, the handler
  synthesizes the START/ARGS/END trio from the parsed input.
- Multi-step (`stopWhen: stepCountIs(N)`): each step gets a fresh
  `currentStepAssistantId` used for `parentMessageId` on tool calls.
  Lazy push avoids trailing empty assistant messages.
- Cleanup-phase synthesis: any tool call that finishes the run without a
  result gets a synthesized `TOOL_CALL_RESULT` so clients don't dangle.
- Proper error/abort semantics: stream-internal `error` parts emit
  `RUN_ERROR` but the stream continues; thrown errors emit `RUN_ERROR`
  then complete; `abort` parts close gracefully via `abortSignal`
  propagation through Observable teardown.
- Replaces the 80-line hand-rolled JSON-Schema → Zod converter with the
  built-in `jsonSchema()` helper from `ai`. Supports any JSON Schema
  including `oneOf`/`anyOf`/`enum`/`pattern`.
- Splits the previous single-file implementation into
  `tool-converter.ts`, `message-converter.ts`, `stream-handler.ts`, and
  `vercel-ai-sdk.ts` for readability and unit-testability.
- 70 tests across 8 files using `MockLanguageModelV3` from `ai/test`,
  covering text, reasoning, tool streaming, tool dedup, invalid
  tool-calls, multi-step, abort, error part, defensive close, and
  cleanup synthesis.

Resolves ag-ui-protocol#933.
- README Quick Start / With Tools: pass messages via `initialMessages`
  in constructor (RunAgentParameters does not accept `messages`).
- README step counter examples: first step is `step-1` (StreamHandler
  increments before emitting), not `step-0`.
- StreamHandler: log a console.warn for unrecognized AI SDK stream part
  types instead of silently skipping, surfacing future v6 part additions.
- VercelAISDKAgent: catch unforeseen StreamHandler errors and surface
  them via subscriber.error() instead of leaking as unhandled rejections.
… & abort

Previously, both the `error` and `abort` stream-part handlers fell through
to the cleanup phase and emitted MESSAGES_SNAPSHOT + RUN_FINISHED after
the run had already failed. AG-UI consumers treat RUN_FINISHED and
RUN_ERROR as mutually exclusive terminal events, so a consumer that tore
down state on RUN_ERROR was confused by the trailing RUN_FINISHED.

- `error` part: emit RUN_ERROR (code: stream_error_part) and complete().
- `abort` part: emit RUN_ERROR (code: aborted) and complete() instead of
  silently degrading into RUN_FINISHED. Mirrors the thrown-error path.
- Drop the now-unused `cancelled` flag — the for-await loop exits via
  `subscriber.closed` once `complete()` runs.
- Rewrite the abort test with a deferred promise instead of racing a
  200 ms / 50 ms setTimeout pair, removing CI flake potential.

The unsubscribe-driven abort path (the only real-world abort source in
this code) is unaffected: by the time the AI SDK emits the `abort` part,
the subscriber is already closed and the `emit()` guard swallows the
synthesized RUN_ERROR — which is exactly what the existing
`vercel-ai-sdk.test.ts` "propagates abort on unsubscribe" test asserts.

All 70 tests pass; tsc --noEmit clean.
… in unsubscribe test

- stream-handler.ts: `onToolCall` no longer appends to
  `assistantMessage.toolCalls` when an entry with the same id is already
  present. The downstream START/ARGS/END events were already deduped via
  `seenToolCalls`, but the toolCalls array push was unconditional, so a
  misbehaving provider that emitted the same `tool-call` twice would
  produce a malformed assistant message in MESSAGES_SNAPSHOT.

- vercel-ai-sdk.test.ts: rewrite "propagates abort on unsubscribe" with a
  deferred promise instead of a `setTimeout(200)` race + `setTimeout(1000)`
  fallback. Suite duration drops from ~1.36s to ~490ms; this single test
  goes from 1014ms to 21ms. Removes the last wall-clock-based timing
  assertion in the package.

70 tests still pass; tsc --noEmit clean.
@MyPrototypeWhat MyPrototypeWhat requested a review from a team as a code owner May 3, 2026 08:01
@vercel
Copy link
Copy Markdown

vercel Bot commented May 3, 2026

@MyPrototypeWhat is attempting to deploy a commit to the CopilotKit Team on Vercel.

A member of the Team first needs to authorize it.

@MyPrototypeWhat
Copy link
Copy Markdown
Author

Hi @NathanTarbert — picking this back up since #933 has been in Roadmap for a while. The Dojo wiring is included (apps/dojo/src/agents.ts + menu.ts), so this should close out the issue. Could you take a look or tag the right reviewer?

Happy to address feedback and to maintain the integration going forward, per the CONTRIBUTING.md note on community integrations. Also flagged the existing #1167 author as a courtesy.

@MyPrototypeWhat
Copy link
Copy Markdown
Author

Hi @contextablemark @tylerslaton — sorry to ping cold. This v6 rewrite (#933) has been open for ~2 weeks without a reviewer assigned. Could one of you take a look or route it to the right person?

Two things:

  1. Review — 70 tests pass, typecheck clean, Dojo wired.
  2. Vercel preview — failing with "Authorization required to deploy" since I'm an external contributor. A maintainer approval on the deploy would unblock the merge state.

Thanks!

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.

Add support for Vercel AI SDK

1 participant