// Shared provider-tool helpers for plugin-owned schema compatibility rewrites. export { cleanSchemaForGemini, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, } from "../agents/schema/clean-for-gemini.js"; export const XAI_UNSUPPORTED_SCHEMA_KEYWORDS = new Set([ "minLength", "maxLength", "minItems", "maxItems", "minContains", "maxContains", ]); export function stripUnsupportedSchemaKeywords( schema: unknown, unsupportedKeywords: ReadonlySet, ): unknown { if (!schema || typeof schema !== "object") { return schema; } if (Array.isArray(schema)) { return schema.map((entry) => stripUnsupportedSchemaKeywords(entry, unsupportedKeywords)); } const obj = schema as Record; const cleaned: Record = {}; for (const [key, value] of Object.entries(obj)) { if (unsupportedKeywords.has(key)) { continue; } if (key === "properties" && value && typeof value === "object" && !Array.isArray(value)) { cleaned[key] = Object.fromEntries( Object.entries(value as Record).map(([childKey, childValue]) => [ childKey, stripUnsupportedSchemaKeywords(childValue, unsupportedKeywords), ]), ); continue; } if (key === "items" && value && typeof value === "object") { cleaned[key] = Array.isArray(value) ? value.map((entry) => stripUnsupportedSchemaKeywords(entry, unsupportedKeywords)) : stripUnsupportedSchemaKeywords(value, unsupportedKeywords); continue; } if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) { cleaned[key] = value.map((entry) => stripUnsupportedSchemaKeywords(entry, unsupportedKeywords), ); continue; } cleaned[key] = value; } return cleaned; } export function stripXaiUnsupportedKeywords(schema: unknown): unknown { return stripUnsupportedSchemaKeywords(schema, XAI_UNSUPPORTED_SCHEMA_KEYWORDS); } export function findUnsupportedSchemaKeywords( schema: unknown, path: string, unsupportedKeywords: ReadonlySet, ): string[] { if (!schema || typeof schema !== "object") { return []; } if (Array.isArray(schema)) { return schema.flatMap((item, index) => findUnsupportedSchemaKeywords(item, `${path}[${index}]`, unsupportedKeywords), ); } const record = schema as Record; const violations: string[] = []; const properties = record.properties && typeof record.properties === "object" && !Array.isArray(record.properties) ? (record.properties as Record) : undefined; if (properties) { for (const [key, value] of Object.entries(properties)) { violations.push( ...findUnsupportedSchemaKeywords(value, `${path}.properties.${key}`, unsupportedKeywords), ); } } for (const [key, value] of Object.entries(record)) { if (key === "properties") { continue; } if (unsupportedKeywords.has(key)) { violations.push(`${path}.${key}`); } if (value && typeof value === "object") { violations.push( ...findUnsupportedSchemaKeywords(value, `${path}.${key}`, unsupportedKeywords), ); } } return violations; }