@tanstack/ai 0.11.0 → 0.11.1
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.
|
@@ -13,18 +13,20 @@ function makeStructuredOutputCompatible(schema, originalRequired = []) {
|
|
|
13
13
|
const prop = properties[propName];
|
|
14
14
|
const wasOptional = !originalRequired.includes(propName);
|
|
15
15
|
if (prop.type === "object" && prop.properties) {
|
|
16
|
-
|
|
16
|
+
const transformed = makeStructuredOutputCompatible(
|
|
17
17
|
prop,
|
|
18
18
|
prop.required || []
|
|
19
19
|
);
|
|
20
|
+
properties[propName] = wasOptional ? { ...transformed, type: ["object", "null"] } : transformed;
|
|
20
21
|
} else if (prop.type === "array" && prop.items) {
|
|
21
|
-
|
|
22
|
+
const transformed = {
|
|
22
23
|
...prop,
|
|
23
24
|
items: makeStructuredOutputCompatible(
|
|
24
25
|
prop.items,
|
|
25
26
|
prop.items.required || []
|
|
26
27
|
)
|
|
27
28
|
};
|
|
29
|
+
properties[propName] = wasOptional ? { ...transformed, type: ["array", "null"] } : transformed;
|
|
28
30
|
} else if (wasOptional) {
|
|
29
31
|
if (prop.type && !Array.isArray(prop.type)) {
|
|
30
32
|
properties[propName] = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-converter.js","sources":["../../../../../src/activities/chat/tools/schema-converter.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n\nimport type {\n StandardJSONSchemaV1,\n StandardSchemaV1,\n} from '@standard-schema/spec'\nimport type { JSONSchema, SchemaInput } from '../../../types'\n\n/**\n * Check if a value is a Standard JSON Schema compliant schema.\n * Standard JSON Schema compliant libraries (Zod v4+, ArkType, Valibot with toStandardJsonSchema, etc.)\n * implement the '~standard' property with jsonSchema converter methods.\n */\nexport function isStandardJSONSchema(\n schema: unknown,\n): schema is StandardJSONSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof (schema as StandardJSONSchemaV1)['~standard'] === 'object' &&\n (schema as StandardJSONSchemaV1)['~standard'].version === 1 &&\n typeof (schema as StandardJSONSchemaV1)['~standard'].jsonSchema ===\n 'object' &&\n typeof (schema as StandardJSONSchemaV1)['~standard'].jsonSchema.input ===\n 'function'\n )\n}\n\n/**\n * Check if a value is a Standard Schema compliant schema (for validation).\n * Standard Schema compliant libraries implement the '~standard' property with a validate function.\n */\nexport function isStandardSchema(schema: unknown): schema is StandardSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof schema['~standard'] === 'object' &&\n schema !== null &&\n schema['~standard'] !== null &&\n 'version' in schema['~standard'] &&\n schema['~standard'].version === 1 &&\n 'validate' in schema['~standard'] &&\n typeof schema['~standard'].validate === 'function'\n )\n}\n\n/**\n * Transform a JSON schema to be compatible with OpenAI's structured output requirements.\n * OpenAI requires:\n * - All properties must be in the `required` array\n * - Optional fields should have null added to their type union\n * - additionalProperties must be false for objects\n *\n * @param schema - JSON schema to transform\n * @param originalRequired - Original required array (to know which fields were optional)\n * @returns Transformed schema compatible with OpenAI structured output\n */\nfunction makeStructuredOutputCompatible(\n schema: Record<string, any>,\n originalRequired: Array<string> = [],\n): Record<string, any> {\n const result = { ...schema }\n\n // Handle object types\n if (result.type === 'object' && result.properties) {\n const properties = { ...result.properties }\n const allPropertyNames = Object.keys(properties)\n\n // Transform each property\n for (const propName of allPropertyNames) {\n const prop = properties[propName]\n const wasOptional = !originalRequired.includes(propName)\n\n // Recursively transform nested objects/arrays\n if (prop.type === 'object' && prop.properties) {\n properties[propName] = makeStructuredOutputCompatible(\n prop,\n prop.required || [],\n )\n } else if (prop.type === 'array' && prop.items) {\n properties[propName] = {\n ...prop,\n items: makeStructuredOutputCompatible(\n prop.items,\n prop.items.required || [],\n ),\n }\n } else if (wasOptional) {\n // Make optional fields nullable by adding null to the type\n if (prop.type && !Array.isArray(prop.type)) {\n properties[propName] = {\n ...prop,\n type: [prop.type, 'null'],\n }\n } else if (Array.isArray(prop.type) && !prop.type.includes('null')) {\n properties[propName] = {\n ...prop,\n type: [...prop.type, 'null'],\n }\n }\n }\n }\n\n result.properties = properties\n // ALL properties must be required for OpenAI structured output\n result.required = allPropertyNames\n // additionalProperties must be false\n result.additionalProperties = false\n }\n\n // Handle array types with object items\n if (result.type === 'array' && result.items) {\n result.items = makeStructuredOutputCompatible(\n result.items,\n result.items.required || [],\n )\n }\n\n return result\n}\n\n/**\n * Options for schema conversion\n */\nexport interface ConvertSchemaOptions {\n /**\n * When true, transforms the schema to be compatible with OpenAI's structured output requirements:\n * - All properties are added to the `required` array\n * - Optional fields get null added to their type union\n * - additionalProperties is set to false for all objects\n *\n * @default false\n */\n forStructuredOutput?: boolean\n}\n\n/**\n * Converts a Standard JSON Schema compliant schema or plain JSONSchema to JSON Schema format\n * compatible with LLM providers.\n *\n * Supports any schema library that implements the Standard JSON Schema spec (v1):\n * - Zod v4+ (natively supports StandardJSONSchemaV1)\n * - ArkType (natively supports StandardJSONSchemaV1)\n * - Valibot (via `toStandardJsonSchema()` from `@valibot/to-json-schema`)\n *\n * If the input is already a plain JSONSchema object, it is returned as-is.\n *\n * @param schema - Standard JSON Schema compliant schema or plain JSONSchema object to convert\n * @param options - Conversion options\n * @returns JSON Schema object that can be sent to LLM providers\n *\n * @example\n * ```typescript\n * // Using Zod v4+ (natively supports Standard JSON Schema)\n * import * as z from 'zod';\n *\n * const zodSchema = z.object({\n * location: z.string().describe('City name'),\n * unit: z.enum(['celsius', 'fahrenheit']).optional()\n * });\n *\n * const jsonSchema = convertSchemaToJsonSchema(zodSchema);\n *\n * @example\n * // Using ArkType (natively supports Standard JSON Schema)\n * import { type } from 'arktype';\n *\n * const arkSchema = type({\n * location: 'string',\n * unit: \"'celsius' | 'fahrenheit'\"\n * });\n *\n * const jsonSchema = convertSchemaToJsonSchema(arkSchema);\n *\n * @example\n * // Using Valibot (via toStandardJsonSchema)\n * import * as v from 'valibot';\n * import { toStandardJsonSchema } from '@valibot/to-json-schema';\n *\n * const valibotSchema = toStandardJsonSchema(v.object({\n * location: v.string(),\n * unit: v.optional(v.picklist(['celsius', 'fahrenheit']))\n * }));\n *\n * const jsonSchema = convertSchemaToJsonSchema(valibotSchema);\n *\n * @example\n * // Using JSONSchema directly (passes through unchanged)\n * const rawSchema = {\n * type: 'object',\n * properties: { location: { type: 'string' } },\n * required: ['location']\n * };\n * const result = convertSchemaToJsonSchema(rawSchema);\n * ```\n */\nexport function convertSchemaToJsonSchema(\n schema: SchemaInput | undefined,\n options: ConvertSchemaOptions = {},\n): JSONSchema | undefined {\n if (!schema) return undefined\n\n const { forStructuredOutput = false } = options\n\n // If it's a Standard JSON Schema compliant schema, use the standard interface\n if (isStandardJSONSchema(schema)) {\n const jsonSchema = schema['~standard'].jsonSchema.input({\n target: 'draft-07',\n })\n\n let result = jsonSchema\n\n if (typeof result === 'object' && '$schema' in result) {\n // Remove $schema property as it's not needed for LLM providers\n const { $schema, ...rest } = result\n result = rest\n }\n\n // Ensure object schemas always have type: \"object\"\n\n if (typeof result === 'object') {\n // If it has properties (even empty), it should be an object type\n if ('properties' in result && !result.type) {\n result.type = 'object'\n }\n\n // Ensure properties exists for object types (even if empty)\n if (result.type === 'object' && !('properties' in result)) {\n result.properties = {}\n }\n\n // Ensure required exists for object types (even if empty array)\n if (result.type === 'object' && !('required' in result)) {\n result.required = []\n }\n\n // Apply structured output transformation if requested\n if (forStructuredOutput) {\n result = makeStructuredOutputCompatible(\n result,\n (result.required as Array<string>) || [],\n )\n }\n }\n\n return result as JSONSchema\n }\n\n // If it's not a Standard JSON Schema, assume it's already a JSONSchema and pass through\n // Still apply structured output transformation if requested\n\n if (forStructuredOutput && typeof schema === 'object') {\n return makeStructuredOutputCompatible(\n schema as Record<string, any>,\n ((schema as JSONSchema).required as Array<string>) || [],\n ) as JSONSchema\n }\n\n return schema as JSONSchema\n}\n\n/**\n * Validates data against a Standard Schema compliant schema.\n *\n * @param schema - Standard Schema compliant schema\n * @param data - Data to validate\n * @returns Validation result with success status, data or issues\n */\nexport async function validateWithStandardSchema<T>(\n schema: unknown,\n data: unknown,\n): Promise<\n | { success: true; data: T }\n | { success: false; issues: Array<{ message: string; path?: Array<string> }> }\n> {\n if (!isStandardSchema(schema)) {\n // If it's not a Standard Schema, just return the data as-is\n return { success: true, data: data as T }\n }\n\n const result = await schema['~standard'].validate(data)\n\n if (!result.issues) {\n return { success: true, data: result.value as T }\n }\n\n return {\n success: false,\n issues: result.issues.map((issue) => ({\n message: issue.message || 'Validation failed',\n path: issue.path?.map(String),\n })),\n }\n}\n\n/**\n * Synchronously validates data against a Standard Schema compliant schema.\n * Note: Some Standard Schema implementations may only support async validation.\n * In those cases, this function will throw.\n *\n * @param schema - Standard Schema compliant schema\n * @param data - Data to validate\n * @returns Parsed/validated data\n * @throws Error if validation fails or if the schema only supports async validation\n */\nexport function parseWithStandardSchema<T>(schema: unknown, data: unknown): T {\n if (!isStandardSchema(schema)) {\n // If it's not a Standard Schema, just return the data as-is\n return data as T\n }\n\n const result = schema['~standard'].validate(data)\n\n // Handle async result (Promise)\n if (result instanceof Promise) {\n throw new Error(\n 'Schema validation returned a Promise. Use validateWithStandardSchema for async validation.',\n )\n }\n // Standard Schema validation returns { value } for success or { issues } for failure\n if (!result.issues) {\n return result.value as T\n }\n\n // invalid validation, throw error with all issues\n const errorMessages = result.issues\n .map((issue) => issue.message || 'Validation failed')\n .join(', ')\n throw new Error(`Validation failed: ${errorMessages}`)\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema-converter.js","sources":["../../../../../src/activities/chat/tools/schema-converter.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n\nimport type {\n StandardJSONSchemaV1,\n StandardSchemaV1,\n} from '@standard-schema/spec'\nimport type { JSONSchema, SchemaInput } from '../../../types'\n\n/**\n * Check if a value is a Standard JSON Schema compliant schema.\n * Standard JSON Schema compliant libraries (Zod v4+, ArkType, Valibot with toStandardJsonSchema, etc.)\n * implement the '~standard' property with jsonSchema converter methods.\n */\nexport function isStandardJSONSchema(\n schema: unknown,\n): schema is StandardJSONSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof (schema as StandardJSONSchemaV1)['~standard'] === 'object' &&\n (schema as StandardJSONSchemaV1)['~standard'].version === 1 &&\n typeof (schema as StandardJSONSchemaV1)['~standard'].jsonSchema ===\n 'object' &&\n typeof (schema as StandardJSONSchemaV1)['~standard'].jsonSchema.input ===\n 'function'\n )\n}\n\n/**\n * Check if a value is a Standard Schema compliant schema (for validation).\n * Standard Schema compliant libraries implement the '~standard' property with a validate function.\n */\nexport function isStandardSchema(schema: unknown): schema is StandardSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof schema['~standard'] === 'object' &&\n schema !== null &&\n schema['~standard'] !== null &&\n 'version' in schema['~standard'] &&\n schema['~standard'].version === 1 &&\n 'validate' in schema['~standard'] &&\n typeof schema['~standard'].validate === 'function'\n )\n}\n\n/**\n * Transform a JSON schema to be compatible with OpenAI's structured output requirements.\n * OpenAI requires:\n * - All properties must be in the `required` array\n * - Optional fields should have null added to their type union\n * - additionalProperties must be false for objects\n *\n * @param schema - JSON schema to transform\n * @param originalRequired - Original required array (to know which fields were optional)\n * @returns Transformed schema compatible with OpenAI structured output\n */\nfunction makeStructuredOutputCompatible(\n schema: Record<string, any>,\n originalRequired: Array<string> = [],\n): Record<string, any> {\n const result = { ...schema }\n\n // Handle object types\n if (result.type === 'object' && result.properties) {\n const properties = { ...result.properties }\n const allPropertyNames = Object.keys(properties)\n\n // Transform each property\n for (const propName of allPropertyNames) {\n const prop = properties[propName]\n const wasOptional = !originalRequired.includes(propName)\n\n // Recursively transform nested objects/arrays\n if (prop.type === 'object' && prop.properties) {\n const transformed = makeStructuredOutputCompatible(\n prop,\n prop.required || [],\n )\n properties[propName] = wasOptional\n ? { ...transformed, type: ['object', 'null'] }\n : transformed\n } else if (prop.type === 'array' && prop.items) {\n const transformed = {\n ...prop,\n items: makeStructuredOutputCompatible(\n prop.items,\n prop.items.required || [],\n ),\n }\n properties[propName] = wasOptional\n ? { ...transformed, type: ['array', 'null'] }\n : transformed\n } else if (wasOptional) {\n // Make optional fields nullable by adding null to the type\n if (prop.type && !Array.isArray(prop.type)) {\n properties[propName] = {\n ...prop,\n type: [prop.type, 'null'],\n }\n } else if (Array.isArray(prop.type) && !prop.type.includes('null')) {\n properties[propName] = {\n ...prop,\n type: [...prop.type, 'null'],\n }\n }\n }\n }\n\n result.properties = properties\n // ALL properties must be required for OpenAI structured output\n result.required = allPropertyNames\n // additionalProperties must be false\n result.additionalProperties = false\n }\n\n // Handle array types with object items\n if (result.type === 'array' && result.items) {\n result.items = makeStructuredOutputCompatible(\n result.items,\n result.items.required || [],\n )\n }\n\n return result\n}\n\n/**\n * Options for schema conversion\n */\nexport interface ConvertSchemaOptions {\n /**\n * When true, transforms the schema to be compatible with OpenAI's structured output requirements:\n * - All properties are added to the `required` array\n * - Optional fields get null added to their type union\n * - additionalProperties is set to false for all objects\n *\n * @default false\n */\n forStructuredOutput?: boolean\n}\n\n/**\n * Converts a Standard JSON Schema compliant schema or plain JSONSchema to JSON Schema format\n * compatible with LLM providers.\n *\n * Supports any schema library that implements the Standard JSON Schema spec (v1):\n * - Zod v4+ (natively supports StandardJSONSchemaV1)\n * - ArkType (natively supports StandardJSONSchemaV1)\n * - Valibot (via `toStandardJsonSchema()` from `@valibot/to-json-schema`)\n *\n * If the input is already a plain JSONSchema object, it is returned as-is.\n *\n * @param schema - Standard JSON Schema compliant schema or plain JSONSchema object to convert\n * @param options - Conversion options\n * @returns JSON Schema object that can be sent to LLM providers\n *\n * @example\n * ```typescript\n * // Using Zod v4+ (natively supports Standard JSON Schema)\n * import * as z from 'zod';\n *\n * const zodSchema = z.object({\n * location: z.string().describe('City name'),\n * unit: z.enum(['celsius', 'fahrenheit']).optional()\n * });\n *\n * const jsonSchema = convertSchemaToJsonSchema(zodSchema);\n *\n * @example\n * // Using ArkType (natively supports Standard JSON Schema)\n * import { type } from 'arktype';\n *\n * const arkSchema = type({\n * location: 'string',\n * unit: \"'celsius' | 'fahrenheit'\"\n * });\n *\n * const jsonSchema = convertSchemaToJsonSchema(arkSchema);\n *\n * @example\n * // Using Valibot (via toStandardJsonSchema)\n * import * as v from 'valibot';\n * import { toStandardJsonSchema } from '@valibot/to-json-schema';\n *\n * const valibotSchema = toStandardJsonSchema(v.object({\n * location: v.string(),\n * unit: v.optional(v.picklist(['celsius', 'fahrenheit']))\n * }));\n *\n * const jsonSchema = convertSchemaToJsonSchema(valibotSchema);\n *\n * @example\n * // Using JSONSchema directly (passes through unchanged)\n * const rawSchema = {\n * type: 'object',\n * properties: { location: { type: 'string' } },\n * required: ['location']\n * };\n * const result = convertSchemaToJsonSchema(rawSchema);\n * ```\n */\nexport function convertSchemaToJsonSchema(\n schema: SchemaInput | undefined,\n options: ConvertSchemaOptions = {},\n): JSONSchema | undefined {\n if (!schema) return undefined\n\n const { forStructuredOutput = false } = options\n\n // If it's a Standard JSON Schema compliant schema, use the standard interface\n if (isStandardJSONSchema(schema)) {\n const jsonSchema = schema['~standard'].jsonSchema.input({\n target: 'draft-07',\n })\n\n let result = jsonSchema\n\n if (typeof result === 'object' && '$schema' in result) {\n // Remove $schema property as it's not needed for LLM providers\n const { $schema, ...rest } = result\n result = rest\n }\n\n // Ensure object schemas always have type: \"object\"\n\n if (typeof result === 'object') {\n // If it has properties (even empty), it should be an object type\n if ('properties' in result && !result.type) {\n result.type = 'object'\n }\n\n // Ensure properties exists for object types (even if empty)\n if (result.type === 'object' && !('properties' in result)) {\n result.properties = {}\n }\n\n // Ensure required exists for object types (even if empty array)\n if (result.type === 'object' && !('required' in result)) {\n result.required = []\n }\n\n // Apply structured output transformation if requested\n if (forStructuredOutput) {\n result = makeStructuredOutputCompatible(\n result,\n (result.required as Array<string>) || [],\n )\n }\n }\n\n return result as JSONSchema\n }\n\n // If it's not a Standard JSON Schema, assume it's already a JSONSchema and pass through\n // Still apply structured output transformation if requested\n\n if (forStructuredOutput && typeof schema === 'object') {\n return makeStructuredOutputCompatible(\n schema as Record<string, any>,\n ((schema as JSONSchema).required as Array<string>) || [],\n ) as JSONSchema\n }\n\n return schema as JSONSchema\n}\n\n/**\n * Validates data against a Standard Schema compliant schema.\n *\n * @param schema - Standard Schema compliant schema\n * @param data - Data to validate\n * @returns Validation result with success status, data or issues\n */\nexport async function validateWithStandardSchema<T>(\n schema: unknown,\n data: unknown,\n): Promise<\n | { success: true; data: T }\n | { success: false; issues: Array<{ message: string; path?: Array<string> }> }\n> {\n if (!isStandardSchema(schema)) {\n // If it's not a Standard Schema, just return the data as-is\n return { success: true, data: data as T }\n }\n\n const result = await schema['~standard'].validate(data)\n\n if (!result.issues) {\n return { success: true, data: result.value as T }\n }\n\n return {\n success: false,\n issues: result.issues.map((issue) => ({\n message: issue.message || 'Validation failed',\n path: issue.path?.map(String),\n })),\n }\n}\n\n/**\n * Synchronously validates data against a Standard Schema compliant schema.\n * Note: Some Standard Schema implementations may only support async validation.\n * In those cases, this function will throw.\n *\n * @param schema - Standard Schema compliant schema\n * @param data - Data to validate\n * @returns Parsed/validated data\n * @throws Error if validation fails or if the schema only supports async validation\n */\nexport function parseWithStandardSchema<T>(schema: unknown, data: unknown): T {\n if (!isStandardSchema(schema)) {\n // If it's not a Standard Schema, just return the data as-is\n return data as T\n }\n\n const result = schema['~standard'].validate(data)\n\n // Handle async result (Promise)\n if (result instanceof Promise) {\n throw new Error(\n 'Schema validation returned a Promise. Use validateWithStandardSchema for async validation.',\n )\n }\n // Standard Schema validation returns { value } for success or { issues } for failure\n if (!result.issues) {\n return result.value as T\n }\n\n // invalid validation, throw error with all issues\n const errorMessages = result.issues\n .map((issue) => issue.message || 'Validation failed')\n .join(', ')\n throw new Error(`Validation failed: ${errorMessages}`)\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Core TanStack AI library - Open source AI SDK",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@ag-ui/core": "0.0.49",
|
|
49
49
|
"partial-json": "^0.1.7",
|
|
50
|
-
"@tanstack/ai-event-client": "0.2.
|
|
50
|
+
"@tanstack/ai-event-client": "0.2.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@standard-schema/spec": "^1.1.0",
|
|
@@ -75,18 +75,24 @@ function makeStructuredOutputCompatible(
|
|
|
75
75
|
|
|
76
76
|
// Recursively transform nested objects/arrays
|
|
77
77
|
if (prop.type === 'object' && prop.properties) {
|
|
78
|
-
|
|
78
|
+
const transformed = makeStructuredOutputCompatible(
|
|
79
79
|
prop,
|
|
80
80
|
prop.required || [],
|
|
81
81
|
)
|
|
82
|
+
properties[propName] = wasOptional
|
|
83
|
+
? { ...transformed, type: ['object', 'null'] }
|
|
84
|
+
: transformed
|
|
82
85
|
} else if (prop.type === 'array' && prop.items) {
|
|
83
|
-
|
|
86
|
+
const transformed = {
|
|
84
87
|
...prop,
|
|
85
88
|
items: makeStructuredOutputCompatible(
|
|
86
89
|
prop.items,
|
|
87
90
|
prop.items.required || [],
|
|
88
91
|
),
|
|
89
92
|
}
|
|
93
|
+
properties[propName] = wasOptional
|
|
94
|
+
? { ...transformed, type: ['array', 'null'] }
|
|
95
|
+
: transformed
|
|
90
96
|
} else if (wasOptional) {
|
|
91
97
|
// Make optional fields nullable by adding null to the type
|
|
92
98
|
if (prop.type && !Array.isArray(prop.type)) {
|