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

Function schema

packages/opencode/src/provider/transform.ts:1419–1559  ·  view source on GitHub ↗
(model: Provider.Model, schema: JSONSchema7)

Source from the content-addressed store, hash-verified

1417}
1418
1419export function schema(model: Provider.Model, schema: JSONSchema7): JSONSchema7 {
1420 /*
1421 if (["openai", "azure"].includes(providerID)) {
1422 if (schema.type === "object" && schema.properties) {
1423 for (const [key, value] of Object.entries(schema.properties)) {
1424 if (schema.required?.includes(key)) continue
1425 schema.properties[key] = {
1426 anyOf: [
1427 value as JSONSchema.JSONSchema,
1428 {
1429 type: "null",
1430 },
1431 ],
1432 }
1433 }
1434 }
1435 }
1436 */
1437
1438 if (model.api.npm === "@ai-sdk/openai" || model.api.npm === "@ai-sdk/azure") {
1439 schema = sanitizeOpenAISchema(schema) as JSONSchema7
1440 // Codex also applies lossy compaction above 4 KB; defer that until OpenCode needs the same schema budget.
1441 }
1442
1443 if (model.providerID === "moonshotai" || model.api.id.toLowerCase().includes("kimi")) {
1444 const sanitizeMoonshot = (obj: unknown): unknown => {
1445 if (obj === null || typeof obj !== "object") return obj
1446 if (Array.isArray(obj)) return obj.map(sanitizeMoonshot)
1447 // Moonshot expands $ref before validation and rejects sibling keywords like description on the same node.
1448 if ("$ref" in obj && typeof obj.$ref === "string") return { $ref: obj.$ref }
1449 const result = Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, sanitizeMoonshot(value)]))
1450 // MFJS does not support tuple-style `items` arrays; it requires one schema object for all array items.
1451 if (Array.isArray(result.items)) result.items = result.items[0] ?? {}
1452 return result
1453 }
1454
1455 const sanitized = sanitizeMoonshot(schema)
1456 if (typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized)) {
1457 schema = sanitized
1458 }
1459 }
1460
1461 // Convert integer enums to string enums for Google/Gemini
1462 if (model.providerID === "google" || model.api.id.includes("gemini")) {
1463 const isPlainObject = (node: unknown): node is Record<string, any> =>
1464 typeof node === "object" && node !== null && !Array.isArray(node)
1465 const hasCombiner = (node: unknown) =>
1466 isPlainObject(node) && (Array.isArray(node.anyOf) || Array.isArray(node.oneOf) || Array.isArray(node.allOf))
1467 const hasSchemaIntent = (node: unknown) => {
1468 if (!isPlainObject(node)) return false
1469 if (hasCombiner(node)) return true
1470 return [
1471 "type",
1472 "properties",
1473 "items",
1474 "prefixItems",
1475 "enum",
1476 "const",

Callers

nothing calls this directly

Calls 3

sanitizeOpenAISchemaFunction · 0.85
sanitizeMoonshotFunction · 0.85
sanitizeGeminiFunction · 0.85

Tested by

no test coverage detected