Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b37eb47
Upgrade core library to AI SDK 6.0
zboyles Dec 24, 2025
72bc221
Upgrade example, playground and docs to AI SDK 6.0
zboyles Dec 24, 2025
cedf410
Add changelog entry for version 0.6.0
zboyles Jan 15, 2026
e217d68
Bump version from 0.3.2 to 0.6.0
zboyles Jan 15, 2026
0ed833c
Initial plan
Copilot Jan 15, 2026
8297be0
Document version jump strategy in CHANGELOG
Copilot Jan 15, 2026
de7ae78
Add comprehensive v6 migration details and link to migration guide
Copilot Jan 15, 2026
a4d598e
Merge pull request #2 from zboyles/copilot/sub-pr-1
zboyles Jan 15, 2026
3688fcb
Initial plan
Copilot Jan 15, 2026
557a151
Remove @openrouter/ai-sdk-provider dependency and references
Copilot Jan 15, 2026
46e8e83
Update AI SDK types from v2 to v3
Copilot Jan 15, 2026
22b267b
Merge pull request #3 from zboyles/copilot/sub-pr-1
zboyles Jan 15, 2026
e8495fe
Merge pull request #1 from zboyles/upgrade-ai-sdk-v6-pkg-pr-new
zboyles Jan 15, 2026
bc629a8
Initial plan
Copilot Jan 15, 2026
ce4287f
Update AI SDK packages to latest versions and fix type compatibility
Copilot Jan 15, 2026
e43c4b9
Mark textEmbeddingModel as deprecated and add embeddingModel as the p…
Copilot Jan 15, 2026
54ebbb7
Merge pull request #4 from zboyles/copilot/update-ai-sdk-packages
zboyles Jan 15, 2026
1752b7e
Fix tools not reporting proper errors (output-error state)
sethconvex Jan 16, 2026
10154dc
Initial plan
Copilot Jan 16, 2026
ef817ee
Merge upstream PR #211: Fix streaming tool calls being overwritten at…
Copilot Jan 16, 2026
10a7875
Merge upstream PR #212: Preserve isError flag for tool error reportin…
Copilot Jan 16, 2026
924f8e3
Merge upstream PR #213: Add userId field to UIMessage type
Copilot Jan 16, 2026
fd76ccf
Fix merge conflicts and restore async fromUIMessages for AI SDK v6 co…
Copilot Jan 16, 2026
e03ecf6
Improve readability of providerOptions type casting
Copilot Jan 16, 2026
9e19fe7
Merge pull request #5 from zboyles/copilot/merge-upstream-prs-211-212…
zboyles Jan 16, 2026
b45fd52
Enhance createTool function to match AI SDK v6 additional properties …
zboyles Jan 17, 2026
676d067
Relaxed ToolInputProperties type definition
zboyles Jan 17, 2026
b6acbf3
Refine createTool function documentation and type definitions
zboyles Jan 17, 2026
b1624a9
Refactor validators to introduce new tool approval request and respon…
zboyles Jan 17, 2026
b1e0df9
Implement tool approval request and response handling in mapping and …
zboyles Jan 17, 2026
a9c4598
Add providerExecuted flag to tool approval response validator and map…
zboyles Jan 17, 2026
9376e9b
Initial plan
Copilot Jan 17, 2026
19692bf
Update mimeType to mediaType with backwards compatibility
Copilot Jan 17, 2026
dcdd9ea
Fix test to expect mediaType instead of mimeType
Copilot Jan 17, 2026
d051529
Update generated component types to use mediaType instead of mimeType
Copilot Jan 17, 2026
392152f
Initial plan
Copilot Jan 17, 2026
1e3f63c
Fix tool-call input field and add execution-denied output type
Copilot Jan 17, 2026
7d85495
Remove backup file
Copilot Jan 17, 2026
3ee5263
Add tool-call input field, execution-denied type, and extended conten…
Copilot Jan 17, 2026
2987530
Add summary document for type error fixes
Copilot Jan 17, 2026
1e7c351
Fix type errors due to experimental_content vs output field mismatch …
zboyles Jan 18, 2026
219f520
Refactor test cases to replace 'args' with 'input' in tool-call defin…
zboyles Jan 18, 2026
0a1bcb5
Use union type for tool-call to support both input and args formats
Copilot Jan 18, 2026
ca35f10
Fix AI SDK v6 type errors: tool-call input/args union type and tool-r…
Copilot Jan 18, 2026
34df29b
Added `input` values to the test types, kept `args`
zboyles Jan 18, 2026
fcacdb7
Merge pull request #8 from zboyles/copilot/review-type-errors-update-…
zboyles Jan 18, 2026
37e0e75
Merge pull request #7 from zboyles/copilot/sub-pr-6
zboyles Jan 18, 2026
06358df
Add support for tool approval workflow in deltas and UI messages
zboyles Jan 18, 2026
d0a161c
Updated `serializeContent` to include cases for `tool-approval-reques…
zboyles Jan 18, 2026
c9c54cd
Refactor to ensure the tool call IS present when the SDK runs `collec…
zboyles Jan 19, 2026
47c4780
Refactor GetEmbedding type to support optional embeddingModel and imp…
zboyles Jan 19, 2026
c1abfc3
Fix streaming error after tool approval by suppressing orphaned tool-…
zboyles Jan 19, 2026
f07fdd5
Silently suppress tool invocation errors in continuation stream after…
zboyles Jan 19, 2026
3875c45
Merge pull request #6 from zboyles/zboyles/ai-sdk-v6/add-tool-approval
zboyles Jan 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## 0.6.0

