diff --git a/.agents/skills/ai-sdk/SKILL.md b/.agents/skills/ai-sdk/SKILL.md new file mode 100644 index 0000000..038ecd1 --- /dev/null +++ b/.agents/skills/ai-sdk/SKILL.md @@ -0,0 +1,78 @@ +--- +name: ai-sdk +description: 'Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLoopAgent, embed, or tools, (2) Want to build AI agents, chatbots, RAG systems, or text generation features, (3) Have questions about AI providers (OpenAI, Anthropic, Google, etc.), streaming, tool calling, structured output, or embeddings, (4) Use React hooks like useChat or useCompletion. Triggers on: "AI SDK", "Vercel AI SDK", "generateText", "streamText", "add AI to my app", "build an agent", "tool calling", "structured output", "useChat".' +--- + +## What the AI SDK Is + +The AI SDK by Vercel (the `ai` package on npm) is a TypeScript toolkit for building AI applications. It provides a unified API across model providers for text generation, structured output, tool calling, agents, embeddings, and framework UI integrations. + +- Repository: https://github.com/vercel/ai +- Documentation: https://ai-sdk.dev/docs + +## Critical: Do Not Trust Your Own Memory + +Whatever you remember about the AI SDK is likely outdated. The SDK changes frequently across versions - APIs are renamed, removed, and added. Your training data almost certainly contains obsolete APIs, deprecated patterns, and model IDs that no longer exist. UI hooks like `useChat` are among the most frequently changed APIs, so be especially careful with client code. + +**Never write AI SDK code from memory.** Always verify every API, option, and pattern against the documentation and source code for the version that is actually installed in the project. + +## Use the Bundled, Version-Matched Docs + +The `ai` package ships its full documentation and source code inside `node_modules`. These always match the installed version, so trust them over anything you remember. + +1. Ensure `ai` is installed. If `node_modules/ai/` does not exist, install **only** the `ai` package using the project's package manager (e.g. `pnpm add ai`). Install provider packages (e.g. `@ai-sdk/openai`) and framework packages (e.g. `@ai-sdk/react`) later, when the task requires them. +2. Read and grep the bundled docs at `node_modules/ai/docs/` and the source at `node_modules/ai/src/`. +3. Provider and framework packages bundle their own docs at `node_modules/@ai-sdk//docs/`. +4. If something isn't in the bundled docs, search https://ai-sdk.dev/docs. You can append `.md` to any docs page URL to get its markdown, and search via `https://ai-sdk.dev/api/search-docs?q=your_query`. +5. If you cannot find support for an answer in the docs or source, say so explicitly — do not guess. + +## AI Gateway: The Fastest Way to Start + +The Vercel AI Gateway is the fastest way to get started with the AI SDK. It provides access to models from OpenAI, Anthropic, Google, and other providers through a single API, without installing provider packages or managing multiple API keys. + +To set it up: + +1. Authenticate with OIDC (for Vercel deployments) or get an AI Gateway API key. +2. Provide it to your app via the `AI_GATEWAY_API_KEY` environment variable. +3. Reference models with `provider/model` strings. + +For exact setup, authentication, and usage, read the bundled guide and the AI Gateway docs. + +### Choosing a Model + +Never use model IDs from memory — models are released and retired frequently. Fetch the current list before writing code that references a model. Do not truncate the list (e.g. with `head`) so you can find the newest models: + +```bash +# All available models +curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '.data[].id' + +# Filter by provider (e.g. anthropic, openai, google) +curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '[.data[] | select(.id | startswith("anthropic/")) | .id] | reverse | .[]' +``` + +When multiple versions of a model exist, prefer the one with the highest version number. + +## Building and Consuming Agents + +Use the SDK's built-in agent abstraction (such as `ToolLoopAgent`) rather than hand-rolling tool-calling loops. For end-to-end type safety, infer the UI message type from your agent definition when consuming it on the client (e.g. with `useChat`). Consuming an agent is framework-specific: check `package.json` to detect the stack, then follow the matching quickstart. + +Look up the current agent, tool, and type-safety APIs in the bundled docs (`node_modules/ai/docs/`, especially the agents section) or at https://ai-sdk.dev/docs. + +## DevTools + +AI SDK DevTools captures your AI SDK calls - requests, responses, tool calls, token usage, and multi-step runs - so you can inspect exactly what your agents do. Use it while developing to debug generations. It is a separate package and is intended for local development only. + +For setup instructions, read the bundled DevTools documentation. + +## Keep the SDK Current + +Outdated installs are the most common source of errors. Compare the installed version against the latest: + +- **Installed:** the `version` field in `node_modules/ai/package.json`. +- **Latest:** run `npm view ai version`. + +If the installed version is a major version (or more) behind the latest, tell the user they are on an old release, and recommend upgrading before continuing. Migration guides are at https://ai-sdk.dev/docs/migration-guides. + +## After Making Changes + +Run the project's type checker. Be minimal — only set options that differ from the defaults, checking docs or source for the defaults rather than over-specifying. Most type errors come from remembered, now-changed APIs; re-check the current docs and source when they occur. diff --git a/.agents/skills/migrate-ai-sdk-v6-to-v7/SKILL.md b/.agents/skills/migrate-ai-sdk-v6-to-v7/SKILL.md new file mode 100644 index 0000000..0c10efe --- /dev/null +++ b/.agents/skills/migrate-ai-sdk-v6-to-v7/SKILL.md @@ -0,0 +1,108 @@ +--- +name: migrate-ai-sdk-v6-to-v7 +description: Migrate applications from AI SDK 6.x to AI SDK 7.0. Use when upgrading Vercel AI SDK packages, fixing v7 migration errors, or when the user mentions AI SDK v6, v7, upgrade, migration, breaking changes, system to instructions, fullStream, telemetry, tool context, or finalStep. +--- + +## AI SDK 6 to 7 Migration + +Use `content/docs/08-migration-guides/23-migration-guide-7-0.mdx` from the AI SDK repo as the source of truth. This skill is the working checklist; read the guide for exact examples or when behavior is unclear. + +## Migration Workflow + +1. Ensure the user has a clean backup or committed baseline before editing. +2. Inspect `package.json` and lockfiles to identify installed `ai`, `@ai-sdk/*`, provider, UI, MCP, and telemetry packages. +3. Upgrade AI SDK packages to latest versions, and add `@ai-sdk/otel` only if the project uses OpenTelemetry spans. +4. Update runtime and module assumptions: Node.js must be `>=22`, and AI SDK packages are ESM-only. Replace `require()` imports with ESM imports and add `"type": "module"` or use `.mjs` where needed. +5. Search for the v6 patterns below, migrate only the code that exists, then run typecheck and targeted tests. + +Prefer behavior-preserving changes. When v7 changes semantics, decide whether the app wants the new all-steps behavior or the previous final-step-only behavior. + +## Core API Changes + +- `experimental_customProvider` -> `customProvider`. +- `experimental_generateImage` -> `generateImage`; `Experimental_GenerateImageResult` -> `GenerateImageResult`. +- `experimental_transcribe` -> `transcribe`; `Experimental_TranscriptionResult` -> `TranscriptionResult`. +- `experimental_generateSpeech` -> `generateSpeech`; `Experimental_SpeechResult` -> `SpeechResult`. +- `experimental_output` option/result -> `output` option/result. +- `CallSettings` -> `LanguageModelCallOptions & Omit`; `prepareCallSettings` -> `prepareLanguageModelCallOptions`. +- `stepCountIs` -> `isStepCount`. + +## Prompts and Steps + +- Rename top-level `system` to `instructions` for `generateText`, `streamText`, `generateObject`, `streamObject`, and `streamUI`. +- Move `{ role: 'system' }` messages from `prompt` or `messages` into top-level `instructions`. Only use `allowSystemInMessages: true` for trusted persisted messages. +- Rename `experimental_prepareStep` to `prepareStep`. +- In `prepareStep`, rename returned `system` to `instructions`. +- In `experimental_repairToolCall`, use `{ instructions }` instead of `{ system }`. +- Audit `prepareStep` behavior: returned `instructions` and `messages` now carry forward into later steps. If code depended on one-step-only overrides, rebuild from `initialInstructions`, `initialMessages`, and `responseMessages` explicitly. + +## Lifecycle Callbacks + +- `experimental_onStart` -> `onStart`. +- `experimental_onStepStart` -> `onStepStart`. +- `onFinish` -> `onEnd`. +- `onStepFinish` -> `onStepEnd`. +- For `embed`, `embedMany`, and `rerank`, `experimental_onFinish` -> `onEnd`. +- Callback event fields use `instructions` instead of `system`. + +## Usage, Telemetry, and Include Options + +- `usage.cachedInputTokens` -> `usage.inputTokenDetails.cacheReadTokens`. +- `usage.reasoningTokens` -> `usage.outputTokenDetails.reasoningTokens`. +- OpenTelemetry moved out of `ai`; install `@ai-sdk/otel` and call `registerTelemetry(new OpenTelemetry(...))` at app startup. +- Telemetry is enabled by default once an integration is registered. Remove redundant `isEnabled: true`; use `isEnabled: false` to opt out per call. +- Move `experimental_telemetry.tracer` into the `OpenTelemetry` constructor. +- `experimental_telemetry` -> `telemetry`. +- Telemetry integration callbacks: `onRerankFinish` -> `onRerankEnd`, `onEmbedFinish` -> `onEmbedEnd`. Update tracing-channel subscribers for the same event type names. +- `experimental_include` -> `include`. +- `includeRawChunks` -> `include.rawChunks`. +- Request and response bodies are excluded by default. If code reads `request.body` or `response.body`, opt in with `include.requestBody` and, for `generateText`, `include.responseBody`. + +## Streaming, Messages, and Tools + +- `StreamTextResult.fullStream` -> `stream`. +- `streamText` `onChunk` now receives all stream parts, including lifecycle, boundary, finish, abort, and error parts. Guard by `chunk.type` before assuming text/tool/raw content. +- `step.response.messages` is no longer accumulated across previous steps. Use `result.responseMessages` for the full response message history, or flatten `result.steps`. +- Tool execution callbacks: `experimental_onToolCallStart` -> `onToolExecutionStart`, `experimental_onToolCallFinish` -> `onToolExecutionEnd`. +- Tool callback `experimental_context` -> `context`. +- Split shared runtime data from tool-specific data: use top-level `runtimeContext` for orchestration state, declare per-tool `contextSchema`, and pass per-tool values through `toolsContext`. +- Move `needsApproval` from `tool()` / `dynamicTool()` into per-call or agent `toolApproval`. +- `experimental_activeTools` -> `activeTools`. +- `ToolCallOptions` -> `ToolExecutionOptions`. +- `isToolOrDynamicToolUIPart` -> `isToolUIPart`. + +## Content Parts and Reasoning + +- Tool result `{ type: 'media' }` is removed; use `{ type: 'file-data' }`. +- Migrate `toModelOutput` `image-*`, `file-*`, `file-id`, and `image-file-id` variants to canonical `{ type: 'file', mediaType, data: { type: 'data' | 'url' | 'reference', ... } }`. +- User message `{ type: 'image', image, mediaType? }` is deprecated; use `{ type: 'file', mediaType: 'image' | 'image/*', data }`. +- Add support for the new `reasoning-file` content type in exhaustive switches, renderers, serializers, and validators. +- When adopting top-level `reasoning`, remove overlapping provider-specific reasoning settings from `providerOptions` unless provider-specific settings intentionally take precedence. + +## Multi-Step Result Shape + +- `result.usage` now includes all steps; `result.totalUsage` is deprecated. Use `result.finalStep.usage` for final-step-only usage. +- Top-level `content`, `toolCalls`, `staticToolCalls`, `dynamicToolCalls`, `toolResults`, `staticToolResults`, `dynamicToolResults`, `files`, `sources`, and `warnings` now include all steps. Use `finalStep` for previous final-step-only behavior. +- Top-level `reasoning`, `reasoningText`, `request`, `response`, and `providerMetadata` are deprecated for final-step data. Use `result.finalStep.*`; for `streamText`, await `result.finalStep`. +- Apply the same result-shape rules to `onEnd` events. + +## Stream Response Helpers + +The `streamText` result helper methods are deprecated. Replace result methods with top-level stateless helpers: + +- `result.toUIMessageStream(...)` -> `toUIMessageStream({ stream: result.stream, ... })`. +- `result.toUIMessageStreamResponse(...)` -> `toUIMessageStream(...)` plus `createUIMessageStreamResponse({ stream })`. +- `result.pipeUIMessageStreamToResponse(response, ...)` -> `toUIMessageStream(...)` plus `pipeUIMessageStreamToResponse({ response, stream })`. +- `result.toTextStreamResponse()` -> `toTextStream({ stream: result.stream })` plus `createTextStreamResponse({ stream })`. +- `result.pipeTextStreamToResponse(response)` -> `toTextStream({ stream: result.stream })` plus `pipeTextStreamToResponse({ response, stream })`. + +## Package-Specific Checks + +- MCP: `MCPTransportConfig.redirect` now defaults to `'error'`. Only set `redirect: 'follow'` for trusted MCP servers that rely on redirects. +- Vue: `@ai-sdk/vue` `Chat` class is deprecated. Prefer `useChat`, including getter/ref init for reactive chat inputs. +- Anthropic and `@ai-sdk/google-vertex/anthropic`: `providerMetadata.anthropic.cacheCreationInputTokens` was removed. Use `usage.inputTokenDetails.cacheWriteTokens`; raw Anthropic usage remains at `finalStep.providerMetadata?.anthropic?.usage`. +- Google: rename `GoogleGenerativeAI*` types, classes, and functions to `Google*`, e.g. `createGoogleGenerativeAI` -> `createGoogle`. The `google` entry point is unchanged. + +## Validation + +Run the project typecheck after edits, then the smallest relevant test suite. Also smoke-test streaming, chat UI, tool execution, telemetry, and multi-step flows if the migration touched them. If type errors remain, search the migration guide for the exact removed or renamed symbol before inventing a workaround. diff --git a/.agents/skills/migrate-radix-to-base/SKILL.md b/.agents/skills/migrate-radix-to-base/SKILL.md new file mode 100644 index 0000000..5eb5dc5 --- /dev/null +++ b/.agents/skills/migrate-radix-to-base/SKILL.md @@ -0,0 +1,173 @@ +--- +name: migrate-radix-to-base +description: Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert radix primitives, or switch a shadcn project's base library. Handles single components ("migrate accordion") and whole projects. +--- + +# Radix UI -> Base UI migration + +You migrate shadcn wrappers, hand-rolled radix compositions, and their +consumers to `@base-ui/react`, keeping the project buildable at every step. +Be precise; never guess a mapping. When a prop or part is not in these +reference files, check `node_modules/@base-ui/react/**/*.d.ts` before +transforming, and record gaps in the report. + +## Preflight (always) + +1. `npx shadcn@latest info --json` (or the project's runner): gives the + current base, STYLE (e.g. `radix-lyra`), tailwind version, aliases, + installed components, and package manager. Trust it over inference. +2. Detect the package manager (packageManager field / lockfile: + pnpm-lock.yaml, bun.lock, yarn.lock, package-lock.json) and use IT for + every install. Never leave a stale lockfile. +3. Require a clean git tree; work on a branch; one commit per component. +4. Baseline check BEFORE touching dependencies: run the project's + typecheck/build so pre-existing failures are never attributed to you. +5. Install `@base-ui/react` alongside radix. Radix packages are removed only + after the LAST component is migrated (both coexist fine). + +## Strategy: golden pair first, transformation engine second + +- **Golden pair via the CLI (preferred).** If the project is shadcn with a + known style (`radix-