MCPcopy Create free account
hub / github.com/anomalyco/opencode / sanitizeOpenAISchema

Function sanitizeOpenAISchema

packages/opencode/src/provider/transform.ts:1336–1417  ·  view source on GitHub ↗
(value: unknown)

Source from the content-addressed store, hash-verified

1334
1335// Mirrors Codex's Rust JSON schema compatibility lowering for OpenAI tool schemas.
1336function sanitizeOpenAISchema(value: unknown): unknown {
1337 const types = ["string", "number", "boolean", "integer", "object", "array", "null"]
1338 const compositionKeys = ["anyOf", "oneOf", "allOf"]
1339
1340 // JSON Schema's boolean form (`true`/`false`) is unsupported by OpenAI tool schemas.
1341 if (typeof value === "boolean") return { type: "string" }
1342 if (Array.isArray(value)) return value.map(sanitizeOpenAISchema)
1343 if (!isPlainObject(value)) return value
1344
1345 const result: JsonRecord = {}
1346
1347 if (typeof value.$ref === "string") result.$ref = value.$ref
1348 if (typeof value.description === "string") result.description = value.description
1349 if ("const" in value) result.enum = [value.const]
1350 else if (Array.isArray(value.enum)) result.enum = value.enum
1351
1352 if (isPlainObject(value.properties)) {
1353 result.properties = Object.fromEntries(
1354 Object.entries(value.properties).map(([key, item]) => [key, sanitizeOpenAISchema(item)]),
1355 )
1356 }
1357
1358 if (Array.isArray(value.required)) {
1359 result.required = value.required.filter((item) => typeof item === "string")
1360 }
1361
1362 if ("items" in value) result.items = sanitizeOpenAISchema(value.items)
1363
1364 if ("additionalProperties" in value) {
1365 result.additionalProperties =
1366 typeof value.additionalProperties === "boolean"
1367 ? value.additionalProperties
1368 : sanitizeOpenAISchema(value.additionalProperties)
1369 }
1370
1371 for (const key of compositionKeys) {
1372 if (Array.isArray(value[key])) result[key] = value[key].map(sanitizeOpenAISchema)
1373 }
1374
1375 for (const key of ["$defs", "definitions"]) {
1376 if (isPlainObject(value[key])) {
1377 result[key] = Object.fromEntries(
1378 Object.entries(value[key]).map(([name, item]) => [name, sanitizeOpenAISchema(item)]),
1379 )
1380 }
1381 }
1382
1383 const schemaTypes =
1384 typeof value.type === "string"
1385 ? types.includes(value.type)
1386 ? [value.type]
1387 : []
1388 : Array.isArray(value.type)
1389 ? value.type.filter((item) => typeof item === "string" && types.includes(item))
1390 : []
1391
1392 if (schemaTypes.length === 0 && (typeof result.$ref === "string" || compositionKeys.some((key) => key in result))) {
1393 return result

Callers 1

schemaFunction · 0.85

Calls 1

isPlainObjectFunction · 0.70

Tested by

no test coverage detected