**Note on versioning:** This release jumps from 0.3.2 to 0.6.0, skipping versions 0.4.0 and 0.5.0. This is intentional and aligns the `@convex-dev/agent` package version with the AI SDK v6 major version for clearer compatibility signaling. Going forward, the minor version of this package will track the AI SDK major version to make it easier for developers to identify which version of the AI SDK is supported.

- Breaking: Requires AI SDK v6 and drops support for AI SDK v5. Projects pinned
to v5 must upgrade their AI SDK dependencies before updating to this
version.
- Aligns this package's message and tool invocation types with the AI SDK v6
APIs to reduce casting/adapter code when integrating with the core SDK.
- Updates internal helpers to use the AI SDK v6 request/response shapes and
error handling semantics.
- Migration from 0.3.x:
- Update your AI SDK dependency to v6 in `package.json` and reinstall
dependencies.
- Rebuild and run your type checker to surface any call sites that depend on
the old AI SDK v5 types or message shapes.
- Review any custom integrations that relied on deprecated v5-only helpers
and update them to the new AI SDK v6-compatible APIs.
- See Vercel's [v6 migration guide](https://ai-sdk.dev/docs/migration-guides/migration-guide-6-0) for details on AI SDK changes.

## 0.3.2

- Fix deleteByOrder spanning many messages
Expand Down Expand Up @@ -306,8 +326,7 @@ data at rest is backwards compatible.
- Adds a `rawRequestResponseHandler` argument to the Agent that is a good spot
to log or save all raw request/responses if you're trying to debug model
behavior, headers, etc.
- Centralizes the example model usage so you can swap openai for openrouter /
grok in one place.
- Centralizes the example model usage so you can swap models in one place.
- StorageOptions now takes a better argument name
`saveMessages?: "all" | "none" | "promptAndOutput";`, deprecating
`save{All,Any}InputMessages` and `saveOutputMessages`.
Expand Down
63 changes: 63 additions & 0 deletions TYPE_FIX_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# AI SDK v6 Type Error Fix Summary

## Problem
The build fails with TypeScript errors after upgrading to AI SDK v6. The main issues are:
1. `ToolCallPart` type now requires `input` field (not optional), but stored data may only have deprecated `args` field
2. Tool-result output types missing newer types like `execution-denied` and extended content types
3. Generated component types out of sync with updated validators

## Changes Made

### 1. Fixed `tool-call` Part Handling (src/mapping.ts)
- Updated `toModelMessageContent()` to ensure `input` is always present by falling back to `args` or `{}`
- Updated `serializeContent()` and `fromModelMessageContent()` to handle both `input` and legacy `args` fields
- This fixes the core issue where AI SDK v6's `ToolCallPart` expects non-nullable `input`

### 2. Fixed Tool Approval Response Handling (src/client/search.ts)
- Updated `filterOutOrphanedToolMessages()` to handle tool-approval-response parts that don't have `toolCallId`
- Tool-approval-response only has `approvalId`, not `toolCallId`

### 3. Updated Generated Component Types (src/component/_generated/component.ts)
Made manual updates to sync with validators (normally done via `convex codegen`):
- Added `input: any` field to all tool-call type definitions
- Made `args` optional (`args?: any`) in tool-call types
- Added `execution-denied` output type to tool-result
- Added extended content types: `file-data`, `file-url`, `file-id`, `image-data`, `image-url`, `image-file-id`, `custom`
- Added `providerOptions` to text types in content values

## Remaining Issues (5 TypeScript errors)

The remaining errors are due to a structural mismatch in the generated component types:
- Generated types have BOTH `experimental_content` (deprecated) and `output` (new) fields on tool-result
- Our validators only define `output`, not `experimental_content`
- TypeScript is comparing our new output types against the old experimental_content types
- This cannot be fixed manually - requires proper component regeneration

### To Complete the Fix:
1. Run `convex codegen --component-dir ./src/component` with a valid Convex deployment
2. This will regenerate `src/component/_generated/component.ts` from the validators
3. The regenerated types will:
- Remove the deprecated `experimental_content` field
- Use only the `output` field with correct types
- Properly match the validator definitions

### Error Locations:
- `src/client/index.ts:1052` - addMessages call
- `src/client/index.ts:1103` - addMessages call
- `src/client/index.ts:1169` - updateMessage call
- `src/client/messages.ts:141` - addMessages call
- `src/client/start.ts:265` - addMessages call

All errors have the same root cause: content value types in tool-result output don't match experimental_content expectations.

