mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-17 12:56:41 +02:00
174 lines
5.6 KiB
TypeScript
174 lines
5.6 KiB
TypeScript
import { type LanguageModelV3CallOptions, type SharedV3Warning, UnsupportedFunctionalityError } from "@ai-sdk/provider"
|
|
import { codeInterpreterArgsSchema } from "./tool/code-interpreter"
|
|
import { fileSearchArgsSchema } from "./tool/file-search"
|
|
import { webSearchArgsSchema } from "./tool/web-search"
|
|
import { webSearchPreviewArgsSchema } from "./tool/web-search-preview"
|
|
import { imageGenerationArgsSchema } from "./tool/image-generation"
|
|
import type { OpenAIResponsesTool } from "./openai-responses-api-types"
|
|
|
|
export function prepareResponsesTools({
|
|
tools,
|
|
toolChoice,
|
|
strictJsonSchema,
|
|
}: {
|
|
tools: LanguageModelV3CallOptions["tools"]
|
|
toolChoice?: LanguageModelV3CallOptions["toolChoice"]
|
|
strictJsonSchema: boolean
|
|
}): {
|
|
tools?: Array<OpenAIResponsesTool>
|
|
toolChoice?:
|
|
| "auto"
|
|
| "none"
|
|
| "required"
|
|
| { type: "file_search" }
|
|
| { type: "web_search_preview" }
|
|
| { type: "web_search" }
|
|
| { type: "function"; name: string }
|
|
| { type: "code_interpreter" }
|
|
| { type: "image_generation" }
|
|
toolWarnings: SharedV3Warning[]
|
|
} {
|
|
// when the tools array is empty, change it to undefined to prevent errors:
|
|
tools = tools?.length ? tools : undefined
|
|
|
|
const toolWarnings: SharedV3Warning[] = []
|
|
|
|
if (tools == null) {
|
|
return { tools: undefined, toolChoice: undefined, toolWarnings }
|
|
}
|
|
|
|
const openaiTools: Array<OpenAIResponsesTool> = []
|
|
|
|
for (const tool of tools) {
|
|
switch (tool.type) {
|
|
case "function":
|
|
openaiTools.push({
|
|
type: "function",
|
|
name: tool.name,
|
|
description: tool.description,
|
|
parameters: tool.inputSchema,
|
|
strict: strictJsonSchema,
|
|
})
|
|
break
|
|
case "provider": {
|
|
switch (tool.id) {
|
|
case "openai.file_search": {
|
|
const args = fileSearchArgsSchema.parse(tool.args)
|
|
|
|
openaiTools.push({
|
|
type: "file_search",
|
|
vector_store_ids: args.vectorStoreIds,
|
|
max_num_results: args.maxNumResults,
|
|
ranking_options: args.ranking
|
|
? {
|
|
ranker: args.ranking.ranker,
|
|
score_threshold: args.ranking.scoreThreshold,
|
|
}
|
|
: undefined,
|
|
filters: args.filters,
|
|
})
|
|
|
|
break
|
|
}
|
|
case "openai.local_shell": {
|
|
openaiTools.push({
|
|
type: "local_shell",
|
|
})
|
|
break
|
|
}
|
|
case "openai.web_search_preview": {
|
|
const args = webSearchPreviewArgsSchema.parse(tool.args)
|
|
openaiTools.push({
|
|
type: "web_search_preview",
|
|
search_context_size: args.searchContextSize,
|
|
user_location: args.userLocation,
|
|
})
|
|
break
|
|
}
|
|
case "openai.web_search": {
|
|
const args = webSearchArgsSchema.parse(tool.args)
|
|
openaiTools.push({
|
|
type: "web_search",
|
|
filters: args.filters != null ? { allowed_domains: args.filters.allowedDomains } : undefined,
|
|
search_context_size: args.searchContextSize,
|
|
user_location: args.userLocation,
|
|
})
|
|
break
|
|
}
|
|
case "openai.code_interpreter": {
|
|
const args = codeInterpreterArgsSchema.parse(tool.args)
|
|
openaiTools.push({
|
|
type: "code_interpreter",
|
|
container:
|
|
args.container == null
|
|
? { type: "auto", file_ids: undefined }
|
|
: typeof args.container === "string"
|
|
? args.container
|
|
: { type: "auto", file_ids: args.container.fileIds },
|
|
})
|
|
break
|
|
}
|
|
case "openai.image_generation": {
|
|
const args = imageGenerationArgsSchema.parse(tool.args)
|
|
openaiTools.push({
|
|
type: "image_generation",
|
|
background: args.background,
|
|
input_fidelity: args.inputFidelity,
|
|
input_image_mask: args.inputImageMask
|
|
? {
|
|
file_id: args.inputImageMask.fileId,
|
|
image_url: args.inputImageMask.imageUrl,
|
|
}
|
|
: undefined,
|
|
model: args.model,
|
|
moderation: args.moderation,
|
|
partial_images: args.partialImages,
|
|
quality: args.quality,
|
|
output_compression: args.outputCompression,
|
|
output_format: args.outputFormat,
|
|
size: args.size,
|
|
})
|
|
break
|
|
}
|
|
}
|
|
break
|
|
}
|
|
default:
|
|
toolWarnings.push({ type: "unsupported", feature: "tool type" })
|
|
break
|
|
}
|
|
}
|
|
|
|
if (toolChoice == null) {
|
|
return { tools: openaiTools, toolChoice: undefined, toolWarnings }
|
|
}
|
|
|
|
const type = toolChoice.type
|
|
|
|
switch (type) {
|
|
case "auto":
|
|
case "none":
|
|
case "required":
|
|
return { tools: openaiTools, toolChoice: type, toolWarnings }
|
|
case "tool":
|
|
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"
|
|
? { type: toolChoice.toolName }
|
|
: { type: "function", name: toolChoice.toolName },
|
|
toolWarnings,
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck: never = type
|
|
throw new UnsupportedFunctionalityError({
|
|
functionality: `tool choice type: ${_exhaustiveCheck}`,
|
|
})
|
|
}
|
|
}
|
|
}
|