migrating-vercel-ai-sdk-and-eve-to-pydantic-ai

Migrate TypeScript Vercel AI SDK or Eve applications to Python with Pydantic AI and, only when needed, Pydantic AI Harness. Use when source code imports `ai`, `@ai-sdk/*`, or `eve`, or relies on `generateText`, `streamText`, `ToolLoopAgent`, `useChat`, Eve agents, tools, skills, subagents, approvals, sessions, channels, schedules, or sandboxes.

Install
npx skills add 'https://github.com/pydantic/pydantic-ai/tree/main/pydantic_ai_slim/pydantic_ai/.agents/skills/migrating-vercel-ai-sdk-and-eve-to-pydantic-ai'
Download bundle ↓
main · 9e9fdc4Scanned 2026-09-17

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

references/RESEARCH-AND-MAPPING.md

references/RESEARCH-AND-MAPPING.mdBrowse 4 files
View on GitHub
← Back to SKILL.md

Research and concept mapping

Use this reference conditionally after tracing the source path. It is a decision guide, not a requirement to reproduce the entire Vercel AI SDK or Eve platform.

Primary documentation

Inspect installed versions before migrating because AI SDK, Eve, Pydantic AI, and Harness continue to evolve.

AI SDK and Eve are TypeScript while Pydantic AI is Python. Capture retained transport and storage boundaries with language-neutral fixtures and keep their field names, using Pydantic aliases where needed.

Gate on the installed AI SDK version

Read the matching v5, v6, or v7 migration guide before choosing fixtures. Important boundaries differ:

Source generationCheck before porting
Before v5Legacy message shapes and line-prefixed stream frames may require an application adapter rather than the current UI path.
v5UIMessage.parts, ModelMessage, stopWhen, transport-based useChat, and start/delta/end stream parts changed the client contract.
v6ToolLoopAgent, async convertToModelMessages, current output APIs, and explicit approval states replaced earlier names or lifecycles.
v7stepCountIs became isStepCount, needsApproval moved to per-call toolApproval, onFinish became onEnd, and usage/tool-call results aggregate across steps; Node and ESM requirements also changed.

Pydantic AI's VercelAIAdapter supports explicit SDK versions 5, 6, and 7. Its default is a compatibility choice, not evidence of the source version; configure it deliberately and test the emitted wire contract.

AI SDK Core and UI ownership map

Observed source behaviorTarget owner and likely seamFocused proof
generateText() / streamText() and text, steps, usage, or finish reasonCore: Agent.run() / run_stream() / run_stream_events(); Application: result adapterAssert caller-visible result, exact required trajectory fields, step count, usage, errors, and effects.
ToolLoopAgent, stopWhen, prepareStepCore: reusable Agent, UsageLimits, dynamic instructions and tool preparation; Application/Graph: explicit dynamic model or workflow policyExercise every observed stop condition and per-step mutation without assuming identical defaults.
@ai-sdk/workflow WorkflowAgentApplication/durable runtime: workflow state, persistence, approvals, and resume lifecycle; Core durable integration: agent model/tool operations inside a supported workflowInterrupt and restart at model, tool, approval, and effect boundaries; assert replay, state, correlation, and idempotency.
Local tool() with Zod or JSON schemaCore: typed functions, Tool, Tool.from_schema, function toolsetsAssert advertised schema, call/result IDs, error recovery, timeout, cancellation, approval, and effects.
Async-generator tool with preliminary resultsCore/Application: custom events plus final tool result when the client consumes intermediate states; otherwise an intentional changeAssert every consumed preliminary state, final output, order, cancellation, and behavior when the generator fails.
Provider-executed toolCore/provider: matching provider tool when available; otherwise Gap/ApplicationVerify who executes it, provider payloads, credentials, result shape, and fallback behavior.
Client-side tool with no server executorApplication/UI: retain browser execution; Core: deferred/external tool callProve the server does not execute it and the validated result resumes the correct call.
Dynamic MCP toolsCore: MCPToolset; Application: auth and lifecycleAssert discovery, schemas, name collisions, transport, credentials, errors, and version skew.
Output.object, array, choice, or jsonCore: Pydantic output type and explicit output mode when transport mattersAssert complete validation, invalid-output behavior, partial-stream expectations, and any extra step after tools.
Tool approval request/responseCore: requires_approval or ApprovalRequiredToolset; resolve inline with HandleDeferredToolCalls, or later with DeferredToolRequests and DeferredToolResults; Application: policy, auth, persistence, audit, UIExercise approve, deny, invalid/replayed decisions, call correlation, and exactly-once effects.
UIMessage, useChat, and ChatTransportApplication: retained TS/React client; Core UI adapter: VercelAIAdapterGolden-test request fields, validation, stream headers/chunks, tool states, errors, and final reconstruction for the installed SDK version.
Persisted UI messages and ModelMessage conversionApplication: UI-message store and trust policy; Core: normalized server-side historyContinue in a fresh process and prove client input cannot set trusted instructions, provider metadata, credentials, or ownership.
Resumable chat streamApplication: active-stream/message persistence and reconnect endpointDisconnect and reconnect; assert continuation, HTTP no-stream behavior, stable correlation, and no duplicate assistant message or effect.
onStepFinish, response onFinish, or v7 onEnd lifecycle callbacksCore/Application: hooks or event stream handling; the on_complete parameter of VercelAIAdapter.dispatch_request() or run_stream() for completed-run persistenceAssert firing point, per-step versus terminal behavior, errors, persisted messages, and exactly-once writes.
Provider string, provider instance, Gateway routing or fallbackCore/provider: model/provider configuration; Application: allow-list and policyExercise each configured route, fallback order, provider options, and failure shape.
AI SDK subagent implemented as a toolCore: agent-as-tool; Harness: SubAgents only for matching reusable delegation policyAssert fresh child context, input projection, result projection, usage/cancellation/error propagation, and approval limitation.
OpenTelemetry and provider metadataCore: instrumentation; optional Logfire; Application: trace and result adapterAssert trace correlation, privacy policy, required spans, usage, and retained dashboards.

