diff --git a/apps/mesh/src/api/llm-provider.ts b/apps/mesh/src/api/llm-provider.ts index 7ff908dadd..f5e03f81f7 100644 --- a/apps/mesh/src/api/llm-provider.ts +++ b/apps/mesh/src/api/llm-provider.ts @@ -134,20 +134,28 @@ export const createLLMProvider = (binding: LLMBindingClient): LLMProvider => { modelId, supportedUrls, doGenerate: async (options: LanguageModelV2CallOptions) => { - const response = await binding.LLM_DO_GENERATE({ + const result = await binding.LLM_DO_GENERATE({ callOptions: options as Parameters< LLMBindingClient["LLM_DO_GENERATE"] >[0]["callOptions"], modelId, }); return { - ...response, + ...result, usage: { - inputTokens: response.usage.inputTokens ?? undefined, - outputTokens: response.usage.outputTokens ?? undefined, - totalTokens: response.usage.totalTokens ?? undefined, - reasoningTokens: response.usage.reasoningTokens ?? undefined, + inputTokens: result.usage.inputTokens ?? undefined, + outputTokens: result.usage.outputTokens ?? undefined, + totalTokens: result.usage.totalTokens ?? undefined, + reasoningTokens: result.usage.reasoningTokens ?? undefined, }, + response: result.response + ? { + ...result.response, + timestamp: result.response.timestamp + ? new Date(result.response.timestamp) + : undefined, + } + : undefined, }; }, doStream: async (options: LanguageModelV2CallOptions) => { diff --git a/apps/mesh/src/api/utils/mcp.ts b/apps/mesh/src/api/utils/mcp.ts index 03a8daed6d..cb13373492 100644 --- a/apps/mesh/src/api/utils/mcp.ts +++ b/apps/mesh/src/api/utils/mcp.ts @@ -270,9 +270,11 @@ class McpServerBuilder { tools: this.tools.map((t) => ({ name: t.name, description: t.description ?? "", - inputSchema: z.toJSONSchema(t.inputSchema), + inputSchema: z.toJSONSchema(t.inputSchema, { + unrepresentable: "any", + }), outputSchema: t.outputSchema - ? z.toJSONSchema(t.outputSchema) + ? z.toJSONSchema(t.outputSchema, { unrepresentable: "any" }) : undefined, })), } as ListToolsResult; diff --git a/apps/mesh/src/gateway/strategy.ts b/apps/mesh/src/gateway/strategy.ts index c5a9582254..5a76b7688e 100644 --- a/apps/mesh/src/gateway/strategy.ts +++ b/apps/mesh/src/gateway/strategy.ts @@ -153,7 +153,9 @@ function createSearchTool(ctx: StrategyContext): ToolWithHandler { tool: { name: "GATEWAY_SEARCH_TOOLS", description: `Search for available tools by name or description. Returns tool names and brief descriptions without full schemas.${categoryList} Total tools: ${ctx.tools.length}.`, - inputSchema: z.toJSONSchema(inputSchema) as Tool["inputSchema"], + inputSchema: z.toJSONSchema(inputSchema, { + unrepresentable: "any", + }) as Tool["inputSchema"], }, handler: async (args) => { const parsed = inputSchema.safeParse(args); @@ -192,7 +194,9 @@ function createDescribeTool(ctx: StrategyContext): ToolWithHandler { name: "GATEWAY_DESCRIBE_TOOLS", description: "Get detailed schemas for specific tools. Call after searching to get full input/output schemas.", - inputSchema: z.toJSONSchema(inputSchema) as Tool["inputSchema"], + inputSchema: z.toJSONSchema(inputSchema, { + unrepresentable: "any", + }) as Tool["inputSchema"], }, handler: async (args) => { const parsed = inputSchema.safeParse(args); @@ -238,7 +242,9 @@ function createCallTool(ctx: StrategyContext): ToolWithHandler { name: "GATEWAY_CALL_TOOL", description: "Execute a tool by name. Use GATEWAY_DESCRIBE_TOOLS first to understand the input schema.", - inputSchema: z.toJSONSchema(inputSchema) as Tool["inputSchema"], + inputSchema: z.toJSONSchema(inputSchema, { + unrepresentable: "any", + }) as Tool["inputSchema"], }, handler: async (args) => { const parsed = inputSchema.safeParse(args); @@ -284,7 +290,9 @@ function createRunCodeTool(ctx: StrategyContext): ToolWithHandler { name: "GATEWAY_RUN_CODE", description: 'Run JavaScript code in a sandbox. Code must be an ES module that `export default`s an async function that receives (tools) as its first parameter. Use GATEWAY_DESCRIBE_TOOLS to understand the input/output schemas for a tool before calling it. Use `await tools.toolName(args)` or `await tools["tool-name"](args)` to call tools.', - inputSchema: z.toJSONSchema(inputSchema) as Tool["inputSchema"], + inputSchema: z.toJSONSchema(inputSchema, { + unrepresentable: "any", + }) as Tool["inputSchema"], }, handler: async (args) => { const parsed = inputSchema.safeParse(args); diff --git a/apps/mesh/src/web/utils/constants.ts b/apps/mesh/src/web/utils/constants.ts index bc8cbcff5d..409fc851fe 100644 --- a/apps/mesh/src/web/utils/constants.ts +++ b/apps/mesh/src/web/utils/constants.ts @@ -24,5 +24,5 @@ export type JsonSchema = { */ export const BaseCollectionJsonSchema: JsonSchema = z.toJSONSchema( BaseCollectionEntitySchema, - { target: "draft-07" }, + { target: "draft-07", unrepresentable: "any" }, ) as JsonSchema; diff --git a/packages/bindings/src/well-known/language-model.ts b/packages/bindings/src/well-known/language-model.ts index 2e6ee4c2e7..d20073e4bf 100644 --- a/packages/bindings/src/well-known/language-model.ts +++ b/packages/bindings/src/well-known/language-model.ts @@ -58,7 +58,7 @@ const TextPartSchema = z.object({ * File data can be Uint8Array (as base64 string), base64 encoded string, or URL string */ const DataContentSchema = z - .union([z.string(), z.instanceof(Uint8Array)]) + .string() .describe("File data as base64 encoded string, URL string, or Uint8Array"); /** @@ -336,7 +336,7 @@ export const LanguageModelCallOptionsSchema = z.object({ // Additional options headers: z - .record(z.string(), z.union([z.string(), z.undefined()])) + .record(z.string(), z.string().optional()) .optional() .describe("Additional HTTP headers to be sent with the request"), providerOptions: z @@ -378,14 +378,7 @@ export const LanguageModelGenerateOutputSchema = z.object({ totalTokens: z.number().optional(), reasoningTokens: z.number().optional(), }) - .passthrough() - .transform((val) => ({ - inputTokens: val.inputTokens, - outputTokens: val.outputTokens, - totalTokens: val.totalTokens, - reasoningTokens: val.reasoningTokens, - ...val, - })) + .loose() .describe("Usage information for the language model call"), // Provider metadata @@ -410,7 +403,7 @@ export const LanguageModelGenerateOutputSchema = z.object({ .object({ id: z.string().optional().describe("ID for the generated response"), timestamp: z - .date() + .string() .optional() .describe("Timestamp for the start of the generated response"), modelId: z diff --git a/packages/runtime/package.json b/packages/runtime/package.json index c6d5a9bfa7..67bac1e756 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@decocms/runtime", - "version": "1.1.0", + "version": "1.1.1", "type": "module", "scripts": { "check": "tsc --noEmit", diff --git a/packages/runtime/src/tools.ts b/packages/runtime/src/tools.ts index fcf64747ee..49de80eef8 100644 --- a/packages/runtime/src/tools.ts +++ b/packages/runtime/src/tools.ts @@ -389,7 +389,7 @@ const toolsFor = ({ configuration: { state: schema, scopes, onChange } = {}, }: CreateMCPServerOptions = {}): CreatedTool[] => { const jsonSchema = schema - ? z.toJSONSchema(schema) + ? z.toJSONSchema(schema, { unrepresentable: "any" }) : { type: "object", properties: {} }; const busProp = String(events?.bus ?? "EVENT_BUS"); return [