## Testing Plan
Once component types are regenerated:
1. Run `npm run build` - should complete without errors
2. Run `npm test` - ensure no regressions
3. Test with actual AI SDK v6 workflow - verify tool-call handling works with both new `input` and legacy `args` fields

## Notes
- The mapping functions in `src/mapping.ts` correctly handle both old and new formats
- Data with only `args` will be converted to have `input` (with `args` as fallback)
- Data with `input` will work directly
- This provides backward compatibility while supporting AI SDK v6's requirements
6 changes: 3 additions & 3 deletions docs/agent-usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ requiring the LLM to always pass through full context to each tool call. It also
allows dynamically choosing a model or other options for the Agent.

```ts
import { Agent } from "@convex-dev/agent";
import { Agent, stepCountIs } from "@convex-dev/agent";
import { type LanguageModel } from "ai";
import type { ActionCtx } from "./_generated/server";
import type { Id } from "./_generated/dataModel";
Expand All @@ -63,7 +63,7 @@ function createAuthorAgent(
researchCharacter: researchCharacterTool(ctx, bookId),
writeChapter: writeChapterTool(ctx, bookId),
},
maxSteps: 10, // Alternative to stopWhen: stepCountIs(10)
stopWhen: stepCountIs(10),
});
}
```
Expand Down Expand Up @@ -249,7 +249,7 @@ const supportAgent = new Agent(components.agent, {
},
}),
// Standard AI SDK tool
myTool: tool({ description, parameters, execute: () => {}}),
myTool: tool({ description, inputSchema: parameters, execute: () => {}}),
},
// Used for limiting the number of steps when tool calls are involved.
// NOTE: if you want tool calls to happen automatically with a single call,
Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ successfully run once before you start defining Agents.

```ts
import { components } from "./_generated/api";
import { Agent } from "@convex-dev/agent";
import { Agent, stepCountIs } from "@convex-dev/agent";
import { openai } from "@ai-sdk/openai";

const agent = new Agent(components.agent, {
name: "My Agent",
languageModel: openai.chat("gpt-4o-mini"),
instructions: "You are a weather forecaster.",
tools: { getWeather, getGeocoding },
maxSteps: 3,
stopWhen: stepCountIs(3),
});
```

Expand Down
2 changes: 1 addition & 1 deletion docs/tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const ideaSearch = createTool({
async function createTool(ctx: ActionCtx, teamId: Id<"teams">) {
const myTool = tool({
description: "My tool",
parameters: z.object({...}).describe("The arguments for the tool"),
inputSchema: z.object({...}).describe("The arguments for the tool"),
execute: async (args, options): Promise<BarReturnType> => {
return await ctx.runQuery(internal.foo.bar, args);
},
Expand Down
13 changes: 5 additions & 8 deletions example/convex/modelsForDemo.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
import { openrouter } from "@openrouter/ai-sdk-provider";
import { type EmbeddingModel } from "ai";
import type { LanguageModelV2 } from "@ai-sdk/provider";
import type { LanguageModelV3 } from "@ai-sdk/provider";
import { anthropic } from "@ai-sdk/anthropic";
import { openai } from "@ai-sdk/openai";
import { groq } from "@ai-sdk/groq";
import { mockModel } from "@convex-dev/agent";

let languageModel: LanguageModelV2;
let textEmbeddingModel: EmbeddingModel<string>;
let languageModel: LanguageModelV3;
let textEmbeddingModel: EmbeddingModel;

if (process.env.ANTHROPIC_API_KEY) {
languageModel = anthropic.chat("claude-opus-4-20250514");
} else if (process.env.OPENAI_API_KEY) {
languageModel = openai.chat("gpt-4o-mini");
textEmbeddingModel = openai.textEmbeddingModel("text-embedding-3-small");
textEmbeddingModel = openai.embedding("text-embedding-3-small");
} else if (process.env.GROQ_API_KEY) {
languageModel = groq.languageModel(
"meta-llama/llama-4-scout-17b-16e-instruct",
);
} else if (process.env.OPENROUTER_API_KEY) {
languageModel = openrouter.chat("openai/gpt-4o-mini") as LanguageModelV2;
} else {
languageModel = mockModel({});
console.warn(
"Run `npx convex env set GROQ_API_KEY=<your-api-key>` or `npx convex env set OPENAI_API_KEY=<your-api-key>` or `npx convex env set OPENROUTER_API_KEY=<your-api-key>` from the example directory to set the API key.",
"Run `npx convex env set GROQ_API_KEY=<your-api-key>` or `npx convex env set OPENAI_API_KEY=<your-api-key>` from the example directory to set the API key.",
);
}

Expand Down
1 change: 0 additions & 1 deletion example/convex/threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export const updateThreadTitle = action({
object: { title, summary },
} = await thread.generateObject(
{
mode: "json",
schemaDescription:
"Generate a title and summary for the thread. The title should be a single sentence that captures the main topic of the thread. The summary should be a short description of the thread that could be used to describe it to someone who hasn't read it.",
schema: z.object({
Expand Down
2 changes: 1 addition & 1 deletion example/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
Expand Down
Loading
Loading