Eve ownership map

Observed Eve behaviorTarget owner and likely seamFocused proof
instructions.md, agent.ts, and filesystem compilationCore: explicit Agent construction; Application: configuration loader only if runtime discovery is requiredConstruct every configured agent and assert instruction, model, tool, and environment selection.
tools/ with defineToolCore: typed tools/toolsets; Application: dependencies and protected servicesAssert schema, executor result, error/retry, approval, cancellation, and effects.
defineWorkflowTool and durable waitsApplication/durable runtime: workflow and wait lifecycle; Core durable integration: model/tool operations within a supported workflowKill and restart around the wait; assert correlation, validated resume data, replay, and idempotency.
skills/ with descriptions, load_skill, and materialized filesHarness: Skills for SKILL.md; Harness/Application: FileSystem or explicit tools for other filesAssert discovery, request-scoped loading, instruction injection, and access to every required reference, asset, or script.
Built-in or declared subagents/Harness: SubAgents for synchronous isolated delegation; Application/Gap: durable children, background results, and child streamsAssert child history/state isolation, dependency/tool sharing, handback, cancellation, errors, events, and restart.
defineState durable session stateApplication: separately typed and persisted stateAssert mutation, schema/version handling, fresh-process continuation, concurrency, and non-sharing with children.
Long-lived memoryHarness: Memory only for matching model-owned notebook semantics; otherwise Application: retained memory providerAssert lifetime, namespace, locking, attribution, bounded injection, and sharing rules independently from messages and state.
Session → turn → step durability and step replayApplication/durable runtime: session driver, replay unit, event log; optional Harness: StepPersistence only for its narrower documented contractInterrupt model, tool, and effect boundaries; assert which step re-runs, event identity, ordering, and exactly-once external effects.
Eve HTTP session API, NDJSON stream, event cursorApplication/Gap: compatibility endpoint and durable event storeGolden-test status codes, payloads, framing, cursor semantics, reconnect, retry, cancel, and terminal state. VercelAIAdapter does not implement Eve's protocol.
connections/, MCP/OpenAPI discovery, app/user OAuthCore: MCP/toolsets where compatible; Application: connection registry, OAuth, token persistence, tenant policyExercise discovery, qualification, auth parking/resume, refresh, revocation, isolation, and errors.
channels/ and schedules/Application/platform: channel adapters, scheduler, queues, and deploymentExercise trigger identity, authorization, deduplication, delivery, retry, cancellation, timezone, and failure behavior.
Sandbox adapters and /workspace boundaryHarness: a supported real sandbox when it matches; Application: existing sandbox and credential brokerRun containment, network, secret, filesystem, resource, timeout, and cleanup tests in the actual isolation boundary.
Evals and agent-run observabilityEvals: pydantic_evals; Core: instrumentation; Application: HTTP eval target, sampling, storage, and dashboardsRe-run the same dataset and essential metrics; assert trace/run correlation and retained privacy policy.
Workflow SDK backends, Vercel Sandbox, Cron, Connect, Blob, Gateway, Agent Runs, and deploymentApplication/platformVerify each retained or replacement service at its public boundary; do not claim Core or Harness equivalence.

Do not collapse distinct state

Keep these stores separate unless the source contract proves they are interchangeable:

  • UI messages restored by the frontend;
  • provider-facing normalized message history;
  • Eve per-session structured state;
  • long-lived memory across sessions;
  • durable step/session records and event cursors;
  • model-owned plans or Harness memory notebooks;
  • application identity, authorization, and tenant configuration.

The same fact appearing in two prompts does not prove equivalent ownership, lifetime, consistency, or restart behavior.

Referenced from SKILL.md