* Flattens a schema with top-level anyOf/oneOf/allOf to a simple object schema. * This is needed because some providers (OpenRouter, Claude) don't support * schema composition keywords at the top level of tool input schemas. * * @param schema - The schema to flatten * @returns A flattened schem
(schema: Record<string, unknown>)
| 239 | * @returns A flattened schema without top-level composition keywords |
| 240 | */ |
| 241 | function flattenTopLevelComposition(schema: Record<string, unknown>): Record<string, unknown> { |
| 242 | const { anyOf, oneOf, allOf, ...rest } = schema |
| 243 | |
| 244 | // If no top-level composition keywords, return as-is |
| 245 | if (!anyOf && !oneOf && !allOf) { |
| 246 | return schema |
| 247 | } |
| 248 | |
| 249 | // Get the composition array to process (prefer anyOf, then oneOf, then allOf) |
| 250 | const compositionArray = (anyOf || oneOf || allOf) as Record<string, unknown>[] | undefined |
| 251 | if (!compositionArray || !Array.isArray(compositionArray) || compositionArray.length === 0) { |
| 252 | return schema |
| 253 | } |
| 254 | |
| 255 | // Find the first non-null object type variant to use as the base |
| 256 | // This preserves the most information while making the schema compatible |
| 257 | const objectVariant = compositionArray.find( |
| 258 | (variant) => |
| 259 | typeof variant === "object" && |
| 260 | variant !== null && |
| 261 | (variant.type === "object" || variant.properties !== undefined), |
| 262 | ) |
| 263 | |
| 264 | if (objectVariant) { |
| 265 | // Merge remaining properties with the object variant |
| 266 | return { ...rest, ...objectVariant } |
| 267 | } |
| 268 | |
| 269 | // If no object variant found, create a generic object schema |
| 270 | // This is a fallback that allows any object structure |
| 271 | return { |
| 272 | type: "object", |
| 273 | additionalProperties: false, |
| 274 | ...rest, |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | /** |
| 279 | * Normalizes a tool input JSON Schema to be compliant with JSON Schema draft 2020-12. |
no outgoing calls
no test coverage detected