Vercel AI SDK 7
AI SDK 7 (ai 7.0.x) code without v4–v6 APIs or invented exports, models and options, with owned streams, tools, approvals and telemetry, and package-manager-owned dependencies; any app shape, framework or runtime. Rule IDs BASE/CLI/MIG/ARCH/TOOL/OUT/RUN/UI/SEC/QA.
Set this profile
ccpp cpo profile set ai-sdk-7Inside Claude Code, prefix the command with ! to run it in the session. Downloading a profile needs a Builder or Team plan; listing them does not.
Policies
101 policies, grouped by what they guard.
Secrets & private data 6
Credentials, keys and personal data stay out of files, logs, commands and the conversation.
ai-sec01-public-credentialsSEC-01 · Provider and service keys never reach a browser bundle or the source: no public-prefixed key variables, no keys in client components, no literal apiKey
ai-sec08-logged-payloadsSEC-08 · Logs never dump raw request/response bodies, headers, credentials or whole generation results
ai-sec09-devtools-captureSEC-09 · DevTools captures (.devtools/) never enter version control
ai-sec09-devtoolsSEC-09 · AI SDK DevTools run only in local development: devToolsMiddleware/DevToolsTelemetry sit behind a development guard
ai-tool05-credentials-to-modelTOOL-05, SEC-01 · Credentials never become model-visible: no secret fields in a tool inputSchema, no secret environment values in prompts or instructions
Authentication & authorization 4
Who may do what, from roles, privileges and permissions to CSRF, CORS and verified tokens.
ai-sec03-sensitive-toolsSEC-03 · A call that gives the model destructive or sensitive local tools sets an explicit toolApproval policy
ai-sec04-approval-replaySEC-04 · Approvals replayed from client-submitted history are protected against forgery (approval signing or trusted server-side state)
ai-sec05-provider-tool-approvalSEC-05 · toolApproval is not relied on for provider-executed tools (webSearch, codeExecution, computer use…): the provider runs them
ai-tool02-identity-inputsTOOL-02 · Identity, tenancy and permission come from trusted context, not from fields of a tool's model-filled inputSchema
Untrusted input 3
Requests, downloads and tool output are validated before they reach SQL, a shell, eval or a deserializer.
ai-sec02-untrusted-instructionsSEC-02, MIG-12 · Request data never becomes privileged instructions: no request values in instructions/system, no system messages from submitted history
ai-sec12-unsandboxed-execSEC-12 · Tools never run commands or code chosen by the model outside a real sandbox (declared in trustedExecutionPaths)
ai-ui05-unvalidated-messagesUI-05 · UI messages parsed from a request or storage are validated (validateUIMessages/safeValidateUIMessages) before conversion when tools are in play
Network & TLS 2
Outbound data, verified certificates, destinations taken from requests and services exposed to others.
ai-sec10-custom-downloadSEC-10 · A custom experimental_download keeps the SDK's URL, redirect and credential-origin protections
ai-sec11-mcp-lifecycleSEC-11 · MCP clients are closed on completion, failure and cancellation, and keep the default redirect: 'error'
Weakened checks 2
Suppressions, disabled lint or CI steps and relaxed strictness need a reason or the user's approval.
ai-cli08-suppressionsCLI-08, QA-01 · AI SDK code gets no new @ts-ignore, @ts-nocheck or @ts-expect-error: type errors from an SDK mismatch are fixed, not muted
ai-qa06-exceptionsQA-06 · A project override that disables or weakens an ai-sdk-7 rule records its reason, owner and expiry (x-reason, x-owner, x-expires)
Type safety 3
No escapes from the type checker (any, unchecked casts, non-null assertions) and explicit contracts.
ai-arch05-type-escapesARCH-05 · SDK types are inferred from their definitions (tools, schemas, agents, UI messages), not re-declared or forced with any/double casts
ai-mig18-tool-contextMIG-18 · Tools that read context declare it with contextSchema instead of casting a shared context object
ai-mig23-chunk-narrowingMIG-23 · onChunk narrows chunk.type before reading variant fields: in v7 it also receives lifecycle, finish, error and abort parts
Error handling 6
Failures are propagated or handled, never swallowed or turned into fake success.
ai-arch08-fabricated-toolsARCH-08 · Production tools never return random demo values, placeholders or a swallowed failure dressed as success
ai-out02-partial-effectsOUT-02 · Irreversible effects wait for the completed, validated output; partial structured output only feeds previews
ai-out03-output-fallbacksOUT-03 · A missing or invalid structured output is handled, never replaced by an empty object or a cast passed off as success
ai-run03-stream-errorsRUN-03 · Streaming failures are handled where the stream is consumed (onError, error parts, iteration), not by a try/catch around streamText
ai-run07-retried-tool-effectsRUN-07 · A generation with tools is not replayed by an outer retry: its tool side effects would run again
ai-tool10-fabricated-resultsTOOL-10 · Pending tool calls are resolved by real outputs, errors or approvals, never by writing output-available states by hand
Async & concurrency 4
Owned tasks, awaited promises, preserved cancellation and no blocking on event loops.
ai-run02-tool-abortRUN-02 · Tool I/O receives the call's abort signal, so cancelling a generation also cancels its tools
ai-run04-abort-cleanupRUN-04 · Cleanup and persistence that must happen on cancellation run in onAbort (and onError), not only in onEnd, which an aborted stream never calls
ai-run05-unconsumed-streamsRUN-05, ARCH-06 · Every SDK promise and stream has an owner: awaited, returned, consumed or deliberately supervised, never dropped or hidden behind void
Performance & resource bounds 3
Timeouts, bounded retries and fan-out, reused clients, closed resources, no N+1 queries.
ai-run01-budgetsRUN-01 · With requireBudgets, generation calls state or inherit maxOutputTokens and a timeout or abort signal
ai-run01-timer-raceRUN-01 · Generation deadlines use the SDK timeout or an abort signal, not Promise.race against a timer that leaves the call running
ai-run06-outer-retriesRUN-06 · Retries use the SDK budgets (maxRetries before streaming, streamRetries after it starts), not an outer loop or retry helper around the whole call
Architecture & boundaries 5
Declared layers and dependency directions, no import cycles, small modules, explicit dependencies.
ai-arch01-mixed-responsibilitiesARCH-01 · One growing file does not mix transport, AI orchestration, inline tool execution and persistence
ai-arch02-import-cyclesARCH-02 · A new runtime import in AI SDK code does not close an import cycle (bounded walk of relative imports)
ai-arch04-pass-through-wrappersARCH-04 · No pass-through wrappers around SDK calls: a function that only forwards its arguments to generateText/streamText adds no behaviour
ai-base05-file-sizeBASE-05 · AI SDK source files do not grow past maxLines (existing debt is judged by its growth only; 0 turns it off)
ai-base05-function-sizeBASE-05 · Functions of AI SDK code (handlers, tools' execute, callbacks) stay under maxFunctionLines when they are added or grown
Language idioms 3
The conventions of the language that keep code predictable for its readers.
ai-cli07-manual-stream-protocolCLI-07 · Streams to clients use the SDK helpers (UI message / text stream responses), not hand-written SSE framing or raw provider HTTP calls
ai-tool06-manual-tool-loopTOOL-06 · Multi-step tool use relies on stopWhen/prepareStep or ToolLoopAgent, not a hand-written loop re-calling generation with tool results
ai-tool07-step-budgetTOOL-07, OUT-04 · generateText/streamText with tools state their step budget: their default is one step (ToolLoopAgent's is 20), too few for tools then an answer or output
HTTP & APIs 3
Request and response contracts, schemas, status codes, error bodies and published API surfaces.
ai-out01-manual-parsingOUT-01 · Structured results come from output: Output.object/array/choice, not JSON.parse or regexes over generated text
ai-out05-schema-portabilityOUT-05 · Tool and output schemas use constructs that convert to JSON Schema (no dates, functions, bigints, maps or transforms)
ai-tool03-tool-descriptionTOOL-03 · Every tool() states what it does and its limits in a description
Framework conventions 7
Routing, server and client boundaries, hooks and plugins the way the framework expects them.
ai-ui02-chat-optionsUI-02 · useChat is configured through its transport (DefaultChatTransport or a custom ChatTransport), not the removed api/body/headers/maxSteps/initialMessages options
ai-ui03-chat-helpersUI-03 · Code reads only what the installed useChat returns: no input, handleInputChange, handleSubmit, append, reload, isLoading or data helpers
ai-ui04-message-contentUI-04 · UI messages render their parts (text, files, tools, reasoning, data), not the removed content or toolInvocations fields
ai-ui06-original-messagesUI-06 · A UI message stream whose end callback persists the chat receives originalMessages, so message IDs and tool states stay stable
ai-ui07-static-transport-bodyUI-07 · Changing values (tokens, model, options) reach requests per call or through transport functions, not a static body or headers object
ai-ui08-tool-outputUI-08 · Client-side tool results go through addToolOutput with the tool name and call ID, never awaited inside onToolCall
ai-ui09-resume-stopUI-09 · A resumable chat (resume: true) cancels server work through an explicit, authorized endpoint; stop() alone only detaches the client
Versions & deprecated APIs 19
Code matches the installed version, without removed, renamed or deprecated APIs.
ai-base01-session-contextBASE-01/02/06/08 · At session start, Claude learns the resolved ai and @ai-sdk/* versions, whether these v7 rules apply, and where the version-matched docs and sources are
ai-base02-remote-docsBASE-02 · Fetching AI SDK docs from the web while the installed package ships its own version-matched docs points Claude to them
ai-base02-unknown-exportsBASE-02/06, MIG-01/02/03, UI-04, QA-02 · AI SDK imports name only exports and subpaths the installed package declares (no removed, invented or un-prefixed experimental names)
ai-base07-esmBASE-07 · AI SDK packages are consumed as ESM: no require() of ai or @ai-sdk/*, no SDK import in a CommonJS file
ai-base07-node-versionBASE-07 · Where the project declares a Node.js version (engines, .nvmrc, .node-version, Dockerfile, CI), it meets AI SDK 7's Node.js 22
ai-mig03-removed-optionsMIG-03/18 · Generation calls and agents pass no option the installed AI SDK removed (maxSteps, maxTokens, experimental_output, experimental_context…), local spreads included
ai-mig04-deprecated-importsMIG-01/04/05/08, UI-01, MIG-24 · New imports avoid deprecated AI SDK aliases (stepCountIs, Experimental_Agent, generateObject, Vue Chat, GoogleGenerativeAI*…)
ai-mig04-deprecated-optionsMIG-04/05/22, UI-01 · SDK calls use current option names (instructions, telemetry, include, onEnd, onStepEnd, onStart…), checked per owning API
ai-mig06-result-membersMIG-06/07/13/15/16 · Generation results are read through current members: stream, partialOutputStream, usage, finalStep, responseMessages and standalone response helpers
ai-mig09-unawaited-conversionMIG-09 · convertToModelMessages is awaited (or returned): its promise is never passed as the messages array
ai-mig10-prepare-step-carry-forwardMIG-10/11 · A prepareStep that overrides instructions or messages for some steps restores them for the others: v7 carries overrides forward
ai-mig14-accumulated-resultsMIG-14 · Loops with effects over toolCalls/toolResults/content/files read finalStep or steps, since top-level values now accumulate every step
ai-mig17-usage-fieldsMIG-17 · Token usage is read from the v7 fields (inputTokenDetails/outputTokenDetails), not the removed cachedInputTokens, reasoningTokens, promptTokens or Anthropic cacheCreationInputTokens
ai-mig19-needs-approvalMIG-19 · Approval moves from the deprecated tool-level needsApproval to call or agent toolApproval
ai-mig20-content-partsMIG-20 · Message and tool-result content uses current part shapes: file parts with mediaType, no removed media parts or mimeType
ai-mig20-legacy-partsMIG-20 · New content parts use the canonical file shape instead of the deprecated image part and image-*/file-* tool-output variants
ai-mig22-bodiesMIG-22 · Code that reads request or response bodies asks for them with include (bodies are excluded by default in v7)
ai-tool01-input-schemaTOOL-01 · Function tools declare inputSchema (not the v4 parameters), and tool calls/results are read as input/output, not args/result
ai-tool09-model-outputTOOL-09 · toModelOutput takes its options object ({ toolCallId, input, output }), and messages are converted with the same tools
Configuration 4
Settings read once at a boundary, validated, with units and without unsafe defaults.
ai-arch03-repeated-model-configARCH-03 · A model ID and its settings have one owner per use case, not a literal repeated across calls
ai-mig21-reasoning-overlapMIG-21 · A call sets portable reasoning or provider-specific reasoning options, deliberately, not both by accident
ai-run08-samplingRUN-08 · A call sets temperature or topP, not both, and does not treat temperature 0 as determinism
ai-run09-model-idsRUN-09, BASE-02 · Model IDs are ones the installed provider package declares (or the project allows), not retired or remembered ones
Logging & observability 2
Structured logs, bounded metric labels, no debug prints left in production code.
ai-sec06-telemetry-migrationSEC-06 · OpenTelemetry tracing in v7 goes through @ai-sdk/otel registered once; a telemetry flag or a tracer option alone collects no spans
ai-sec07-telemetry-captureSEC-07 · Registering telemetry decides what it records: inputs/outputs are captured by default, and allowlisted context fields carry no credential
Dependencies & toolchain 19
Packages change through the package manager, lockfiles stay consistent and the project's tools are used.
ai-base01-install-specsBASE-01, CLI-04 · Installs keep ai on this profile's major, never give @ai-sdk/* packages ai's major, and add no removed SDK package
ai-base01-manifest-rangesBASE-01, CLI-04 · package.json keeps ai on this profile's major and gives @ai-sdk/* packages their own majors
ai-cli01-init-over-projectCLI-01 · No package-manager initializer (npm/pnpm/yarn/bun init, npm create) runs in a directory that already has a package.json
ai-cli01-package-managerCLI-01 · Dependencies are installed with the project's package manager (packageManager field, lockfile)
ai-cli01-second-lockfileCLI-01/08 · No second lockfile next to another package manager's lockfile
ai-cli02-hand-edited-lockfileCLI-02 · Lockfiles are written by the package manager only (no hand edit, no script rewriting them)
ai-cli02-hand-written-manifestCLI-02 · A new package.json without dependencies is initialized with the package manager
ai-cli02-manual-dependency-editCLI-02 · Dependencies change through the package manager (add/remove/update), never by editing package.json by hand
ai-cli02-new-manifestCLI-02 · A new package.json comes from the package-manager initializer (or a generator), and gets its dependencies from the package manager
ai-cli02-package-manager-callRecords the tool calls that run a package manager (they may rewrite package.json and lockfiles; CLI-02/04, CLI-06)
ai-cli02-stale-lockfileCLI-02 · A turn that changes package.json dependencies also updates the lockfile next to it (once per stop)
ai-cli03-version-lookupsCLI-02 · Registry version lookups are not a step before installing
ai-cli03-version-pinsCLI-03 · Packages are installed by name: no guessed exact version, no @latest, no --save-exact without a reason
ai-cli04-resolved-versionCLI-04 · After an install naming ai or an @ai-sdk/* package, the resolved ai is still on this profile's major
ai-cli05-unused-integrationsCLI-05 · A turn adds only the AI SDK packages its code uses: no speculative UI adapter, provider, MCP, DevTools or telemetry install (once per stop)
ai-cli06-codemod-runCLI-06 · Records official AI SDK codemod runs, and asks for the diff to be reviewed afterwards (codemods do not cover every change)
ai-cli06-manual-migrationCLI-06 · Repetitive manual migration of names an official codemod renames points to the codemod (from the third file of the session)
ai-cli08-forced-peers-configCLI-08 · No configuration that forces peers or pins AI SDK packages behind the package manager's back (.npmrc legacy peers, overrides/resolutions)
ai-cli08-forced-resolutionCLI-08 · Dependency conflicts are fixed, not forced: no --force/--legacy-peer-deps installs, no lockfile deletion to make them pass
Tests 2
Tests assert behavior, stay deterministic and are not removed or skipped silently.
ai-qa02-test-mocksQA-02 · Tests use the installed ai/test mocks (V4 at this baseline) instead of older mock versions or module-mocking the SDK
ai-qa05-live-model-testsQA-05 · Automated tests do not call live, paid models: provider models and gateway IDs stay out of tests unless they are explicit integration tests
Completion evidence 4
A turn ends with its checks run and passing; claims of success need proof after the last edit.
ai-qa01-check-ledgerQA-01 · Records successful type-check, build, lint and test commands (the evidence the end-of-turn check reads)
ai-qa01-unchecked-turnQA-01 · A turn that changed AI SDK code runs the project's type-check, build or tests after the last change (once per stop)
ai-qa01-write-ledgerQA-01 · Counts the AI SDK code Claude changes in a turn (the end-of-turn check compares it with the last successful check)
ai-turn-baselineRecords the work tree when a prompt starts: the baseline of the AI SDK end-of-turn checks (CLI-02, CLI-05, QA-01)