@ai-sdk/openai
Advanced tools
| import { | ||
| createProviderToolFactory, | ||
| lazySchema, | ||
| zodSchema, | ||
| } from '@ai-sdk/provider-utils'; | ||
| import { z } from 'zod/v4'; | ||
| export const customArgsSchema = lazySchema(() => | ||
| zodSchema( | ||
| z.object({ | ||
| name: z.string(), | ||
| description: z.string().optional(), | ||
| format: z | ||
| .union([ | ||
| z.object({ | ||
| type: z.literal('grammar'), | ||
| syntax: z.enum(['regex', 'lark']), | ||
| definition: z.string(), | ||
| }), | ||
| z.object({ | ||
| type: z.literal('text'), | ||
| }), | ||
| ]) | ||
| .optional(), | ||
| }), | ||
| ), | ||
| ); | ||
| const customInputSchema = lazySchema(() => zodSchema(z.string())); | ||
| export const customToolFactory = createProviderToolFactory< | ||
| string, | ||
| { | ||
| /** | ||
| * The name of the custom tool, used to identify it in the API. | ||
| */ | ||
| name: string; | ||
| /** | ||
| * An optional description of what the tool does. | ||
| */ | ||
| description?: string; | ||
| /** | ||
| * The output format specification for the tool. | ||
| * Omit for unconstrained text output. | ||
| */ | ||
| format?: | ||
| | { | ||
| type: 'grammar'; | ||
| syntax: 'regex' | 'lark'; | ||
| definition: string; | ||
| } | ||
| | { | ||
| type: 'text'; | ||
| }; | ||
| } | ||
| >({ | ||
| id: 'openai.custom', | ||
| inputSchema: customInputSchema, | ||
| }); | ||
| export const customTool = (args: Parameters<typeof customToolFactory>[0]) => | ||
| customToolFactory(args); |
+50
-0
@@ -290,2 +290,8 @@ import * as _ai_sdk_provider from '@ai-sdk/provider'; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| } | { | ||
| type: "shell_call"; | ||
@@ -333,2 +339,9 @@ id: string; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| status: "completed"; | ||
| } | { | ||
| type: "code_interpreter_call"; | ||
@@ -483,2 +496,7 @@ id: string; | ||
| } | { | ||
| type: "response.custom_tool_call_input.delta"; | ||
| item_id: string; | ||
| output_index: number; | ||
| delta: string; | ||
| } | { | ||
| type: "response.image_generation_call.partial_image"; | ||
@@ -562,2 +580,24 @@ item_id: string; | ||
| declare const customToolFactory: _ai_sdk_provider_utils.ProviderToolFactory<string, { | ||
| /** | ||
| * The name of the custom tool, used to identify it in the API. | ||
| */ | ||
| name: string; | ||
| /** | ||
| * An optional description of what the tool does. | ||
| */ | ||
| description?: string; | ||
| /** | ||
| * The output format specification for the tool. | ||
| * Omit for unconstrained text output. | ||
| */ | ||
| format?: { | ||
| type: "grammar"; | ||
| syntax: "regex" | "lark"; | ||
| definition: string; | ||
| } | { | ||
| type: "text"; | ||
| }; | ||
| }>; | ||
| /** | ||
@@ -610,2 +650,12 @@ * Type definitions for the apply_patch operations. | ||
| /** | ||
| * Custom tools let callers constrain model output to a grammar (regex or | ||
| * Lark syntax). The model returns a `custom_tool_call` output item whose | ||
| * `input` field is a string matching the specified grammar. | ||
| * | ||
| * @param name - The name of the custom tool. | ||
| * @param description - An optional description of the tool. | ||
| * @param format - The output format constraint (grammar type, syntax, and definition). | ||
| */ | ||
| customTool: (args: Parameters<typeof customToolFactory>[0]) => _ai_sdk_provider_utils.Tool<string, unknown>; | ||
| /** | ||
| * The Code Interpreter tool allows models to write and run Python code in a | ||
@@ -612,0 +662,0 @@ * sandboxed environment to solve complex problems in domains like data analysis, |
+50
-0
@@ -290,2 +290,8 @@ import * as _ai_sdk_provider from '@ai-sdk/provider'; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| } | { | ||
| type: "shell_call"; | ||
@@ -333,2 +339,9 @@ id: string; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| status: "completed"; | ||
| } | { | ||
| type: "code_interpreter_call"; | ||
@@ -483,2 +496,7 @@ id: string; | ||
| } | { | ||
| type: "response.custom_tool_call_input.delta"; | ||
| item_id: string; | ||
| output_index: number; | ||
| delta: string; | ||
| } | { | ||
| type: "response.image_generation_call.partial_image"; | ||
@@ -562,2 +580,24 @@ item_id: string; | ||
| declare const customToolFactory: _ai_sdk_provider_utils.ProviderToolFactory<string, { | ||
| /** | ||
| * The name of the custom tool, used to identify it in the API. | ||
| */ | ||
| name: string; | ||
| /** | ||
| * An optional description of what the tool does. | ||
| */ | ||
| description?: string; | ||
| /** | ||
| * The output format specification for the tool. | ||
| * Omit for unconstrained text output. | ||
| */ | ||
| format?: { | ||
| type: "grammar"; | ||
| syntax: "regex" | "lark"; | ||
| definition: string; | ||
| } | { | ||
| type: "text"; | ||
| }; | ||
| }>; | ||
| /** | ||
@@ -610,2 +650,12 @@ * Type definitions for the apply_patch operations. | ||
| /** | ||
| * Custom tools let callers constrain model output to a grammar (regex or | ||
| * Lark syntax). The model returns a `custom_tool_call` output item whose | ||
| * `input` field is a string matching the specified grammar. | ||
| * | ||
| * @param name - The name of the custom tool. | ||
| * @param description - An optional description of the tool. | ||
| * @param format - The output format constraint (grammar type, syntax, and definition). | ||
| */ | ||
| customTool: (args: Parameters<typeof customToolFactory>[0]) => _ai_sdk_provider_utils.Tool<string, unknown>; | ||
| /** | ||
| * The Code Interpreter tool allows models to write and run Python code in a | ||
@@ -612,0 +662,0 @@ * sandboxed environment to solve complex problems in domains like data analysis, |
@@ -349,2 +349,8 @@ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, EmbeddingModelV3, ImageModelV3, TranscriptionModelV3CallOptions, TranscriptionModelV3, SpeechModelV3 } from '@ai-sdk/provider'; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| } | { | ||
| type: "shell_call"; | ||
@@ -392,2 +398,9 @@ id: string; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| status: "completed"; | ||
| } | { | ||
| type: "code_interpreter_call"; | ||
@@ -542,2 +555,7 @@ id: string; | ||
| } | { | ||
| type: "response.custom_tool_call_input.delta"; | ||
| item_id: string; | ||
| output_index: number; | ||
| delta: string; | ||
| } | { | ||
| type: "response.image_generation_call.partial_image"; | ||
@@ -544,0 +562,0 @@ item_id: string; |
@@ -349,2 +349,8 @@ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, EmbeddingModelV3, ImageModelV3, TranscriptionModelV3CallOptions, TranscriptionModelV3, SpeechModelV3 } from '@ai-sdk/provider'; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| } | { | ||
| type: "shell_call"; | ||
@@ -392,2 +398,9 @@ id: string; | ||
| } | { | ||
| type: "custom_tool_call"; | ||
| id: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| status: "completed"; | ||
| } | { | ||
| type: "code_interpreter_call"; | ||
@@ -542,2 +555,7 @@ id: string; | ||
| } | { | ||
| type: "response.custom_tool_call_input.delta"; | ||
| item_id: string; | ||
| output_index: number; | ||
| delta: string; | ||
| } | { | ||
| type: "response.image_generation_call.partial_image"; | ||
@@ -544,0 +562,0 @@ item_id: string; |
+2
-2
| { | ||
| "name": "@ai-sdk/openai", | ||
| "version": "3.0.36", | ||
| "version": "3.0.37", | ||
| "license": "Apache-2.0", | ||
@@ -40,3 +40,3 @@ "sideEffects": false, | ||
| "@ai-sdk/provider": "3.0.8", | ||
| "@ai-sdk/provider-utils": "4.0.15" | ||
| "@ai-sdk/provider-utils": "4.0.16" | ||
| }, | ||
@@ -43,0 +43,0 @@ "devDependencies": { |
+12
-0
| import { applyPatch } from './tool/apply-patch'; | ||
| import { codeInterpreter } from './tool/code-interpreter'; | ||
| import { customTool } from './tool/custom'; | ||
| import { fileSearch } from './tool/file-search'; | ||
@@ -22,2 +23,13 @@ import { imageGeneration } from './tool/image-generation'; | ||
| /** | ||
| * Custom tools let callers constrain model output to a grammar (regex or | ||
| * Lark syntax). The model returns a `custom_tool_call` output item whose | ||
| * `input` field is a string matching the specified grammar. | ||
| * | ||
| * @param name - The name of the custom tool. | ||
| * @param description - An optional description of the tool. | ||
| * @param format - The output format constraint (grammar type, syntax, and definition). | ||
| */ | ||
| customTool, | ||
| /** | ||
| * The Code Interpreter tool allows models to write and run Python code in a | ||
@@ -24,0 +36,0 @@ * sandboxed environment to solve complex problems in domains like data analysis, |
@@ -25,2 +25,3 @@ import { | ||
| import { | ||
| OpenAIResponsesCustomToolCallOutput, | ||
| OpenAIResponsesFunctionCallOutput, | ||
@@ -51,2 +52,3 @@ OpenAIResponsesInput, | ||
| hasApplyPatchTool = false, | ||
| customProviderToolNames, | ||
| }: { | ||
@@ -63,2 +65,3 @@ prompt: LanguageModelV3Prompt; | ||
| hasApplyPatchTool?: boolean; | ||
| customProviderToolNames?: Set<string>; | ||
| }): Promise<{ | ||
@@ -283,2 +286,16 @@ input: OpenAIResponsesInput; | ||
| if (customProviderToolNames?.has(resolvedToolName)) { | ||
| input.push({ | ||
| type: 'custom_tool_call', | ||
| call_id: part.toolCallId, | ||
| name: resolvedToolName, | ||
| input: | ||
| typeof part.input === 'string' | ||
| ? part.input | ||
| : JSON.stringify(part.input), | ||
| id, | ||
| }); | ||
| break; | ||
| } | ||
| input.push({ | ||
@@ -582,2 +599,59 @@ type: 'function_call', | ||
| if (customProviderToolNames?.has(resolvedToolName)) { | ||
| let outputValue: OpenAIResponsesCustomToolCallOutput['output']; | ||
| switch (output.type) { | ||
| case 'text': | ||
| case 'error-text': | ||
| outputValue = output.value; | ||
| break; | ||
| case 'execution-denied': | ||
| outputValue = output.reason ?? 'Tool execution denied.'; | ||
| break; | ||
| case 'json': | ||
| case 'error-json': | ||
| outputValue = JSON.stringify(output.value); | ||
| break; | ||
| case 'content': | ||
| outputValue = output.value | ||
| .map(item => { | ||
| switch (item.type) { | ||
| case 'text': | ||
| return { type: 'input_text' as const, text: item.text }; | ||
| case 'image-data': | ||
| return { | ||
| type: 'input_image' as const, | ||
| image_url: `data:${item.mediaType};base64,${item.data}`, | ||
| }; | ||
| case 'image-url': | ||
| return { | ||
| type: 'input_image' as const, | ||
| image_url: item.url, | ||
| }; | ||
| case 'file-data': | ||
| return { | ||
| type: 'input_file' as const, | ||
| filename: item.filename ?? 'data', | ||
| file_data: `data:${item.mediaType};base64,${item.data}`, | ||
| }; | ||
| default: | ||
| warnings.push({ | ||
| type: 'other', | ||
| message: `unsupported custom tool content part type: ${item.type}`, | ||
| }); | ||
| return undefined; | ||
| } | ||
| }) | ||
| .filter(isNonNullable); | ||
| break; | ||
| default: | ||
| outputValue = ''; | ||
| } | ||
| input.push({ | ||
| type: 'custom_tool_call_output', | ||
| call_id: part.toolCallId, | ||
| output: outputValue, | ||
| } satisfies OpenAIResponsesCustomToolCallOutput); | ||
| continue; | ||
| } | ||
| let contentValue: OpenAIResponsesFunctionCallOutput['output']; | ||
@@ -584,0 +658,0 @@ switch (output.type) { |
@@ -13,2 +13,4 @@ import { JSONSchema7 } from '@ai-sdk/provider'; | ||
| | OpenAIResponsesFunctionCallOutput | ||
| | OpenAIResponsesCustomToolCall | ||
| | OpenAIResponsesCustomToolCallOutput | ||
| | OpenAIResponsesMcpApprovalResponse | ||
@@ -98,2 +100,16 @@ | OpenAIResponsesComputerCall | ||
| export type OpenAIResponsesCustomToolCall = { | ||
| type: 'custom_tool_call'; | ||
| id?: string; | ||
| call_id: string; | ||
| name: string; | ||
| input: string; | ||
| }; | ||
| export type OpenAIResponsesCustomToolCallOutput = { | ||
| type: 'custom_tool_call_output'; | ||
| call_id: string; | ||
| output: OpenAIResponsesFunctionCallOutput['output']; | ||
| }; | ||
| export type OpenAIResponsesMcpApprovalResponse = { | ||
@@ -332,2 +348,16 @@ type: 'mcp_approval_response'; | ||
| | { | ||
| type: 'custom'; | ||
| name: string; | ||
| description?: string; | ||
| format?: | ||
| | { | ||
| type: 'grammar'; | ||
| syntax: 'regex' | 'lark'; | ||
| definition: string; | ||
| } | ||
| | { | ||
| type: 'text'; | ||
| }; | ||
| } | ||
| | { | ||
| type: 'local_shell'; | ||
@@ -534,2 +564,9 @@ } | ||
| z.object({ | ||
| type: z.literal('custom_tool_call'), | ||
| id: z.string(), | ||
| call_id: z.string(), | ||
| name: z.string(), | ||
| input: z.string(), | ||
| }), | ||
| z.object({ | ||
| type: z.literal('shell_call'), | ||
@@ -587,2 +624,10 @@ id: z.string(), | ||
| z.object({ | ||
| type: z.literal('custom_tool_call'), | ||
| id: z.string(), | ||
| call_id: z.string(), | ||
| name: z.string(), | ||
| input: z.string(), | ||
| status: z.literal('completed'), | ||
| }), | ||
| z.object({ | ||
| type: z.literal('code_interpreter_call'), | ||
@@ -787,2 +832,8 @@ id: z.string(), | ||
| z.object({ | ||
| type: z.literal('response.custom_tool_call_input.delta'), | ||
| item_id: z.string(), | ||
| output_index: z.number(), | ||
| delta: z.string(), | ||
| }), | ||
| z.object({ | ||
| type: z.literal('response.image_generation_call.partial_image'), | ||
@@ -1069,2 +1120,9 @@ item_id: z.string(), | ||
| z.object({ | ||
| type: z.literal('custom_tool_call'), | ||
| call_id: z.string(), | ||
| name: z.string(), | ||
| input: z.string(), | ||
| id: z.string(), | ||
| }), | ||
| z.object({ | ||
| type: z.literal('computer_call'), | ||
@@ -1071,0 +1129,0 @@ id: z.string(), |
@@ -6,6 +6,7 @@ import { | ||
| } from '@ai-sdk/provider'; | ||
| import { validateTypes } from '@ai-sdk/provider-utils'; | ||
| import { ToolNameMapping, validateTypes } from '@ai-sdk/provider-utils'; | ||
| import { codeInterpreterArgsSchema } from '../tool/code-interpreter'; | ||
| import { fileSearchArgsSchema } from '../tool/file-search'; | ||
| import { imageGenerationArgsSchema } from '../tool/image-generation'; | ||
| import { customArgsSchema } from '../tool/custom'; | ||
| import { mcpArgsSchema } from '../tool/mcp'; | ||
@@ -20,5 +21,9 @@ import { shellArgsSchema } from '../tool/shell'; | ||
| toolChoice, | ||
| toolNameMapping, | ||
| customProviderToolNames, | ||
| }: { | ||
| tools: LanguageModelV3CallOptions['tools']; | ||
| toolChoice: LanguageModelV3CallOptions['toolChoice'] | undefined; | ||
| toolNameMapping?: ToolNameMapping; | ||
| customProviderToolNames?: Set<string>; | ||
| }): Promise<{ | ||
@@ -34,2 +39,3 @@ tools?: Array<OpenAIResponsesTool>; | ||
| | { type: 'function'; name: string } | ||
| | { type: 'custom'; name: string } | ||
| | { type: 'code_interpreter' } | ||
@@ -51,2 +57,4 @@ | { type: 'mcp' } | ||
| const openaiTools: Array<OpenAIResponsesTool> = []; | ||
| const resolvedCustomProviderToolNames = | ||
| customProviderToolNames ?? new Set<string>(); | ||
@@ -232,2 +240,17 @@ for (const tool of tools) { | ||
| } | ||
| case 'openai.custom': { | ||
| const args = await validateTypes({ | ||
| value: tool.args, | ||
| schema: customArgsSchema, | ||
| }); | ||
| openaiTools.push({ | ||
| type: 'custom', | ||
| name: args.name, | ||
| description: args.description, | ||
| format: args.format, | ||
| }); | ||
| resolvedCustomProviderToolNames.add(args.name); | ||
| break; | ||
| } | ||
| } | ||
@@ -256,17 +279,24 @@ break; | ||
| return { tools: openaiTools, toolChoice: type, toolWarnings }; | ||
| case 'tool': | ||
| case 'tool': { | ||
| const resolvedToolName = | ||
| toolNameMapping?.toProviderToolName(toolChoice.toolName) ?? | ||
| toolChoice.toolName; | ||
| return { | ||
| tools: openaiTools, | ||
| toolChoice: | ||
| toolChoice.toolName === 'code_interpreter' || | ||
| toolChoice.toolName === 'file_search' || | ||
| toolChoice.toolName === 'image_generation' || | ||
| toolChoice.toolName === 'web_search_preview' || | ||
| toolChoice.toolName === 'web_search' || | ||
| toolChoice.toolName === 'mcp' || | ||
| toolChoice.toolName === 'apply_patch' | ||
| ? { type: toolChoice.toolName } | ||
| : { type: 'function', name: toolChoice.toolName }, | ||
| resolvedToolName === 'code_interpreter' || | ||
| resolvedToolName === 'file_search' || | ||
| resolvedToolName === 'image_generation' || | ||
| resolvedToolName === 'web_search_preview' || | ||
| resolvedToolName === 'web_search' || | ||
| resolvedToolName === 'mcp' || | ||
| resolvedToolName === 'apply_patch' | ||
| ? { type: resolvedToolName } | ||
| : resolvedCustomProviderToolNames.has(resolvedToolName) | ||
| ? { type: 'custom', name: resolvedToolName } | ||
| : { type: 'function', name: resolvedToolName }, | ||
| toolWarnings, | ||
| }; | ||
| } | ||
| default: { | ||
@@ -273,0 +303,0 @@ const _exhaustiveCheck: never = type; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
3383379
3.32%73
1.39%36794
3.45%+ Added
- Removed