@copilotkit/shared 1.56.0 → 1.56.2-canary.pin-to-send
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/debug-event-envelope.d.cts +13 -0
- package/dist/debug-event-envelope.d.cts.map +1 -0
- package/dist/debug-event-envelope.d.mts +13 -0
- package/dist/debug-event-envelope.d.mts.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +28 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/standard-schema.cjs +4 -2
- package/dist/standard-schema.cjs.map +1 -1
- package/dist/standard-schema.d.cts +3 -2
- package/dist/standard-schema.d.cts.map +1 -1
- package/dist/standard-schema.d.mts +3 -2
- package/dist/standard-schema.d.mts.map +1 -1
- package/dist/standard-schema.mjs +4 -2
- package/dist/standard-schema.mjs.map +1 -1
- package/dist/utils/json-schema.cjs +23 -0
- package/dist/utils/json-schema.cjs.map +1 -1
- package/dist/utils/json-schema.d.cts.map +1 -1
- package/dist/utils/json-schema.d.mts.map +1 -1
- package/dist/utils/json-schema.mjs +23 -0
- package/dist/utils/json-schema.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/standard-schema.test.ts +92 -0
- package/src/debug-event-envelope.ts +9 -0
- package/src/index.ts +2 -0
- package/src/standard-schema.ts +9 -3
- package/src/utils/__tests__/json-schema.test.ts +137 -0
- package/src/utils/json-schema.ts +32 -0
|
@@ -22,9 +22,10 @@ interface SchemaToJsonSchemaOptions {
|
|
|
22
22
|
* Strategy:
|
|
23
23
|
* 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),
|
|
24
24
|
* call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.
|
|
25
|
-
* 2. If the schema
|
|
25
|
+
* 2. If the schema exposes a `toJSONSchema()` method (Zod v4), call it directly.
|
|
26
|
+
* 3. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the
|
|
26
27
|
* injected `zodToJsonSchema()` function.
|
|
27
|
-
*
|
|
28
|
+
* 4. Otherwise throw a descriptive error.
|
|
28
29
|
*/
|
|
29
30
|
declare function schemaToJsonSchema(schema: StandardSchemaV1, options?: SchemaToJsonSchemaOptions): Record<string, unknown>;
|
|
30
31
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema.d.mts","names":[],"sources":["../src/standard-schema.ts"],"mappings":";;;;AAWA;;;KAAY,iBAAA,MACV,CAAA,SAAU,gBAAA,iBAAiC,CAAA;AAAA,UAE5B,yBAAA;EAFf;;;;;EAQA,eAAA,IACE,MAAA,WACA,OAAA;IAAY,YAAA;EAAA,MACT,MAAA;AAAA;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"standard-schema.d.mts","names":[],"sources":["../src/standard-schema.ts"],"mappings":";;;;AAWA;;;KAAY,iBAAA,MACV,CAAA,SAAU,gBAAA,iBAAiC,CAAA;AAAA,UAE5B,yBAAA;EAFf;;;;;EAQA,eAAA,IACE,MAAA,WACA,OAAA;IAAY,YAAA;EAAA,MACT,MAAA;AAAA;;;;;;;;;AAgCP;;;iBAAgB,kBAAA,CACd,MAAA,EAAQ,gBAAA,EACR,OAAA,GAAU,yBAAA,GACT,MAAA"}
|
package/dist/standard-schema.mjs
CHANGED
|
@@ -12,12 +12,14 @@ function hasStandardJsonSchema(schema) {
|
|
|
12
12
|
* Strategy:
|
|
13
13
|
* 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),
|
|
14
14
|
* call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.
|
|
15
|
-
* 2. If the schema
|
|
15
|
+
* 2. If the schema exposes a `toJSONSchema()` method (Zod v4), call it directly.
|
|
16
|
+
* 3. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the
|
|
16
17
|
* injected `zodToJsonSchema()` function.
|
|
17
|
-
*
|
|
18
|
+
* 4. Otherwise throw a descriptive error.
|
|
18
19
|
*/
|
|
19
20
|
function schemaToJsonSchema(schema, options) {
|
|
20
21
|
if (hasStandardJsonSchema(schema)) return schema["~standard"].jsonSchema.input({ target: "draft-07" });
|
|
22
|
+
if (typeof schema.toJSONSchema === "function") return schema.toJSONSchema();
|
|
21
23
|
const vendor = schema["~standard"].vendor;
|
|
22
24
|
if (vendor === "zod" && options?.zodToJsonSchema) return options.zodToJsonSchema(schema, { $refStrategy: "none" });
|
|
23
25
|
throw new Error(`Cannot convert schema to JSON Schema. The schema (vendor: "${vendor}") does not implement Standard JSON Schema V1 and no zodToJsonSchema fallback is available. Use a library that supports Standard JSON Schema (e.g., Zod 3.24+, Valibot v1+, ArkType v2+) or pass a zodToJsonSchema function in options.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema.mjs","names":[],"sources":["../src/standard-schema.ts"],"sourcesContent":["import type {\n StandardSchemaV1,\n StandardJSONSchemaV1,\n} from \"@standard-schema/spec\";\n\nexport type { StandardSchemaV1, StandardJSONSchemaV1 };\n\n/**\n * Extract the Output type from a StandardSchemaV1 schema.\n * Replaces `z.infer<S>` for generic schema inference.\n */\nexport type InferSchemaOutput<S> =\n S extends StandardSchemaV1<any, infer O> ? O : never;\n\nexport interface SchemaToJsonSchemaOptions {\n /**\n * Injected `zodToJsonSchema` function so that `shared` does not depend on\n * `zod-to-json-schema`. Required when the schema is a Zod v3 schema that\n * does not implement Standard JSON Schema V1.\n */\n zodToJsonSchema?: (\n schema: unknown,\n options?: { $refStrategy?: string },\n ) => Record<string, unknown>;\n}\n\n/**\n * Check whether a schema implements the Standard JSON Schema V1 protocol.\n */\nfunction hasStandardJsonSchema(\n schema: StandardSchemaV1,\n): schema is StandardSchemaV1 & StandardJSONSchemaV1 {\n const props = schema[\"~standard\"];\n return (\n props != null &&\n typeof props === \"object\" &&\n \"jsonSchema\" in props &&\n props.jsonSchema != null &&\n typeof props.jsonSchema === \"object\" &&\n \"input\" in props.jsonSchema &&\n typeof props.jsonSchema.input === \"function\"\n );\n}\n\n/**\n * Convert any StandardSchemaV1-compatible schema to a JSON Schema object.\n *\n * Strategy:\n * 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),\n * call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.\n * 2. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the\n * injected `zodToJsonSchema()` function.\n *
|
|
1
|
+
{"version":3,"file":"standard-schema.mjs","names":[],"sources":["../src/standard-schema.ts"],"sourcesContent":["import type {\n StandardSchemaV1,\n StandardJSONSchemaV1,\n} from \"@standard-schema/spec\";\n\nexport type { StandardSchemaV1, StandardJSONSchemaV1 };\n\n/**\n * Extract the Output type from a StandardSchemaV1 schema.\n * Replaces `z.infer<S>` for generic schema inference.\n */\nexport type InferSchemaOutput<S> =\n S extends StandardSchemaV1<any, infer O> ? O : never;\n\nexport interface SchemaToJsonSchemaOptions {\n /**\n * Injected `zodToJsonSchema` function so that `shared` does not depend on\n * `zod-to-json-schema`. Required when the schema is a Zod v3 schema that\n * does not implement Standard JSON Schema V1.\n */\n zodToJsonSchema?: (\n schema: unknown,\n options?: { $refStrategy?: string },\n ) => Record<string, unknown>;\n}\n\n/**\n * Check whether a schema implements the Standard JSON Schema V1 protocol.\n */\nfunction hasStandardJsonSchema(\n schema: StandardSchemaV1,\n): schema is StandardSchemaV1 & StandardJSONSchemaV1 {\n const props = schema[\"~standard\"];\n return (\n props != null &&\n typeof props === \"object\" &&\n \"jsonSchema\" in props &&\n props.jsonSchema != null &&\n typeof props.jsonSchema === \"object\" &&\n \"input\" in props.jsonSchema &&\n typeof props.jsonSchema.input === \"function\"\n );\n}\n\n/**\n * Convert any StandardSchemaV1-compatible schema to a JSON Schema object.\n *\n * Strategy:\n * 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),\n * call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.\n * 2. If the schema exposes a `toJSONSchema()` method (Zod v4), call it directly.\n * 3. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the\n * injected `zodToJsonSchema()` function.\n * 4. Otherwise throw a descriptive error.\n */\nexport function schemaToJsonSchema(\n schema: StandardSchemaV1,\n options?: SchemaToJsonSchemaOptions,\n): Record<string, unknown> {\n // 1. Standard JSON Schema V1\n if (hasStandardJsonSchema(schema)) {\n return schema[\"~standard\"].jsonSchema.input({ target: \"draft-07\" });\n }\n\n // 2. Zod v4 native — exposes toJSONSchema() on the schema itself\n if (typeof (schema as any).toJSONSchema === \"function\") {\n return (schema as any).toJSONSchema() as Record<string, unknown>;\n }\n\n // 3. Zod v3 fallback\n const vendor = schema[\"~standard\"].vendor;\n if (vendor === \"zod\" && options?.zodToJsonSchema) {\n return options.zodToJsonSchema(schema, { $refStrategy: \"none\" });\n }\n\n throw new Error(\n `Cannot convert schema to JSON Schema. The schema (vendor: \"${vendor}\") does not implement Standard JSON Schema V1 ` +\n `and no zodToJsonSchema fallback is available. ` +\n `Use a library that supports Standard JSON Schema (e.g., Zod 3.24+, Valibot v1+, ArkType v2+) ` +\n `or pass a zodToJsonSchema function in options.`,\n );\n}\n"],"mappings":";;;;AA6BA,SAAS,sBACP,QACmD;CACnD,MAAM,QAAQ,OAAO;AACrB,QACE,SAAS,QACT,OAAO,UAAU,YACjB,gBAAgB,SAChB,MAAM,cAAc,QACpB,OAAO,MAAM,eAAe,YAC5B,WAAW,MAAM,cACjB,OAAO,MAAM,WAAW,UAAU;;;;;;;;;;;;;AAetC,SAAgB,mBACd,QACA,SACyB;AAEzB,KAAI,sBAAsB,OAAO,CAC/B,QAAO,OAAO,aAAa,WAAW,MAAM,EAAE,QAAQ,YAAY,CAAC;AAIrE,KAAI,OAAQ,OAAe,iBAAiB,WAC1C,QAAQ,OAAe,cAAc;CAIvC,MAAM,SAAS,OAAO,aAAa;AACnC,KAAI,WAAW,SAAS,SAAS,gBAC/B,QAAO,QAAQ,gBAAgB,QAAQ,EAAE,cAAc,QAAQ,CAAC;AAGlE,OAAM,IAAI,MACR,8DAA8D,OAAO,yOAItE"}
|
|
@@ -29,6 +29,16 @@ function convertJsonSchemaToParameter(name, schema, isRequired) {
|
|
|
29
29
|
description: schema.description
|
|
30
30
|
};
|
|
31
31
|
if (!isRequired) baseParameter.required = false;
|
|
32
|
+
if (Array.isArray(schema.type)) {
|
|
33
|
+
const types = schema.type;
|
|
34
|
+
const hasNull = types.includes("null");
|
|
35
|
+
const nonNullTypes = types.filter((t) => t !== "null");
|
|
36
|
+
const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : "string";
|
|
37
|
+
return convertJsonSchemaToParameter(name, {
|
|
38
|
+
...schema,
|
|
39
|
+
type: resolvedType
|
|
40
|
+
}, hasNull ? false : isRequired);
|
|
41
|
+
}
|
|
32
42
|
switch (schema.type) {
|
|
33
43
|
case "string": return {
|
|
34
44
|
...baseParameter,
|
|
@@ -139,6 +149,19 @@ function convertJsonSchemaToZodSchema(jsonSchema, required, definitions, visited
|
|
|
139
149
|
}
|
|
140
150
|
}
|
|
141
151
|
const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;
|
|
152
|
+
if (Array.isArray(jsonSchema.type)) {
|
|
153
|
+
const types = jsonSchema.type;
|
|
154
|
+
const hasNull = types.includes("null");
|
|
155
|
+
const nonNullTypes = types.filter((t) => t !== "null");
|
|
156
|
+
const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : "string";
|
|
157
|
+
const innerSchema = convertJsonSchemaToZodSchema({
|
|
158
|
+
...jsonSchema,
|
|
159
|
+
type: resolvedType
|
|
160
|
+
}, true, defs, visitedRefs);
|
|
161
|
+
let schema = hasNull ? zod.z.union([innerSchema, zod.z.null()]) : innerSchema;
|
|
162
|
+
if (jsonSchema.description) schema = schema.describe(jsonSchema.description);
|
|
163
|
+
return required ? schema : schema.optional();
|
|
164
|
+
}
|
|
142
165
|
const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;
|
|
143
166
|
if (Array.isArray(unionVariants) && unionVariants.length > 0) {
|
|
144
167
|
if (unionVariants.length === 1) return convertJsonSchemaToZodSchema(unionVariants[0], required, defs, visitedRefs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-schema.cjs","names":["z"],"sources":["../../src/utils/json-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Parameter } from \"../types\";\n\nexport type JSONSchemaString = {\n type: \"string\";\n description?: string;\n enum?: string[];\n};\n\nexport type JSONSchemaNumber = {\n type: \"number\";\n description?: string;\n};\n\nexport type JSONSchemaBoolean = {\n type: \"boolean\";\n description?: string;\n};\n\nexport type JSONSchemaObject = {\n type: \"object\";\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n};\n\nexport type JSONSchemaArray = {\n type: \"array\";\n items: JSONSchema;\n description?: string;\n};\n\nexport type JSONSchema =\n | JSONSchemaString\n | JSONSchemaNumber\n | JSONSchemaBoolean\n | JSONSchemaObject\n | JSONSchemaArray;\n\nexport function actionParametersToJsonSchema(\n actionParameters: Parameter[],\n): JSONSchema {\n // Create the parameters object based on the argumentAnnotations\n let parameters: { [key: string]: any } = {};\n for (let parameter of actionParameters || []) {\n parameters[parameter.name] = convertAttribute(parameter);\n }\n\n let requiredParameterNames: string[] = [];\n for (let arg of actionParameters || []) {\n if (arg.required !== false) {\n requiredParameterNames.push(arg.name);\n }\n }\n\n // Create the ChatCompletionFunctions object\n return {\n type: \"object\",\n properties: parameters,\n required: requiredParameterNames,\n };\n}\n\n// Convert JSONSchema to Parameter[]\nexport function jsonSchemaToActionParameters(\n jsonSchema: JSONSchema,\n): Parameter[] {\n if (jsonSchema.type !== \"object\" || !jsonSchema.properties) {\n return [];\n }\n\n const parameters: Parameter[] = [];\n const requiredFields = jsonSchema.required || [];\n\n for (const [name, schema] of Object.entries(jsonSchema.properties)) {\n const parameter = convertJsonSchemaToParameter(\n name,\n schema,\n requiredFields.includes(name),\n );\n parameters.push(parameter);\n }\n\n return parameters;\n}\n\n// Convert JSONSchema property to Parameter\nfunction convertJsonSchemaToParameter(\n name: string,\n schema: JSONSchema,\n isRequired: boolean,\n): Parameter {\n const baseParameter: Parameter = {\n name,\n description: schema.description,\n };\n\n if (!isRequired) {\n baseParameter.required = false;\n }\n\n switch (schema.type) {\n case \"string\":\n return {\n ...baseParameter,\n type: \"string\",\n ...(schema.enum && { enum: schema.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n ...baseParameter,\n type: schema.type,\n };\n case \"object\":\n if (schema.properties) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object\",\n attributes,\n };\n }\n return {\n ...baseParameter,\n type: \"object\",\n };\n case \"array\":\n if (schema.items.type === \"object\" && \"properties\" in schema.items) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.items.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.items.properties || {},\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object[]\",\n attributes,\n };\n } else if (schema.items.type === \"array\") {\n throw new Error(\"Nested arrays are not supported\");\n } else {\n return {\n ...baseParameter,\n type: `${schema.items.type}[]`,\n };\n }\n default:\n return {\n ...baseParameter,\n type: \"string\",\n };\n }\n}\n\nfunction convertAttribute(attribute: Parameter): JSONSchema {\n switch (attribute.type) {\n case \"string\":\n return {\n type: \"string\",\n description: attribute.description,\n ...(attribute.enum && { enum: attribute.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n type: attribute.type,\n description: attribute.description,\n };\n case \"object\":\n case \"object[]\":\n const properties = attribute.attributes?.reduce(\n (acc, attr) => {\n acc[attr.name] = convertAttribute(attr);\n return acc;\n },\n {} as Record<string, any>,\n );\n const required = attribute.attributes\n ?.filter((attr) => attr.required !== false)\n .map((attr) => attr.name);\n if (attribute.type === \"object[]\") {\n return {\n type: \"array\",\n items: {\n type: \"object\",\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n },\n description: attribute.description,\n };\n }\n return {\n type: \"object\",\n description: attribute.description,\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n };\n default:\n // Handle arrays of primitive types and undefined attribute.type\n if (attribute.type?.endsWith(\"[]\")) {\n const itemType = attribute.type.slice(0, -2);\n return {\n type: \"array\",\n items: { type: itemType as any },\n description: attribute.description,\n };\n }\n // Fallback for undefined type or any other unexpected type\n return {\n type: \"string\",\n description: attribute.description,\n };\n }\n}\n\nexport function convertJsonSchemaToZodSchema(\n jsonSchema: any,\n required: boolean,\n definitions?: Record<string, any>,\n visitedRefs?: Set<string>,\n): z.ZodSchema {\n // Resolve $ref references\n if (jsonSchema.$ref && definitions) {\n const refPath = jsonSchema.$ref.replace(\n /^#\\/\\$defs\\/|^#\\/definitions\\//,\n \"\",\n );\n\n // Detect circular $ref cycles\n const refs = visitedRefs ?? new Set<string>();\n if (refs.has(refPath)) {\n console.warn(\n `[CopilotKit] Circular $ref detected for \"${refPath}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n const resolved = definitions[refPath];\n if (resolved) {\n // Clone the set so sibling branches don't see each other's visited refs\n const nextRefs = new Set(refs);\n nextRefs.add(refPath);\n return convertJsonSchemaToZodSchema(\n resolved,\n required,\n definitions,\n nextRefs,\n );\n }\n }\n\n // Collect top-level definitions for $ref resolution\n const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;\n\n // Handle anyOf / oneOf as z.union\n const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;\n if (Array.isArray(unionVariants) && unionVariants.length > 0) {\n if (unionVariants.length === 1) {\n return convertJsonSchemaToZodSchema(\n unionVariants[0],\n required,\n defs,\n visitedRefs,\n );\n }\n const schemas = unionVariants.map((v: any) =>\n convertJsonSchemaToZodSchema(v, true, defs, visitedRefs),\n );\n let schema = z.union(\n schemas as [z.ZodSchema, z.ZodSchema, ...z.ZodSchema[]],\n );\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n if (jsonSchema.type === \"object\") {\n const spec: { [key: string]: z.ZodSchema } = {};\n\n if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) {\n return !required ? z.object(spec).optional() : z.object(spec);\n }\n\n for (const [key, value] of Object.entries(jsonSchema.properties)) {\n spec[key] = convertJsonSchemaToZodSchema(\n value,\n jsonSchema.required ? jsonSchema.required.includes(key) : false,\n defs,\n visitedRefs,\n );\n }\n let schema = z.object(spec).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"string\") {\n if (jsonSchema.enum && jsonSchema.enum.length > 0) {\n let schema = z\n .enum(jsonSchema.enum as [string, ...string[]])\n .describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n let schema = z.string().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"number\" || jsonSchema.type === \"integer\") {\n let schema = z.number().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"boolean\") {\n let schema = z.boolean().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"array\") {\n let itemSchema = convertJsonSchemaToZodSchema(\n jsonSchema.items,\n true,\n defs,\n visitedRefs,\n );\n let schema = z.array(itemSchema).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"null\") {\n let schema = z.null().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n\n // Fallback: accept any value rather than throwing\n console.warn(\n `[CopilotKit] Unsupported JSON schema type \"${jsonSchema.type ?? \"unknown\"}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n}\n\nexport function getZodParameters<T extends [] | Parameter[] | undefined>(\n parameters: T,\n): any {\n if (!parameters) return z.object({});\n const jsonParams = actionParametersToJsonSchema(parameters);\n return convertJsonSchemaToZodSchema(jsonParams, true);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"json-schema.cjs","names":["z"],"sources":["../../src/utils/json-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Parameter } from \"../types\";\n\nexport type JSONSchemaString = {\n type: \"string\";\n description?: string;\n enum?: string[];\n};\n\nexport type JSONSchemaNumber = {\n type: \"number\";\n description?: string;\n};\n\nexport type JSONSchemaBoolean = {\n type: \"boolean\";\n description?: string;\n};\n\nexport type JSONSchemaObject = {\n type: \"object\";\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n};\n\nexport type JSONSchemaArray = {\n type: \"array\";\n items: JSONSchema;\n description?: string;\n};\n\nexport type JSONSchema =\n | JSONSchemaString\n | JSONSchemaNumber\n | JSONSchemaBoolean\n | JSONSchemaObject\n | JSONSchemaArray;\n\nexport function actionParametersToJsonSchema(\n actionParameters: Parameter[],\n): JSONSchema {\n // Create the parameters object based on the argumentAnnotations\n let parameters: { [key: string]: any } = {};\n for (let parameter of actionParameters || []) {\n parameters[parameter.name] = convertAttribute(parameter);\n }\n\n let requiredParameterNames: string[] = [];\n for (let arg of actionParameters || []) {\n if (arg.required !== false) {\n requiredParameterNames.push(arg.name);\n }\n }\n\n // Create the ChatCompletionFunctions object\n return {\n type: \"object\",\n properties: parameters,\n required: requiredParameterNames,\n };\n}\n\n// Convert JSONSchema to Parameter[]\nexport function jsonSchemaToActionParameters(\n jsonSchema: JSONSchema,\n): Parameter[] {\n if (jsonSchema.type !== \"object\" || !jsonSchema.properties) {\n return [];\n }\n\n const parameters: Parameter[] = [];\n const requiredFields = jsonSchema.required || [];\n\n for (const [name, schema] of Object.entries(jsonSchema.properties)) {\n const parameter = convertJsonSchemaToParameter(\n name,\n schema,\n requiredFields.includes(name),\n );\n parameters.push(parameter);\n }\n\n return parameters;\n}\n\n// Convert JSONSchema property to Parameter\nfunction convertJsonSchemaToParameter(\n name: string,\n schema: JSONSchema,\n isRequired: boolean,\n): Parameter {\n const baseParameter: Parameter = {\n name,\n description: schema.description,\n };\n\n if (!isRequired) {\n baseParameter.required = false;\n }\n\n // Handle null-union types like [\"string\", \"null\"] by picking the non-null type\n if (Array.isArray(schema.type)) {\n const types = schema.type as string[];\n const hasNull = types.includes(\"null\");\n const nonNullTypes = types.filter((t: string) => t !== \"null\");\n const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : \"string\";\n return convertJsonSchemaToParameter(\n name,\n { ...schema, type: resolvedType } as JSONSchema,\n hasNull ? false : isRequired,\n );\n }\n\n switch (schema.type) {\n case \"string\":\n return {\n ...baseParameter,\n type: \"string\",\n ...(schema.enum && { enum: schema.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n ...baseParameter,\n type: schema.type,\n };\n case \"object\":\n if (schema.properties) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object\",\n attributes,\n };\n }\n return {\n ...baseParameter,\n type: \"object\",\n };\n case \"array\":\n if (schema.items.type === \"object\" && \"properties\" in schema.items) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.items.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.items.properties || {},\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object[]\",\n attributes,\n };\n } else if (schema.items.type === \"array\") {\n throw new Error(\"Nested arrays are not supported\");\n } else {\n return {\n ...baseParameter,\n type: `${schema.items.type}[]`,\n };\n }\n default:\n return {\n ...baseParameter,\n type: \"string\",\n };\n }\n}\n\nfunction convertAttribute(attribute: Parameter): JSONSchema {\n switch (attribute.type) {\n case \"string\":\n return {\n type: \"string\",\n description: attribute.description,\n ...(attribute.enum && { enum: attribute.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n type: attribute.type,\n description: attribute.description,\n };\n case \"object\":\n case \"object[]\":\n const properties = attribute.attributes?.reduce(\n (acc, attr) => {\n acc[attr.name] = convertAttribute(attr);\n return acc;\n },\n {} as Record<string, any>,\n );\n const required = attribute.attributes\n ?.filter((attr) => attr.required !== false)\n .map((attr) => attr.name);\n if (attribute.type === \"object[]\") {\n return {\n type: \"array\",\n items: {\n type: \"object\",\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n },\n description: attribute.description,\n };\n }\n return {\n type: \"object\",\n description: attribute.description,\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n };\n default:\n // Handle arrays of primitive types and undefined attribute.type\n if (attribute.type?.endsWith(\"[]\")) {\n const itemType = attribute.type.slice(0, -2);\n return {\n type: \"array\",\n items: { type: itemType as any },\n description: attribute.description,\n };\n }\n // Fallback for undefined type or any other unexpected type\n return {\n type: \"string\",\n description: attribute.description,\n };\n }\n}\n\nexport function convertJsonSchemaToZodSchema(\n jsonSchema: any,\n required: boolean,\n definitions?: Record<string, any>,\n visitedRefs?: Set<string>,\n): z.ZodSchema {\n // Resolve $ref references\n if (jsonSchema.$ref && definitions) {\n const refPath = jsonSchema.$ref.replace(\n /^#\\/\\$defs\\/|^#\\/definitions\\//,\n \"\",\n );\n\n // Detect circular $ref cycles\n const refs = visitedRefs ?? new Set<string>();\n if (refs.has(refPath)) {\n console.warn(\n `[CopilotKit] Circular $ref detected for \"${refPath}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n const resolved = definitions[refPath];\n if (resolved) {\n // Clone the set so sibling branches don't see each other's visited refs\n const nextRefs = new Set(refs);\n nextRefs.add(refPath);\n return convertJsonSchemaToZodSchema(\n resolved,\n required,\n definitions,\n nextRefs,\n );\n }\n }\n\n // Collect top-level definitions for $ref resolution\n const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;\n\n // Handle null-union types like [\"string\", \"null\"]\n if (Array.isArray(jsonSchema.type)) {\n const types = jsonSchema.type as string[];\n const hasNull = types.includes(\"null\");\n const nonNullTypes = types.filter((t: string) => t !== \"null\");\n const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : \"string\";\n const innerSchema = convertJsonSchemaToZodSchema(\n { ...jsonSchema, type: resolvedType },\n true,\n defs,\n visitedRefs,\n );\n let schema = hasNull ? z.union([innerSchema, z.null()]) : innerSchema;\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n // Handle anyOf / oneOf as z.union\n const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;\n if (Array.isArray(unionVariants) && unionVariants.length > 0) {\n if (unionVariants.length === 1) {\n return convertJsonSchemaToZodSchema(\n unionVariants[0],\n required,\n defs,\n visitedRefs,\n );\n }\n const schemas = unionVariants.map((v: any) =>\n convertJsonSchemaToZodSchema(v, true, defs, visitedRefs),\n );\n let schema = z.union(\n schemas as [z.ZodSchema, z.ZodSchema, ...z.ZodSchema[]],\n );\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n if (jsonSchema.type === \"object\") {\n const spec: { [key: string]: z.ZodSchema } = {};\n\n if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) {\n return !required ? z.object(spec).optional() : z.object(spec);\n }\n\n for (const [key, value] of Object.entries(jsonSchema.properties)) {\n spec[key] = convertJsonSchemaToZodSchema(\n value,\n jsonSchema.required ? jsonSchema.required.includes(key) : false,\n defs,\n visitedRefs,\n );\n }\n let schema = z.object(spec).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"string\") {\n if (jsonSchema.enum && jsonSchema.enum.length > 0) {\n let schema = z\n .enum(jsonSchema.enum as [string, ...string[]])\n .describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n let schema = z.string().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"number\" || jsonSchema.type === \"integer\") {\n let schema = z.number().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"boolean\") {\n let schema = z.boolean().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"array\") {\n let itemSchema = convertJsonSchemaToZodSchema(\n jsonSchema.items,\n true,\n defs,\n visitedRefs,\n );\n let schema = z.array(itemSchema).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"null\") {\n let schema = z.null().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n\n // Fallback: accept any value rather than throwing\n console.warn(\n `[CopilotKit] Unsupported JSON schema type \"${jsonSchema.type ?? \"unknown\"}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n}\n\nexport function getZodParameters<T extends [] | Parameter[] | undefined>(\n parameters: T,\n): any {\n if (!parameters) return z.object({});\n const jsonParams = actionParametersToJsonSchema(parameters);\n return convertJsonSchemaToZodSchema(jsonParams, true);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-schema.d.cts","names":[],"sources":["../../src/utils/json-schema.ts"],"mappings":";;;;KAGY,gBAAA;EACV,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,UAAA,GAAa,MAAA,SAAe,UAAA;EAC5B,QAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,WAAA;AAAA;AAAA,KAGU,UAAA,GACR,gBAAA,GACA,gBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA;AAAA,iBAEY,4BAAA,CACd,gBAAA,EAAkB,SAAA,KACjB,UAAA;AAAA,iBAuBa,4BAAA,CACd,UAAA,EAAY,UAAA,GACX,SAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"json-schema.d.cts","names":[],"sources":["../../src/utils/json-schema.ts"],"mappings":";;;;KAGY,gBAAA;EACV,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,UAAA,GAAa,MAAA,SAAe,UAAA;EAC5B,QAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,WAAA;AAAA;AAAA,KAGU,UAAA,GACR,gBAAA,GACA,gBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA;AAAA,iBAEY,4BAAA,CACd,gBAAA,EAAkB,SAAA,KACjB,UAAA;AAAA,iBAuBa,4BAAA,CACd,UAAA,EAAY,UAAA,GACX,SAAA;AAAA,iBA2La,4BAAA,CACd,UAAA,OACA,QAAA,WACA,WAAA,GAAc,MAAA,eACd,WAAA,GAAc,GAAA,WACb,CAAA,CAAE,SAAA;AAAA,iBAyIW,gBAAA,gBAAgC,SAAA,eAAA,CAC9C,UAAA,EAAY,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-schema.d.mts","names":[],"sources":["../../src/utils/json-schema.ts"],"mappings":";;;;KAGY,gBAAA;EACV,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,UAAA,GAAa,MAAA,SAAe,UAAA;EAC5B,QAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,WAAA;AAAA;AAAA,KAGU,UAAA,GACR,gBAAA,GACA,gBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA;AAAA,iBAEY,4BAAA,CACd,gBAAA,EAAkB,SAAA,KACjB,UAAA;AAAA,iBAuBa,4BAAA,CACd,UAAA,EAAY,UAAA,GACX,SAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"json-schema.d.mts","names":[],"sources":["../../src/utils/json-schema.ts"],"mappings":";;;;KAGY,gBAAA;EACV,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,UAAA,GAAa,MAAA,SAAe,UAAA;EAC5B,QAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,WAAA;AAAA;AAAA,KAGU,UAAA,GACR,gBAAA,GACA,gBAAA,GACA,iBAAA,GACA,gBAAA,GACA,eAAA;AAAA,iBAEY,4BAAA,CACd,gBAAA,EAAkB,SAAA,KACjB,UAAA;AAAA,iBAuBa,4BAAA,CACd,UAAA,EAAY,UAAA,GACX,SAAA;AAAA,iBA2La,4BAAA,CACd,UAAA,OACA,QAAA,WACA,WAAA,GAAc,MAAA,eACd,WAAA,GAAc,GAAA,WACb,CAAA,CAAE,SAAA;AAAA,iBAyIW,gBAAA,gBAAgC,SAAA,eAAA,CAC9C,UAAA,EAAY,CAAA"}
|
|
@@ -28,6 +28,16 @@ function convertJsonSchemaToParameter(name, schema, isRequired) {
|
|
|
28
28
|
description: schema.description
|
|
29
29
|
};
|
|
30
30
|
if (!isRequired) baseParameter.required = false;
|
|
31
|
+
if (Array.isArray(schema.type)) {
|
|
32
|
+
const types = schema.type;
|
|
33
|
+
const hasNull = types.includes("null");
|
|
34
|
+
const nonNullTypes = types.filter((t) => t !== "null");
|
|
35
|
+
const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : "string";
|
|
36
|
+
return convertJsonSchemaToParameter(name, {
|
|
37
|
+
...schema,
|
|
38
|
+
type: resolvedType
|
|
39
|
+
}, hasNull ? false : isRequired);
|
|
40
|
+
}
|
|
31
41
|
switch (schema.type) {
|
|
32
42
|
case "string": return {
|
|
33
43
|
...baseParameter,
|
|
@@ -138,6 +148,19 @@ function convertJsonSchemaToZodSchema(jsonSchema, required, definitions, visited
|
|
|
138
148
|
}
|
|
139
149
|
}
|
|
140
150
|
const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;
|
|
151
|
+
if (Array.isArray(jsonSchema.type)) {
|
|
152
|
+
const types = jsonSchema.type;
|
|
153
|
+
const hasNull = types.includes("null");
|
|
154
|
+
const nonNullTypes = types.filter((t) => t !== "null");
|
|
155
|
+
const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : "string";
|
|
156
|
+
const innerSchema = convertJsonSchemaToZodSchema({
|
|
157
|
+
...jsonSchema,
|
|
158
|
+
type: resolvedType
|
|
159
|
+
}, true, defs, visitedRefs);
|
|
160
|
+
let schema = hasNull ? z.union([innerSchema, z.null()]) : innerSchema;
|
|
161
|
+
if (jsonSchema.description) schema = schema.describe(jsonSchema.description);
|
|
162
|
+
return required ? schema : schema.optional();
|
|
163
|
+
}
|
|
141
164
|
const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;
|
|
142
165
|
if (Array.isArray(unionVariants) && unionVariants.length > 0) {
|
|
143
166
|
if (unionVariants.length === 1) return convertJsonSchemaToZodSchema(unionVariants[0], required, defs, visitedRefs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-schema.mjs","names":[],"sources":["../../src/utils/json-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Parameter } from \"../types\";\n\nexport type JSONSchemaString = {\n type: \"string\";\n description?: string;\n enum?: string[];\n};\n\nexport type JSONSchemaNumber = {\n type: \"number\";\n description?: string;\n};\n\nexport type JSONSchemaBoolean = {\n type: \"boolean\";\n description?: string;\n};\n\nexport type JSONSchemaObject = {\n type: \"object\";\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n};\n\nexport type JSONSchemaArray = {\n type: \"array\";\n items: JSONSchema;\n description?: string;\n};\n\nexport type JSONSchema =\n | JSONSchemaString\n | JSONSchemaNumber\n | JSONSchemaBoolean\n | JSONSchemaObject\n | JSONSchemaArray;\n\nexport function actionParametersToJsonSchema(\n actionParameters: Parameter[],\n): JSONSchema {\n // Create the parameters object based on the argumentAnnotations\n let parameters: { [key: string]: any } = {};\n for (let parameter of actionParameters || []) {\n parameters[parameter.name] = convertAttribute(parameter);\n }\n\n let requiredParameterNames: string[] = [];\n for (let arg of actionParameters || []) {\n if (arg.required !== false) {\n requiredParameterNames.push(arg.name);\n }\n }\n\n // Create the ChatCompletionFunctions object\n return {\n type: \"object\",\n properties: parameters,\n required: requiredParameterNames,\n };\n}\n\n// Convert JSONSchema to Parameter[]\nexport function jsonSchemaToActionParameters(\n jsonSchema: JSONSchema,\n): Parameter[] {\n if (jsonSchema.type !== \"object\" || !jsonSchema.properties) {\n return [];\n }\n\n const parameters: Parameter[] = [];\n const requiredFields = jsonSchema.required || [];\n\n for (const [name, schema] of Object.entries(jsonSchema.properties)) {\n const parameter = convertJsonSchemaToParameter(\n name,\n schema,\n requiredFields.includes(name),\n );\n parameters.push(parameter);\n }\n\n return parameters;\n}\n\n// Convert JSONSchema property to Parameter\nfunction convertJsonSchemaToParameter(\n name: string,\n schema: JSONSchema,\n isRequired: boolean,\n): Parameter {\n const baseParameter: Parameter = {\n name,\n description: schema.description,\n };\n\n if (!isRequired) {\n baseParameter.required = false;\n }\n\n switch (schema.type) {\n case \"string\":\n return {\n ...baseParameter,\n type: \"string\",\n ...(schema.enum && { enum: schema.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n ...baseParameter,\n type: schema.type,\n };\n case \"object\":\n if (schema.properties) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object\",\n attributes,\n };\n }\n return {\n ...baseParameter,\n type: \"object\",\n };\n case \"array\":\n if (schema.items.type === \"object\" && \"properties\" in schema.items) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.items.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.items.properties || {},\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object[]\",\n attributes,\n };\n } else if (schema.items.type === \"array\") {\n throw new Error(\"Nested arrays are not supported\");\n } else {\n return {\n ...baseParameter,\n type: `${schema.items.type}[]`,\n };\n }\n default:\n return {\n ...baseParameter,\n type: \"string\",\n };\n }\n}\n\nfunction convertAttribute(attribute: Parameter): JSONSchema {\n switch (attribute.type) {\n case \"string\":\n return {\n type: \"string\",\n description: attribute.description,\n ...(attribute.enum && { enum: attribute.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n type: attribute.type,\n description: attribute.description,\n };\n case \"object\":\n case \"object[]\":\n const properties = attribute.attributes?.reduce(\n (acc, attr) => {\n acc[attr.name] = convertAttribute(attr);\n return acc;\n },\n {} as Record<string, any>,\n );\n const required = attribute.attributes\n ?.filter((attr) => attr.required !== false)\n .map((attr) => attr.name);\n if (attribute.type === \"object[]\") {\n return {\n type: \"array\",\n items: {\n type: \"object\",\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n },\n description: attribute.description,\n };\n }\n return {\n type: \"object\",\n description: attribute.description,\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n };\n default:\n // Handle arrays of primitive types and undefined attribute.type\n if (attribute.type?.endsWith(\"[]\")) {\n const itemType = attribute.type.slice(0, -2);\n return {\n type: \"array\",\n items: { type: itemType as any },\n description: attribute.description,\n };\n }\n // Fallback for undefined type or any other unexpected type\n return {\n type: \"string\",\n description: attribute.description,\n };\n }\n}\n\nexport function convertJsonSchemaToZodSchema(\n jsonSchema: any,\n required: boolean,\n definitions?: Record<string, any>,\n visitedRefs?: Set<string>,\n): z.ZodSchema {\n // Resolve $ref references\n if (jsonSchema.$ref && definitions) {\n const refPath = jsonSchema.$ref.replace(\n /^#\\/\\$defs\\/|^#\\/definitions\\//,\n \"\",\n );\n\n // Detect circular $ref cycles\n const refs = visitedRefs ?? new Set<string>();\n if (refs.has(refPath)) {\n console.warn(\n `[CopilotKit] Circular $ref detected for \"${refPath}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n const resolved = definitions[refPath];\n if (resolved) {\n // Clone the set so sibling branches don't see each other's visited refs\n const nextRefs = new Set(refs);\n nextRefs.add(refPath);\n return convertJsonSchemaToZodSchema(\n resolved,\n required,\n definitions,\n nextRefs,\n );\n }\n }\n\n // Collect top-level definitions for $ref resolution\n const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;\n\n // Handle anyOf / oneOf as z.union\n const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;\n if (Array.isArray(unionVariants) && unionVariants.length > 0) {\n if (unionVariants.length === 1) {\n return convertJsonSchemaToZodSchema(\n unionVariants[0],\n required,\n defs,\n visitedRefs,\n );\n }\n const schemas = unionVariants.map((v: any) =>\n convertJsonSchemaToZodSchema(v, true, defs, visitedRefs),\n );\n let schema = z.union(\n schemas as [z.ZodSchema, z.ZodSchema, ...z.ZodSchema[]],\n );\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n if (jsonSchema.type === \"object\") {\n const spec: { [key: string]: z.ZodSchema } = {};\n\n if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) {\n return !required ? z.object(spec).optional() : z.object(spec);\n }\n\n for (const [key, value] of Object.entries(jsonSchema.properties)) {\n spec[key] = convertJsonSchemaToZodSchema(\n value,\n jsonSchema.required ? jsonSchema.required.includes(key) : false,\n defs,\n visitedRefs,\n );\n }\n let schema = z.object(spec).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"string\") {\n if (jsonSchema.enum && jsonSchema.enum.length > 0) {\n let schema = z\n .enum(jsonSchema.enum as [string, ...string[]])\n .describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n let schema = z.string().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"number\" || jsonSchema.type === \"integer\") {\n let schema = z.number().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"boolean\") {\n let schema = z.boolean().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"array\") {\n let itemSchema = convertJsonSchemaToZodSchema(\n jsonSchema.items,\n true,\n defs,\n visitedRefs,\n );\n let schema = z.array(itemSchema).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"null\") {\n let schema = z.null().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n\n // Fallback: accept any value rather than throwing\n console.warn(\n `[CopilotKit] Unsupported JSON schema type \"${jsonSchema.type ?? \"unknown\"}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n}\n\nexport function getZodParameters<T extends [] | Parameter[] | undefined>(\n parameters: T,\n): any {\n if (!parameters) return z.object({});\n const jsonParams = actionParametersToJsonSchema(parameters);\n return convertJsonSchemaToZodSchema(jsonParams, true);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"json-schema.mjs","names":[],"sources":["../../src/utils/json-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Parameter } from \"../types\";\n\nexport type JSONSchemaString = {\n type: \"string\";\n description?: string;\n enum?: string[];\n};\n\nexport type JSONSchemaNumber = {\n type: \"number\";\n description?: string;\n};\n\nexport type JSONSchemaBoolean = {\n type: \"boolean\";\n description?: string;\n};\n\nexport type JSONSchemaObject = {\n type: \"object\";\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n};\n\nexport type JSONSchemaArray = {\n type: \"array\";\n items: JSONSchema;\n description?: string;\n};\n\nexport type JSONSchema =\n | JSONSchemaString\n | JSONSchemaNumber\n | JSONSchemaBoolean\n | JSONSchemaObject\n | JSONSchemaArray;\n\nexport function actionParametersToJsonSchema(\n actionParameters: Parameter[],\n): JSONSchema {\n // Create the parameters object based on the argumentAnnotations\n let parameters: { [key: string]: any } = {};\n for (let parameter of actionParameters || []) {\n parameters[parameter.name] = convertAttribute(parameter);\n }\n\n let requiredParameterNames: string[] = [];\n for (let arg of actionParameters || []) {\n if (arg.required !== false) {\n requiredParameterNames.push(arg.name);\n }\n }\n\n // Create the ChatCompletionFunctions object\n return {\n type: \"object\",\n properties: parameters,\n required: requiredParameterNames,\n };\n}\n\n// Convert JSONSchema to Parameter[]\nexport function jsonSchemaToActionParameters(\n jsonSchema: JSONSchema,\n): Parameter[] {\n if (jsonSchema.type !== \"object\" || !jsonSchema.properties) {\n return [];\n }\n\n const parameters: Parameter[] = [];\n const requiredFields = jsonSchema.required || [];\n\n for (const [name, schema] of Object.entries(jsonSchema.properties)) {\n const parameter = convertJsonSchemaToParameter(\n name,\n schema,\n requiredFields.includes(name),\n );\n parameters.push(parameter);\n }\n\n return parameters;\n}\n\n// Convert JSONSchema property to Parameter\nfunction convertJsonSchemaToParameter(\n name: string,\n schema: JSONSchema,\n isRequired: boolean,\n): Parameter {\n const baseParameter: Parameter = {\n name,\n description: schema.description,\n };\n\n if (!isRequired) {\n baseParameter.required = false;\n }\n\n // Handle null-union types like [\"string\", \"null\"] by picking the non-null type\n if (Array.isArray(schema.type)) {\n const types = schema.type as string[];\n const hasNull = types.includes(\"null\");\n const nonNullTypes = types.filter((t: string) => t !== \"null\");\n const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : \"string\";\n return convertJsonSchemaToParameter(\n name,\n { ...schema, type: resolvedType } as JSONSchema,\n hasNull ? false : isRequired,\n );\n }\n\n switch (schema.type) {\n case \"string\":\n return {\n ...baseParameter,\n type: \"string\",\n ...(schema.enum && { enum: schema.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n ...baseParameter,\n type: schema.type,\n };\n case \"object\":\n if (schema.properties) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object\",\n attributes,\n };\n }\n return {\n ...baseParameter,\n type: \"object\",\n };\n case \"array\":\n if (schema.items.type === \"object\" && \"properties\" in schema.items) {\n const attributes: Parameter[] = [];\n const requiredFields = schema.items.required || [];\n\n for (const [propName, propSchema] of Object.entries(\n schema.items.properties || {},\n )) {\n attributes.push(\n convertJsonSchemaToParameter(\n propName,\n propSchema,\n requiredFields.includes(propName),\n ),\n );\n }\n\n return {\n ...baseParameter,\n type: \"object[]\",\n attributes,\n };\n } else if (schema.items.type === \"array\") {\n throw new Error(\"Nested arrays are not supported\");\n } else {\n return {\n ...baseParameter,\n type: `${schema.items.type}[]`,\n };\n }\n default:\n return {\n ...baseParameter,\n type: \"string\",\n };\n }\n}\n\nfunction convertAttribute(attribute: Parameter): JSONSchema {\n switch (attribute.type) {\n case \"string\":\n return {\n type: \"string\",\n description: attribute.description,\n ...(attribute.enum && { enum: attribute.enum }),\n };\n case \"number\":\n case \"boolean\":\n return {\n type: attribute.type,\n description: attribute.description,\n };\n case \"object\":\n case \"object[]\":\n const properties = attribute.attributes?.reduce(\n (acc, attr) => {\n acc[attr.name] = convertAttribute(attr);\n return acc;\n },\n {} as Record<string, any>,\n );\n const required = attribute.attributes\n ?.filter((attr) => attr.required !== false)\n .map((attr) => attr.name);\n if (attribute.type === \"object[]\") {\n return {\n type: \"array\",\n items: {\n type: \"object\",\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n },\n description: attribute.description,\n };\n }\n return {\n type: \"object\",\n description: attribute.description,\n ...(properties && { properties }),\n ...(required && required.length > 0 && { required }),\n };\n default:\n // Handle arrays of primitive types and undefined attribute.type\n if (attribute.type?.endsWith(\"[]\")) {\n const itemType = attribute.type.slice(0, -2);\n return {\n type: \"array\",\n items: { type: itemType as any },\n description: attribute.description,\n };\n }\n // Fallback for undefined type or any other unexpected type\n return {\n type: \"string\",\n description: attribute.description,\n };\n }\n}\n\nexport function convertJsonSchemaToZodSchema(\n jsonSchema: any,\n required: boolean,\n definitions?: Record<string, any>,\n visitedRefs?: Set<string>,\n): z.ZodSchema {\n // Resolve $ref references\n if (jsonSchema.$ref && definitions) {\n const refPath = jsonSchema.$ref.replace(\n /^#\\/\\$defs\\/|^#\\/definitions\\//,\n \"\",\n );\n\n // Detect circular $ref cycles\n const refs = visitedRefs ?? new Set<string>();\n if (refs.has(refPath)) {\n console.warn(\n `[CopilotKit] Circular $ref detected for \"${refPath}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n const resolved = definitions[refPath];\n if (resolved) {\n // Clone the set so sibling branches don't see each other's visited refs\n const nextRefs = new Set(refs);\n nextRefs.add(refPath);\n return convertJsonSchemaToZodSchema(\n resolved,\n required,\n definitions,\n nextRefs,\n );\n }\n }\n\n // Collect top-level definitions for $ref resolution\n const defs = definitions ?? jsonSchema.$defs ?? jsonSchema.definitions;\n\n // Handle null-union types like [\"string\", \"null\"]\n if (Array.isArray(jsonSchema.type)) {\n const types = jsonSchema.type as string[];\n const hasNull = types.includes(\"null\");\n const nonNullTypes = types.filter((t: string) => t !== \"null\");\n const resolvedType = nonNullTypes.length > 0 ? nonNullTypes[0] : \"string\";\n const innerSchema = convertJsonSchemaToZodSchema(\n { ...jsonSchema, type: resolvedType },\n true,\n defs,\n visitedRefs,\n );\n let schema = hasNull ? z.union([innerSchema, z.null()]) : innerSchema;\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n // Handle anyOf / oneOf as z.union\n const unionVariants = jsonSchema.anyOf ?? jsonSchema.oneOf;\n if (Array.isArray(unionVariants) && unionVariants.length > 0) {\n if (unionVariants.length === 1) {\n return convertJsonSchemaToZodSchema(\n unionVariants[0],\n required,\n defs,\n visitedRefs,\n );\n }\n const schemas = unionVariants.map((v: any) =>\n convertJsonSchemaToZodSchema(v, true, defs, visitedRefs),\n );\n let schema = z.union(\n schemas as [z.ZodSchema, z.ZodSchema, ...z.ZodSchema[]],\n );\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n }\n\n if (jsonSchema.type === \"object\") {\n const spec: { [key: string]: z.ZodSchema } = {};\n\n if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) {\n return !required ? z.object(spec).optional() : z.object(spec);\n }\n\n for (const [key, value] of Object.entries(jsonSchema.properties)) {\n spec[key] = convertJsonSchemaToZodSchema(\n value,\n jsonSchema.required ? jsonSchema.required.includes(key) : false,\n defs,\n visitedRefs,\n );\n }\n let schema = z.object(spec).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"string\") {\n if (jsonSchema.enum && jsonSchema.enum.length > 0) {\n let schema = z\n .enum(jsonSchema.enum as [string, ...string[]])\n .describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n let schema = z.string().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"number\" || jsonSchema.type === \"integer\") {\n let schema = z.number().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"boolean\") {\n let schema = z.boolean().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"array\") {\n let itemSchema = convertJsonSchemaToZodSchema(\n jsonSchema.items,\n true,\n defs,\n visitedRefs,\n );\n let schema = z.array(itemSchema).describe(jsonSchema.description);\n return required ? schema : schema.optional();\n } else if (jsonSchema.type === \"null\") {\n let schema = z.null().describe(jsonSchema.description);\n return required ? schema : schema.optional();\n }\n\n // Fallback: accept any value rather than throwing\n console.warn(\n `[CopilotKit] Unsupported JSON schema type \"${jsonSchema.type ?? \"unknown\"}\" — falling back to z.any()`,\n );\n let schema = z.any();\n if (jsonSchema.description) {\n schema = schema.describe(jsonSchema.description);\n }\n return required ? schema : schema.optional();\n}\n\nexport function getZodParameters<T extends [] | Parameter[] | undefined>(\n parameters: T,\n): any {\n if (!parameters) return z.object({});\n const jsonParams = actionParametersToJsonSchema(parameters);\n return convertJsonSchemaToZodSchema(jsonParams, true);\n}\n"],"mappings":";;;AAuCA,SAAgB,6BACd,kBACY;CAEZ,IAAI,aAAqC,EAAE;AAC3C,MAAK,IAAI,aAAa,oBAAoB,EAAE,CAC1C,YAAW,UAAU,QAAQ,iBAAiB,UAAU;CAG1D,IAAI,yBAAmC,EAAE;AACzC,MAAK,IAAI,OAAO,oBAAoB,EAAE,CACpC,KAAI,IAAI,aAAa,MACnB,wBAAuB,KAAK,IAAI,KAAK;AAKzC,QAAO;EACL,MAAM;EACN,YAAY;EACZ,UAAU;EACX;;AAIH,SAAgB,6BACd,YACa;AACb,KAAI,WAAW,SAAS,YAAY,CAAC,WAAW,WAC9C,QAAO,EAAE;CAGX,MAAM,aAA0B,EAAE;CAClC,MAAM,iBAAiB,WAAW,YAAY,EAAE;AAEhD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,WAAW,WAAW,EAAE;EAClE,MAAM,YAAY,6BAChB,MACA,QACA,eAAe,SAAS,KAAK,CAC9B;AACD,aAAW,KAAK,UAAU;;AAG5B,QAAO;;AAIT,SAAS,6BACP,MACA,QACA,YACW;CACX,MAAM,gBAA2B;EAC/B;EACA,aAAa,OAAO;EACrB;AAED,KAAI,CAAC,WACH,eAAc,WAAW;AAI3B,KAAI,MAAM,QAAQ,OAAO,KAAK,EAAE;EAC9B,MAAM,QAAQ,OAAO;EACrB,MAAM,UAAU,MAAM,SAAS,OAAO;EACtC,MAAM,eAAe,MAAM,QAAQ,MAAc,MAAM,OAAO;EAC9D,MAAM,eAAe,aAAa,SAAS,IAAI,aAAa,KAAK;AACjE,SAAO,6BACL,MACA;GAAE,GAAG;GAAQ,MAAM;GAAc,EACjC,UAAU,QAAQ,WACnB;;AAGH,SAAQ,OAAO,MAAf;EACE,KAAK,SACH,QAAO;GACL,GAAG;GACH,MAAM;GACN,GAAI,OAAO,QAAQ,EAAE,MAAM,OAAO,MAAM;GACzC;EACH,KAAK;EACL,KAAK,UACH,QAAO;GACL,GAAG;GACH,MAAM,OAAO;GACd;EACH,KAAK;AACH,OAAI,OAAO,YAAY;IACrB,MAAM,aAA0B,EAAE;IAClC,MAAM,iBAAiB,OAAO,YAAY,EAAE;AAE5C,SAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAC1C,OAAO,WACR,CACC,YAAW,KACT,6BACE,UACA,YACA,eAAe,SAAS,SAAS,CAClC,CACF;AAGH,WAAO;KACL,GAAG;KACH,MAAM;KACN;KACD;;AAEH,UAAO;IACL,GAAG;IACH,MAAM;IACP;EACH,KAAK,QACH,KAAI,OAAO,MAAM,SAAS,YAAY,gBAAgB,OAAO,OAAO;GAClE,MAAM,aAA0B,EAAE;GAClC,MAAM,iBAAiB,OAAO,MAAM,YAAY,EAAE;AAElD,QAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAC1C,OAAO,MAAM,cAAc,EAAE,CAC9B,CACC,YAAW,KACT,6BACE,UACA,YACA,eAAe,SAAS,SAAS,CAClC,CACF;AAGH,UAAO;IACL,GAAG;IACH,MAAM;IACN;IACD;aACQ,OAAO,MAAM,SAAS,QAC/B,OAAM,IAAI,MAAM,kCAAkC;MAElD,QAAO;GACL,GAAG;GACH,MAAM,GAAG,OAAO,MAAM,KAAK;GAC5B;EAEL,QACE,QAAO;GACL,GAAG;GACH,MAAM;GACP;;;AAIP,SAAS,iBAAiB,WAAkC;AAC1D,SAAQ,UAAU,MAAlB;EACE,KAAK,SACH,QAAO;GACL,MAAM;GACN,aAAa,UAAU;GACvB,GAAI,UAAU,QAAQ,EAAE,MAAM,UAAU,MAAM;GAC/C;EACH,KAAK;EACL,KAAK,UACH,QAAO;GACL,MAAM,UAAU;GAChB,aAAa,UAAU;GACxB;EACH,KAAK;EACL,KAAK;GACH,MAAM,aAAa,UAAU,YAAY,QACtC,KAAK,SAAS;AACb,QAAI,KAAK,QAAQ,iBAAiB,KAAK;AACvC,WAAO;MAET,EAAE,CACH;GACD,MAAM,WAAW,UAAU,YACvB,QAAQ,SAAS,KAAK,aAAa,MAAM,CAC1C,KAAK,SAAS,KAAK,KAAK;AAC3B,OAAI,UAAU,SAAS,WACrB,QAAO;IACL,MAAM;IACN,OAAO;KACL,MAAM;KACN,GAAI,cAAc,EAAE,YAAY;KAChC,GAAI,YAAY,SAAS,SAAS,KAAK,EAAE,UAAU;KACpD;IACD,aAAa,UAAU;IACxB;AAEH,UAAO;IACL,MAAM;IACN,aAAa,UAAU;IACvB,GAAI,cAAc,EAAE,YAAY;IAChC,GAAI,YAAY,SAAS,SAAS,KAAK,EAAE,UAAU;IACpD;EACH;AAEE,OAAI,UAAU,MAAM,SAAS,KAAK,CAEhC,QAAO;IACL,MAAM;IACN,OAAO,EAAE,MAHM,UAAU,KAAK,MAAM,GAAG,GAAG,EAGV;IAChC,aAAa,UAAU;IACxB;AAGH,UAAO;IACL,MAAM;IACN,aAAa,UAAU;IACxB;;;AAIP,SAAgB,6BACd,YACA,UACA,aACA,aACa;AAEb,KAAI,WAAW,QAAQ,aAAa;EAClC,MAAM,UAAU,WAAW,KAAK,QAC9B,kCACA,GACD;EAGD,MAAM,OAAO,+BAAe,IAAI,KAAa;AAC7C,MAAI,KAAK,IAAI,QAAQ,EAAE;AACrB,WAAQ,KACN,4CAA4C,QAAQ,6BACrD;GACD,IAAI,SAAS,EAAE,KAAK;AACpB,OAAI,WAAW,YACb,UAAS,OAAO,SAAS,WAAW,YAAY;AAElD,UAAO,WAAW,SAAS,OAAO,UAAU;;EAG9C,MAAM,WAAW,YAAY;AAC7B,MAAI,UAAU;GAEZ,MAAM,WAAW,IAAI,IAAI,KAAK;AAC9B,YAAS,IAAI,QAAQ;AACrB,UAAO,6BACL,UACA,UACA,aACA,SACD;;;CAKL,MAAM,OAAO,eAAe,WAAW,SAAS,WAAW;AAG3D,KAAI,MAAM,QAAQ,WAAW,KAAK,EAAE;EAClC,MAAM,QAAQ,WAAW;EACzB,MAAM,UAAU,MAAM,SAAS,OAAO;EACtC,MAAM,eAAe,MAAM,QAAQ,MAAc,MAAM,OAAO;EAC9D,MAAM,eAAe,aAAa,SAAS,IAAI,aAAa,KAAK;EACjE,MAAM,cAAc,6BAClB;GAAE,GAAG;GAAY,MAAM;GAAc,EACrC,MACA,MACA,YACD;EACD,IAAI,SAAS,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;AAC1D,MAAI,WAAW,YACb,UAAS,OAAO,SAAS,WAAW,YAAY;AAElD,SAAO,WAAW,SAAS,OAAO,UAAU;;CAI9C,MAAM,gBAAgB,WAAW,SAAS,WAAW;AACrD,KAAI,MAAM,QAAQ,cAAc,IAAI,cAAc,SAAS,GAAG;AAC5D,MAAI,cAAc,WAAW,EAC3B,QAAO,6BACL,cAAc,IACd,UACA,MACA,YACD;EAEH,MAAM,UAAU,cAAc,KAAK,MACjC,6BAA6B,GAAG,MAAM,MAAM,YAAY,CACzD;EACD,IAAI,SAAS,EAAE,MACb,QACD;AACD,MAAI,WAAW,YACb,UAAS,OAAO,SAAS,WAAW,YAAY;AAElD,SAAO,WAAW,SAAS,OAAO,UAAU;;AAG9C,KAAI,WAAW,SAAS,UAAU;EAChC,MAAM,OAAuC,EAAE;AAE/C,MAAI,CAAC,WAAW,cAAc,CAAC,OAAO,KAAK,WAAW,WAAW,CAAC,OAChE,QAAO,CAAC,WAAW,EAAE,OAAO,KAAK,CAAC,UAAU,GAAG,EAAE,OAAO,KAAK;AAG/D,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,WAAW,CAC9D,MAAK,OAAO,6BACV,OACA,WAAW,WAAW,WAAW,SAAS,SAAS,IAAI,GAAG,OAC1D,MACA,YACD;EAEH,IAAI,SAAS,EAAE,OAAO,KAAK,CAAC,SAAS,WAAW,YAAY;AAC5D,SAAO,WAAW,SAAS,OAAO,UAAU;YACnC,WAAW,SAAS,UAAU;AACvC,MAAI,WAAW,QAAQ,WAAW,KAAK,SAAS,GAAG;GACjD,IAAI,SAAS,EACV,KAAK,WAAW,KAA8B,CAC9C,SAAS,WAAW,YAAY;AACnC,UAAO,WAAW,SAAS,OAAO,UAAU;;EAE9C,IAAI,SAAS,EAAE,QAAQ,CAAC,SAAS,WAAW,YAAY;AACxD,SAAO,WAAW,SAAS,OAAO,UAAU;YACnC,WAAW,SAAS,YAAY,WAAW,SAAS,WAAW;EACxE,IAAI,SAAS,EAAE,QAAQ,CAAC,SAAS,WAAW,YAAY;AACxD,SAAO,WAAW,SAAS,OAAO,UAAU;YACnC,WAAW,SAAS,WAAW;EACxC,IAAI,SAAS,EAAE,SAAS,CAAC,SAAS,WAAW,YAAY;AACzD,SAAO,WAAW,SAAS,OAAO,UAAU;YACnC,WAAW,SAAS,SAAS;EACtC,IAAI,aAAa,6BACf,WAAW,OACX,MACA,MACA,YACD;EACD,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC,SAAS,WAAW,YAAY;AACjE,SAAO,WAAW,SAAS,OAAO,UAAU;YACnC,WAAW,SAAS,QAAQ;EACrC,IAAI,SAAS,EAAE,MAAM,CAAC,SAAS,WAAW,YAAY;AACtD,SAAO,WAAW,SAAS,OAAO,UAAU;;AAI9C,SAAQ,KACN,8CAA8C,WAAW,QAAQ,UAAU,6BAC5E;CACD,IAAI,SAAS,EAAE,KAAK;AACpB,KAAI,WAAW,YACb,UAAS,OAAO,SAAS,WAAW,YAAY;AAElD,QAAO,WAAW,SAAS,OAAO,UAAU;;AAG9C,SAAgB,iBACd,YACK;AACL,KAAI,CAAC,WAAY,QAAO,EAAE,OAAO,EAAE,CAAC;AAEpC,QAAO,6BADY,6BAA6B,WAAW,EACX,KAAK"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/shared",
|
|
3
|
-
"version": "1.56.
|
|
3
|
+
"version": "1.56.2-canary.pin-to-send",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@ag-ui/client": "0.0.52",
|
|
42
|
-
"@copilotkit/license-verifier": "0.0
|
|
42
|
+
"@copilotkit/license-verifier": "0.2.0",
|
|
43
43
|
"@segment/analytics-node": "^2.1.2",
|
|
44
44
|
"@standard-schema/spec": "^1.0.0",
|
|
45
45
|
"chalk": "4.1.2",
|
|
@@ -210,6 +210,98 @@ describe("schemaToJsonSchema", () => {
|
|
|
210
210
|
});
|
|
211
211
|
});
|
|
212
212
|
|
|
213
|
+
describe("Zod v4 schemas (via toJSONSchema method)", () => {
|
|
214
|
+
it("calls toJSONSchema() when the method exists on the schema", () => {
|
|
215
|
+
const expectedOutput = {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: { name: { type: "string" } },
|
|
218
|
+
required: ["name"],
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const mockZod4Schema: StandardSchemaV1 = {
|
|
222
|
+
"~standard": {
|
|
223
|
+
version: 1,
|
|
224
|
+
vendor: "zod",
|
|
225
|
+
validate: (value: unknown) => ({ value }),
|
|
226
|
+
},
|
|
227
|
+
toJSONSchema: () => expectedOutput,
|
|
228
|
+
} as any;
|
|
229
|
+
|
|
230
|
+
const result = schemaToJsonSchema(mockZod4Schema);
|
|
231
|
+
expect(result).toEqual(expectedOutput);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it("uses toJSONSchema() even without zodToJsonSchema option", () => {
|
|
235
|
+
const mockZod4Schema: StandardSchemaV1 = {
|
|
236
|
+
"~standard": {
|
|
237
|
+
version: 1,
|
|
238
|
+
vendor: "zod",
|
|
239
|
+
validate: (value: unknown) => ({ value }),
|
|
240
|
+
},
|
|
241
|
+
toJSONSchema: () => ({
|
|
242
|
+
type: "object",
|
|
243
|
+
properties: { city: { type: "string" } },
|
|
244
|
+
}),
|
|
245
|
+
} as any;
|
|
246
|
+
|
|
247
|
+
// No options passed — toJSONSchema() should still work
|
|
248
|
+
const result = schemaToJsonSchema(mockZod4Schema);
|
|
249
|
+
expect(result).toHaveProperty("properties.city.type", "string");
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("prefers toJSONSchema() over zodToJsonSchema fallback for Zod v4", () => {
|
|
253
|
+
const mockZod4Schema: StandardSchemaV1 = {
|
|
254
|
+
"~standard": {
|
|
255
|
+
version: 1,
|
|
256
|
+
vendor: "zod",
|
|
257
|
+
validate: (value: unknown) => ({ value }),
|
|
258
|
+
},
|
|
259
|
+
toJSONSchema: () => ({
|
|
260
|
+
type: "object",
|
|
261
|
+
properties: { fromNative: { type: "boolean" } },
|
|
262
|
+
}),
|
|
263
|
+
} as any;
|
|
264
|
+
|
|
265
|
+
const zodFallback = () => ({
|
|
266
|
+
type: "object",
|
|
267
|
+
properties: { fromFallback: { type: "boolean" } },
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const result = schemaToJsonSchema(mockZod4Schema, {
|
|
271
|
+
zodToJsonSchema: zodFallback,
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
expect(result).toHaveProperty("properties.fromNative");
|
|
275
|
+
expect(result).not.toHaveProperty("properties.fromFallback");
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("prefers ~standard.jsonSchema over toJSONSchema()", () => {
|
|
279
|
+
const mockSchema = {
|
|
280
|
+
"~standard": {
|
|
281
|
+
version: 1,
|
|
282
|
+
vendor: "zod",
|
|
283
|
+
validate: (value: unknown) => ({ value }),
|
|
284
|
+
jsonSchema: {
|
|
285
|
+
input: () => ({
|
|
286
|
+
type: "object",
|
|
287
|
+
properties: { fromStandard: { type: "boolean" } },
|
|
288
|
+
}),
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
toJSONSchema: () => ({
|
|
292
|
+
type: "object",
|
|
293
|
+
properties: { fromToJSONSchema: { type: "boolean" } },
|
|
294
|
+
}),
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const result = schemaToJsonSchema(mockSchema);
|
|
298
|
+
|
|
299
|
+
// Standard JSON Schema V1 should take priority
|
|
300
|
+
expect(result).toHaveProperty("properties.fromStandard");
|
|
301
|
+
expect(result).not.toHaveProperty("properties.fromToJSONSchema");
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
213
305
|
describe("Error handling", () => {
|
|
214
306
|
it("throws when schema has no jsonSchema support and no zodToJsonSchema", () => {
|
|
215
307
|
const mockSchema: StandardSchemaV1 = {
|
package/src/index.ts
CHANGED
package/src/standard-schema.ts
CHANGED
|
@@ -48,9 +48,10 @@ function hasStandardJsonSchema(
|
|
|
48
48
|
* Strategy:
|
|
49
49
|
* 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),
|
|
50
50
|
* call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.
|
|
51
|
-
* 2. If the schema
|
|
51
|
+
* 2. If the schema exposes a `toJSONSchema()` method (Zod v4), call it directly.
|
|
52
|
+
* 3. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the
|
|
52
53
|
* injected `zodToJsonSchema()` function.
|
|
53
|
-
*
|
|
54
|
+
* 4. Otherwise throw a descriptive error.
|
|
54
55
|
*/
|
|
55
56
|
export function schemaToJsonSchema(
|
|
56
57
|
schema: StandardSchemaV1,
|
|
@@ -61,7 +62,12 @@ export function schemaToJsonSchema(
|
|
|
61
62
|
return schema["~standard"].jsonSchema.input({ target: "draft-07" });
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
// 2. Zod
|
|
65
|
+
// 2. Zod v4 native — exposes toJSONSchema() on the schema itself
|
|
66
|
+
if (typeof (schema as any).toJSONSchema === "function") {
|
|
67
|
+
return (schema as any).toJSONSchema() as Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 3. Zod v3 fallback
|
|
65
71
|
const vendor = schema["~standard"].vendor;
|
|
66
72
|
if (vendor === "zod" && options?.zodToJsonSchema) {
|
|
67
73
|
return options.zodToJsonSchema(schema, { $refStrategy: "none" });
|
|
@@ -169,6 +169,46 @@ describe("convertJsonSchemaToZodSchema", () => {
|
|
|
169
169
|
expect(statusSchema._def.values).toEqual(["todo", "done"]);
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
+
it("should handle null-union type ['string', 'null'] as nullable", () => {
|
|
173
|
+
const jsonSchema = {
|
|
174
|
+
type: "object",
|
|
175
|
+
properties: {
|
|
176
|
+
nickname: {
|
|
177
|
+
type: ["string", "null"],
|
|
178
|
+
description: "Optional nickname",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
required: ["nickname"],
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const result = convertJsonSchemaToZodSchema(jsonSchema, true);
|
|
185
|
+
const shape = (result as z.ZodObject<any>).shape;
|
|
186
|
+
|
|
187
|
+
// The nickname field should accept both string and null
|
|
188
|
+
expect(shape.nickname.safeParse("hello").success).toBe(true);
|
|
189
|
+
expect(shape.nickname.safeParse(null).success).toBe(true);
|
|
190
|
+
expect(shape.nickname.safeParse(42).success).toBe(false);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("should handle null-union type ['number', 'null'] as nullable number", () => {
|
|
194
|
+
const jsonSchema = {
|
|
195
|
+
type: "object",
|
|
196
|
+
properties: {
|
|
197
|
+
score: {
|
|
198
|
+
type: ["number", "null"],
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
required: ["score"],
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const result = convertJsonSchemaToZodSchema(jsonSchema, true);
|
|
205
|
+
const shape = (result as z.ZodObject<any>).shape;
|
|
206
|
+
|
|
207
|
+
expect(shape.score.safeParse(42).success).toBe(true);
|
|
208
|
+
expect(shape.score.safeParse(null).success).toBe(true);
|
|
209
|
+
expect(shape.score.safeParse("hello").success).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
|
|
172
212
|
it("should handle edge case where JSON schema has no required properties", () => {
|
|
173
213
|
const jsonSchema = {
|
|
174
214
|
type: "object",
|
|
@@ -637,6 +677,103 @@ describe("jsonSchemaToActionParameters", () => {
|
|
|
637
677
|
);
|
|
638
678
|
});
|
|
639
679
|
|
|
680
|
+
it("should handle null-union type ['string', 'null'] as optional string", () => {
|
|
681
|
+
const jsonSchema = {
|
|
682
|
+
type: "object",
|
|
683
|
+
properties: {
|
|
684
|
+
nickname: {
|
|
685
|
+
type: ["string", "null"],
|
|
686
|
+
description: "Optional nickname",
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
required: ["nickname"],
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
const result = jsonSchemaToActionParameters(jsonSchema as any);
|
|
693
|
+
expect(result).toEqual([
|
|
694
|
+
{
|
|
695
|
+
name: "nickname",
|
|
696
|
+
type: "string",
|
|
697
|
+
description: "Optional nickname",
|
|
698
|
+
required: false,
|
|
699
|
+
},
|
|
700
|
+
]);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it("should handle null-union type ['object', 'null'] preserving properties", () => {
|
|
704
|
+
const jsonSchema = {
|
|
705
|
+
type: "object",
|
|
706
|
+
properties: {
|
|
707
|
+
metadata: {
|
|
708
|
+
type: ["object", "null"],
|
|
709
|
+
description: "Optional metadata",
|
|
710
|
+
properties: {
|
|
711
|
+
key: { type: "string" },
|
|
712
|
+
},
|
|
713
|
+
required: ["key"],
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
required: ["metadata"],
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
const result = jsonSchemaToActionParameters(jsonSchema as any);
|
|
720
|
+
expect(result).toEqual([
|
|
721
|
+
{
|
|
722
|
+
name: "metadata",
|
|
723
|
+
type: "object",
|
|
724
|
+
description: "Optional metadata",
|
|
725
|
+
required: false,
|
|
726
|
+
attributes: [{ name: "key", type: "string", description: undefined }],
|
|
727
|
+
},
|
|
728
|
+
]);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it("should handle null-union type when field is already optional", () => {
|
|
732
|
+
const jsonSchema = {
|
|
733
|
+
type: "object",
|
|
734
|
+
properties: {
|
|
735
|
+
nickname: {
|
|
736
|
+
type: ["string", "null"],
|
|
737
|
+
description: "Optional nickname",
|
|
738
|
+
},
|
|
739
|
+
},
|
|
740
|
+
// nickname is NOT in required
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
const result = jsonSchemaToActionParameters(jsonSchema as any);
|
|
744
|
+
expect(result).toEqual([
|
|
745
|
+
{
|
|
746
|
+
name: "nickname",
|
|
747
|
+
type: "string",
|
|
748
|
+
description: "Optional nickname",
|
|
749
|
+
required: false,
|
|
750
|
+
},
|
|
751
|
+
]);
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
it("should handle type array with only 'null' by falling back to string", () => {
|
|
755
|
+
const jsonSchema = {
|
|
756
|
+
type: "object",
|
|
757
|
+
properties: {
|
|
758
|
+
weird: {
|
|
759
|
+
type: ["null"],
|
|
760
|
+
description: "Null-only type",
|
|
761
|
+
},
|
|
762
|
+
},
|
|
763
|
+
required: ["weird"],
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
const result = jsonSchemaToActionParameters(jsonSchema as any);
|
|
767
|
+
expect(result).toEqual([
|
|
768
|
+
{
|
|
769
|
+
name: "weird",
|
|
770
|
+
type: "string",
|
|
771
|
+
description: "Null-only type",
|
|
772
|
+
required: false,
|
|
773
|
+
},
|
|
774
|
+
]);
|
|
775
|
+
});
|
|
776
|
+
|
|
640
777
|
it("should ensure round-trip conversion works", () => {
|
|
641
778
|
const originalParameters: Parameter[] = [
|
|
642
779
|
{ name: "name", type: "string", description: "User name" },
|