diff --git a/TYPE_FIX_SUMMARY.md b/TYPE_FIX_SUMMARY.md new file mode 100644 index 00000000..f11e3ad2 --- /dev/null +++ b/TYPE_FIX_SUMMARY.md @@ -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 diff --git a/src/client/index.test.ts b/src/client/index.test.ts index f6e97269..9a2c4e18 100644 --- a/src/client/index.test.ts +++ b/src/client/index.test.ts @@ -193,6 +193,7 @@ describe("filterOutOrphanedToolMessages", () => { type: "tool-call", toolCallId: "1", toolName: "tool1", + input: { test: "test" }, args: { test: "test" }, }, ], diff --git a/src/client/search.test.ts b/src/client/search.test.ts index c2749c92..3a9b9b86 100644 --- a/src/client/search.test.ts +++ b/src/client/search.test.ts @@ -159,6 +159,7 @@ describe("search.ts", () => { type: "tool-call", toolCallId: "call_123", toolName: "test", + input: {}, args: {}, }, ], @@ -202,6 +203,7 @@ describe("search.ts", () => { type: "tool-call", toolCallId: "call_orphaned", toolName: "test", + input: {}, args: {}, }, ], diff --git a/src/client/search.ts b/src/client/search.ts index 05cf42d5..5c970932 100644 --- a/src/client/search.ts +++ b/src/client/search.ts @@ -267,9 +267,14 @@ export function filterOutOrphanedToolMessages(docs: MessageDoc[]) { }); } } else if (doc.message?.role === "tool") { - const content = doc.message.content.filter((c) => - toolCallIds.has(c.toolCallId), - ); + const content = doc.message.content.filter((c) => { + // tool-result parts have toolCallId + if (c.type === "tool-result") { + return toolCallIds.has(c.toolCallId); + } + // tool-approval-response parts don't have toolCallId, so include them + return true; + }); if (content.length) { result.push({ ...doc, diff --git a/src/component/_generated/component.ts b/src/component/_generated/component.ts index 7ee22d7d..f6708edc 100644 --- a/src/component/_generated/component.ts +++ b/src/component/_generated/component.ts @@ -185,6 +185,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record< string, @@ -267,8 +268,25 @@ export type ComponentApi = >; type: "redacted-reasoning"; } + | { + args?: any; + input: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args: any; + input?: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -294,19 +312,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -354,38 +473,167 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } @@ -490,6 +738,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record< string, @@ -572,8 +821,25 @@ export type ComponentApi = >; type: "redacted-reasoning"; } + | { + args?: any; + input: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args: any; + input?: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -599,19 +865,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -659,38 +1026,167 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } @@ -846,6 +1342,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record>; type: "image"; @@ -854,7 +1351,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -883,7 +1380,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -911,7 +1408,8 @@ export type ComponentApi = type: "redacted-reasoning"; } | { - args: any; + args?: any; + input: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -922,6 +1420,22 @@ export type ComponentApi = toolName: string; type: "tool-call"; } + | { + args: any; + input?: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args?: any; experimental_content?: Array< @@ -930,19 +1444,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -981,87 +1596,213 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record>; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; - providerOptions?: Record>; - role: "tool"; - } - | { - content: string; - providerOptions?: Record>; - role: "system"; - }; - model?: string; - order: number; - provider?: string; - providerMetadata?: Record>; - providerOptions?: Record>; - reasoning?: string; - reasoningDetails?: Array< - | { - providerMetadata?: Record>; - providerOptions?: Record>; - signature?: string; - text: string; - type: "reasoning"; - } - | { signature?: string; text: string; type: "text" } - | { data: string; type: "redacted" } - >; - sources?: Array< - | { - id: string; - providerMetadata?: Record>; - providerOptions?: Record>; - sourceType: "url"; - title?: string; - type?: "source"; - url: string; - } - | { - filename?: string; - id: string; - mediaType: string; - providerMetadata?: Record>; - providerOptions?: Record>; - sourceType: "document"; - title: string; - type: "source"; - } - >; - status: "pending" | "success" | "failed"; - stepOrder: number; - text?: string; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; + providerOptions?: Record>; + role: "tool"; + } + | { + content: string; + providerOptions?: Record>; + role: "system"; + }; + model?: string; + order: number; + provider?: string; + providerMetadata?: Record>; + providerOptions?: Record>; + reasoning?: string; + reasoningDetails?: Array< + | { + providerMetadata?: Record>; + providerOptions?: Record>; + signature?: string; + text: string; + type: "reasoning"; + } + | { signature?: string; text: string; type: "text" } + | { data: string; type: "redacted" } + >; + sources?: Array< + | { + id: string; + providerMetadata?: Record>; + providerOptions?: Record>; + sourceType: "url"; + title?: string; + type?: "source"; + url: string; + } + | { + filename?: string; + id: string; + mediaType: string; + providerMetadata?: Record>; + providerOptions?: Record>; + sourceType: "document"; + title: string; + type: "source"; + } + >; + status: "pending" | "success" | "failed"; + stepOrder: number; + text?: string; threadId: string; tool: boolean; usage?: { @@ -1143,6 +1884,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record< string, @@ -1225,8 +1967,25 @@ export type ComponentApi = >; type: "redacted-reasoning"; } + | { + args?: any; + input: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args: any; + input?: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -1252,19 +2011,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -1312,38 +2172,167 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } @@ -1466,6 +2455,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record>; type: "image"; @@ -1474,7 +2464,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -1503,7 +2493,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -1531,7 +2521,8 @@ export type ComponentApi = type: "redacted-reasoning"; } | { - args: any; + args?: any; + input: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -1542,6 +2533,22 @@ export type ComponentApi = toolName: string; type: "tool-call"; } + | { + args: any; + input?: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args?: any; experimental_content?: Array< @@ -1550,19 +2557,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -1601,46 +2709,172 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record>; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; - providerOptions?: Record>; - role: "tool"; - } - | { - content: string; - providerOptions?: Record>; - role: "system"; - }; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; + providerOptions?: Record>; + role: "tool"; + } + | { + content: string; + providerOptions?: Record>; + role: "system"; + }; model?: string; order: number; provider?: string; @@ -1742,6 +2976,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record>; type: "image"; @@ -1750,7 +2985,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -1779,7 +3014,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -1807,7 +3042,8 @@ export type ComponentApi = type: "redacted-reasoning"; } | { - args: any; + args?: any; + input: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -1818,6 +3054,22 @@ export type ComponentApi = toolName: string; type: "tool-call"; } + | { + args: any; + input?: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args?: any; experimental_content?: Array< @@ -1826,19 +3078,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -1877,38 +3230,164 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record>; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } @@ -2011,6 +3490,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record< string, @@ -2093,8 +3573,25 @@ export type ComponentApi = >; type: "redacted-reasoning"; } + | { + args?: any; + input: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args: any; + input?: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -2120,19 +3617,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -2180,38 +3778,167 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } @@ -2258,6 +3985,7 @@ export type ComponentApi = } | { image: string | ArrayBuffer; + mediaType?: string; mimeType?: string; providerOptions?: Record>; type: "image"; @@ -2266,7 +3994,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -2295,7 +4023,7 @@ export type ComponentApi = data: string | ArrayBuffer; filename?: string; mediaType?: string; - mimeType?: string; + mimeType?: string; providerMetadata?: Record< string, Record @@ -2323,7 +4051,8 @@ export type ComponentApi = type: "redacted-reasoning"; } | { - args: any; + args?: any; + input: any; providerExecuted?: boolean; providerMetadata?: Record< string, @@ -2334,6 +4063,22 @@ export type ComponentApi = toolName: string; type: "tool-call"; } + | { + args: any; + input?: any; + providerExecuted?: boolean; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record< + string, + Record + >; + toolCallId: string; + toolName: string; + type: "tool-call"; + } | { args?: any; experimental_content?: Array< @@ -2342,19 +4087,120 @@ export type ComponentApi = >; isError?: boolean; output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } | { type: "content"; value: Array< - | { text: string; type: "text" } + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } | { data: string; mediaType: string; type: "media"; } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } >; }; providerExecuted?: boolean; @@ -2393,38 +4239,164 @@ export type ComponentApi = title: string; type: "source"; } + | { + approvalId: string; + providerMetadata?: Record< + string, + Record + >; + providerOptions?: Record>; + toolCallId: string; + type: "tool-approval-request"; + } >; providerOptions?: Record>; role: "assistant"; } | { - content: Array<{ - args?: any; - experimental_content?: Array< - | { text: string; type: "text" } - | { data: string; mimeType?: string; type: "image" } - >; - isError?: boolean; - output?: - | { type: "text"; value: string } - | { type: "json"; value: any } - | { type: "error-text"; value: string } - | { type: "error-json"; value: any } - | { - type: "content"; - value: Array< - | { text: string; type: "text" } - | { data: string; mediaType: string; type: "media" } - >; - }; - providerExecuted?: boolean; - providerMetadata?: Record>; - providerOptions?: Record>; - result?: any; - toolCallId: string; - toolName: string; - type: "tool-result"; - }>; + content: Array< + | { + args?: any; + experimental_content?: Array< + | { text: string; type: "text" } + | { data: string; mimeType?: string; type: "image" } + >; + isError?: boolean; + output?: + | { + providerOptions?: Record< + string, + Record + >; + type: "text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-text"; + value: string; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "error-json"; + value: any; + } + | { + providerOptions?: Record< + string, + Record + >; + reason?: string; + type: "execution-denied"; + } + | { + type: "content"; + value: Array< + | { + providerOptions?: Record< + string, + Record + >; + text: string; + type: "text"; + } + | { + data: string; + mediaType: string; + type: "media"; + } + | { + data: string; + filename?: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "file-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "file-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "file-id"; + } + | { + data: string; + mediaType: string; + providerOptions?: Record< + string, + Record + >; + type: "image-data"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "image-url"; + url: string; + } + | { + fileId: string | Record; + providerOptions?: Record< + string, + Record + >; + type: "image-file-id"; + } + | { + providerOptions?: Record< + string, + Record + >; + type: "custom"; + } + >; + }; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + result?: any; + toolCallId: string; + toolName: string; + type: "tool-result"; + } + | { + approvalId: string; + approved: boolean; + providerExecuted?: boolean; + providerMetadata?: Record>; + providerOptions?: Record>; + reason?: string; + type: "tool-approval-response"; + } + >; providerOptions?: Record>; role: "tool"; } diff --git a/src/component/messages.test.ts b/src/component/messages.test.ts index 9581b8f6..0c273307 100644 --- a/src/component/messages.test.ts +++ b/src/component/messages.test.ts @@ -68,7 +68,7 @@ describe("agent", () => { content: [ { type: "tool-call", - args: { a: 1 }, + input: { a: 1 }, toolCallId: "1", toolName: "tool", }, @@ -258,7 +258,7 @@ describe("agent", () => { content: [ { type: "tool-call", - args: { a: 1 }, + input: { a: 1 }, toolCallId: "1", toolName: "tool", }, @@ -389,7 +389,7 @@ describe("agent", () => { content: [ { type: "tool-call", - args: { a: 1 }, + input: { a: 1 }, toolCallId: "1", toolName: "tool", }, @@ -408,7 +408,7 @@ describe("agent", () => { content: [ { type: "tool-call", - args: { a: 2, b: 3 }, + input: { a: 2, b: 3 }, toolCallId: "1", toolName: "tool", }, @@ -422,7 +422,7 @@ describe("agent", () => { content: [ { type: "tool-call", - args: { a: 2, b: 3 }, + input: { a: 2, b: 3 }, toolCallId: "1", toolName: "tool", }, diff --git a/src/fromUIMessages.test.ts b/src/fromUIMessages.test.ts index cbe0cb24..4413c3c1 100644 --- a/src/fromUIMessages.test.ts +++ b/src/fromUIMessages.test.ts @@ -166,6 +166,7 @@ describe("fromUIMessages round-trip tests", () => { type: "tool-call", toolName: "calculator", toolCallId: "call1", + input: { operation: "add", a: 2, b: 3 }, args: { operation: "add", a: 2, b: 3 }, }, ], @@ -442,7 +443,9 @@ describe("fromUIMessages functionality tests", () => { ], }; - const result = await fromUIMessages([toolUIMessage], { threadId: "thread1" }); + const result = await fromUIMessages([toolUIMessage], { + threadId: "thread1", + }); expect(result.length).toBeGreaterThan(0); // Should have tool messages @@ -471,7 +474,9 @@ describe("fromUIMessages functionality tests", () => { ], }; - const result = await fromUIMessages([toolUIMessage], { threadId: "thread1" }); + const result = await fromUIMessages([toolUIMessage], { + threadId: "thread1", + }); expect(result.length).toBeGreaterThan(0); // Should have tool messages diff --git a/src/mapping.ts b/src/mapping.ts index 4bb91659..c2d179c0 100644 --- a/src/mapping.ts +++ b/src/mapping.ts @@ -353,12 +353,13 @@ export async function serializeContent( } satisfies Infer; } case "tool-call": { - const input = part.input ?? (part as any)?.args; + // Handle legacy data where only args field exists + const input = part.input ?? (part as any)?.args ?? {}; return { type: part.type, - input: input ?? null, + input, /** @deprecated Use `input` instead. */ - args: input ?? null, + args: input, toolCallId: part.toolCallId, toolName: part.toolName, providerExecuted: part.providerExecuted, @@ -432,11 +433,12 @@ export function fromModelMessageContent(content: Content): Message["content"] { ...metadata, } satisfies Infer; case "tool-call": + // Handle legacy data where only args field exists return { type: part.type, - input: part.input ?? null, + input: part.input ?? (part as any)?.args ?? {}, /** @deprecated Use `input` instead. */ - args: part.input ?? null, + args: part.input ?? (part as any)?.args ?? {}, toolCallId: part.toolCallId, toolName: part.toolName, providerExecuted: part.providerExecuted, @@ -515,10 +517,11 @@ export function toModelMessageContent( ...metadata, } satisfies FilePart; case "tool-call": { - const input = part.input ?? (part as any)?.args; + // Handle legacy data where only args field exists + const input = part.input ?? (part as any)?.args ?? {}; return { type: part.type, - input: input ?? null, + input, toolCallId: part.toolCallId, toolName: part.toolName, providerExecuted: part.providerExecuted, diff --git a/src/toUIMessages.test.ts b/src/toUIMessages.test.ts index f871f8d3..63edb787 100644 --- a/src/toUIMessages.test.ts +++ b/src/toUIMessages.test.ts @@ -90,6 +90,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "myTool", toolCallId: "call1", + input: "an arg", args: "an arg", }, ], @@ -219,6 +220,7 @@ describe("toUIMessages", () => { }, { type: "tool-call", + input: "What's the meaning of life?", args: "What's the meaning of life?", toolCallId: "call1", toolName: "myTool", @@ -310,6 +312,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "myTool", toolCallId: "call1", + input: { query: "test" }, args: { query: "test" }, }, ], @@ -356,6 +359,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "myTool", toolCallId: "call1", + input: "hi", args: "hi", }, ], @@ -387,6 +391,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "myTool", toolCallId: "call1", + input: "", args: "", }, ], @@ -448,6 +453,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "calculator", toolCallId: "call1", + input: { operation: "add", a: 2, b: 3 }, args: { operation: "add", a: 2, b: 3 }, }, { @@ -490,6 +496,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "calculator", toolCallId: "call1", + input: { operation: "add", a: 1, b: 2 }, args: { operation: "add", a: 1, b: 2 }, }, ], @@ -561,6 +568,9 @@ describe("toUIMessages", () => { text: "**Finding the Time**\n\nI've pinpointed the core task: obtaining the current time in Paris. It involves using the `dateTime` tool. I've identified \"Europe/Paris\" as the necessary timezone identifier to provide to the tool. My next step is to test the tool.\n\n\n", }, { + input: { + timezone: "Europe/Paris", + }, args: { timezone: "Europe/Paris", }, @@ -690,6 +700,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "calculator", toolCallId: "call1", + input: { operation: "add", a: 40, b: 2 }, args: { operation: "add", a: 40, b: 2 }, }, ], @@ -744,6 +755,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "generateImage", toolCallId: "call1", + input: { id: "invalid-id" }, args: { id: "invalid-id" }, }, ], @@ -898,6 +910,7 @@ describe("toUIMessages", () => { type: "tool-call", toolName: "myTool", toolCallId: "call1", + input: {}, args: {}, }, ], diff --git a/src/validators.ts b/src/validators.ts index f7ecea38..f8e03132 100644 --- a/src/validators.ts +++ b/src/validators.ts @@ -115,17 +115,34 @@ export const vSourcePart = v.union( ); export type SourcePart = Infer; -export const vToolCallPart = v.object({ - type: v.literal("tool-call"), - toolCallId: v.string(), - toolName: v.string(), - input: v.any(), - /** @deprecated Use `input` instead. */ - args: v.optional(v.any()), - providerExecuted: v.optional(v.boolean()), - providerOptions, - providerMetadata, -}); +// Union type to support both old (args) and new (input) formats +// Both include input for type hint support +export const vToolCallPart = v.union( + // New format: input is primary, args is optional for backwards compat + v.object({ + type: v.literal("tool-call"), + toolCallId: v.string(), + toolName: v.string(), + input: v.any(), + /** @deprecated Use `input` instead. */ + args: v.optional(v.any()), + providerExecuted: v.optional(v.boolean()), + providerOptions, + providerMetadata, + }), + // Legacy format: args is present, input is optional + v.object({ + type: v.literal("tool-call"), + toolCallId: v.string(), + toolName: v.string(), + /** @deprecated Use `input` instead. */ + args: v.any(), + input: v.optional(v.any()), + providerExecuted: v.optional(v.boolean()), + providerOptions, + providerMetadata, + }), +); const vToolResultContent = v.array( v.union(