feat: enhance tool conversion to support strict mode based on schema validation

This commit is contained in:
Daniel
2026-04-01 15:51:24 +02:00
committed by Kevin Codex
parent 8750f84464
commit 372ba31c17
2 changed files with 141 additions and 7 deletions

View File

@@ -300,13 +300,75 @@ export function convertToolsToResponsesTools(
): ResponsesTool[] {
return tools
.filter(tool => tool.name && tool.name !== 'ToolSearchTool')
.map(tool => ({
type: 'function',
name: tool.name ?? 'tool',
description: tool.description ?? '',
parameters: tool.input_schema ?? { type: 'object', properties: {} },
strict: true,
}))
.map(tool => {
const parameters = tool.input_schema ?? { type: 'object', properties: {} }
return {
type: 'function',
name: tool.name ?? 'tool',
description: tool.description ?? '',
parameters,
...(isStrictResponsesSchema(parameters) ? { strict: true } : {}),
}
})
}
function isStrictResponsesSchema(schema: unknown): boolean {
if (!schema || typeof schema !== 'object' || Array.isArray(schema)) {
return true
}
const record = schema as Record<string, unknown>
const type = record.type
if (type === 'object') {
const properties =
record.properties && typeof record.properties === 'object' && !Array.isArray(record.properties)
? (record.properties as Record<string, unknown>)
: {}
const propertyKeys = Object.keys(properties)
const required = Array.isArray(record.required)
? record.required.filter((value): value is string => typeof value === 'string')
: null
if (propertyKeys.length > 0) {
if (!required) return false
const requiredSet = new Set(required)
for (const key of propertyKeys) {
if (!requiredSet.has(key)) {
return false
}
}
}
for (const child of Object.values(properties)) {
if (!isStrictResponsesSchema(child)) {
return false
}
}
}
const combinators = ['anyOf', 'oneOf', 'allOf'] as const
for (const key of combinators) {
if (key in record) {
const value = record[key]
if (!Array.isArray(value) || value.some(item => !isStrictResponsesSchema(item))) {
return false
}
}
}
if ('items' in record) {
const items = record.items
if (Array.isArray(items)) {
return items.every(item => isStrictResponsesSchema(item))
}
return isStrictResponsesSchema(items)
}
return true
}
function convertToolChoice(toolChoice: unknown): unknown {