diff --git a/examples/anthropic/index.tsx b/examples/anthropic/index.tsx index 80ca2002..e74e6c49 100644 --- a/examples/anthropic/index.tsx +++ b/examples/anthropic/index.tsx @@ -375,7 +375,7 @@ async function main() { | "multiStepTools" | "toolsWithStructuredOutput"; - const example: Example = "tools"; + const example: Example = "toolsWithStructuredOutput"; switch (example as Example) { case "basicCompletion": diff --git a/packages/gensx-anthropic/src/gsx-completion.tsx b/packages/gensx-anthropic/src/gsx-completion.tsx index 6236b91e..ef124df3 100644 --- a/packages/gensx-anthropic/src/gsx-completion.tsx +++ b/packages/gensx-anthropic/src/gsx-completion.tsx @@ -1,5 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +// Import Zod extensions for improved serialization +import "./utils/zod-extensions.js"; + import { Message, MessageCreateParamsNonStreaming, diff --git a/packages/gensx-anthropic/src/tools.tsx b/packages/gensx-anthropic/src/tools.tsx index 7a08c2b2..3f0acc6f 100644 --- a/packages/gensx-anthropic/src/tools.tsx +++ b/packages/gensx-anthropic/src/tools.tsx @@ -65,6 +65,14 @@ export class GSXTool> { return new GSXTool(params); } + toJSON(): Record { + return { + name: this.name, + description: this.description, + schema: this.definition.input_schema, + }; + } + public readonly name: string; public readonly description: string; public readonly schema: TSchema; diff --git a/packages/gensx-anthropic/src/utils/zod-extensions.ts b/packages/gensx-anthropic/src/utils/zod-extensions.ts new file mode 100644 index 00000000..69f4156c --- /dev/null +++ b/packages/gensx-anthropic/src/utils/zod-extensions.ts @@ -0,0 +1,30 @@ +/** + * Zod Schema Extensions + * + * This module provides extensions to Zod schemas that improve their + * serialization capabilities when used with GenSX's checkpoint system. + */ + +import { z } from "zod"; +import { zodToJsonSchema } from "zod-to-json-schema"; + +export function extendZodWithToJSON(): void { + // Use type assertion to check for toJSON method + const prototype = z.ZodSchema.prototype as unknown as { + toJSON?: () => Record; + }; + + // Only add the method once to avoid overriding + if (!prototype.toJSON) { + Object.defineProperty(z.ZodSchema.prototype, "toJSON", { + value: function (this: z.ZodType) { + return zodToJsonSchema(this); + }, + configurable: true, + writable: true, + }); + } +} + +// Execute the extension immediately when this module is imported +extendZodWithToJSON(); diff --git a/packages/gensx-openai/src/gsx-completion.tsx b/packages/gensx-openai/src/gsx-completion.tsx index 2e8bd8f8..2abfd5df 100644 --- a/packages/gensx-openai/src/gsx-completion.tsx +++ b/packages/gensx-openai/src/gsx-completion.tsx @@ -1,5 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +// Import Zod extensions for improved serialization +import "./utils/zod-extensions.js"; + import { Args, gsx } from "gensx"; import { ChatCompletion as ChatCompletionOutput, diff --git a/packages/gensx-openai/src/tools.tsx b/packages/gensx-openai/src/tools.tsx index 1c3f415e..a11fc0e0 100644 --- a/packages/gensx-openai/src/tools.tsx +++ b/packages/gensx-openai/src/tools.tsx @@ -65,6 +65,14 @@ export class GSXTool> { return new GSXTool(params); } + toJSON(): Record { + return { + name: this.name, + description: this.description, + schema: zodToJsonSchema(this.schema), + }; + } + public readonly name: string; public readonly description: string; public readonly schema: TSchema; diff --git a/packages/gensx-openai/src/utils/zod-extensions.ts b/packages/gensx-openai/src/utils/zod-extensions.ts new file mode 100644 index 00000000..69f4156c --- /dev/null +++ b/packages/gensx-openai/src/utils/zod-extensions.ts @@ -0,0 +1,30 @@ +/** + * Zod Schema Extensions + * + * This module provides extensions to Zod schemas that improve their + * serialization capabilities when used with GenSX's checkpoint system. + */ + +import { z } from "zod"; +import { zodToJsonSchema } from "zod-to-json-schema"; + +export function extendZodWithToJSON(): void { + // Use type assertion to check for toJSON method + const prototype = z.ZodSchema.prototype as unknown as { + toJSON?: () => Record; + }; + + // Only add the method once to avoid overriding + if (!prototype.toJSON) { + Object.defineProperty(z.ZodSchema.prototype, "toJSON", { + value: function (this: z.ZodType) { + return zodToJsonSchema(this); + }, + configurable: true, + writable: true, + }); + } +} + +// Execute the extension immediately when this module is imported +extendZodWithToJSON(); diff --git a/packages/gensx/src/checkpoint.ts b/packages/gensx/src/checkpoint.ts index c853e7b5..6e98be3d 100644 --- a/packages/gensx/src/checkpoint.ts +++ b/packages/gensx/src/checkpoint.ts @@ -591,6 +591,12 @@ export class CheckpointManager implements CheckpointWriter { if (Symbol.asyncIterator in value) return value; if (ArrayBuffer.isView(value)) return value; + // Check for toJSON method before doing regular object cloning + const objValue = value as { toJSON?: () => unknown }; + if (typeof objValue.toJSON === "function") { + return this.cloneValue(objValue.toJSON()); + } + // For regular objects, clone each property return Object.fromEntries( Object.entries(value).map(([key, val]) => [key, this.cloneValue(val)]),