feat: Complete zCode CLI X with Telegram bot integration

- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
This commit is contained in:
admin
2026-05-05 09:01:26 +00:00
Unverified
parent 4a7035dd92
commit 875c7f9b91
24688 changed files with 3224957 additions and 221 deletions

View File

@@ -0,0 +1,31 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { Promisable, BetaRunnableTool } from "../../lib/tools/BetaRunnableTool.mjs";
import { BetaToolResultContentBlockParam } from "../../resources/beta.mjs";
import { AutoParseableBetaOutputFormat } from "../../lib/beta-parser.mjs";
type NoInfer<T> = T extends infer R ? R : never;
/**
* Creates a Tool with a provided JSON schema that can be passed
* to the `.toolRunner()` method. The schema is used to automatically validate
* the input arguments for the tool.
*/
export declare function betaTool<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(options: {
name: string;
inputSchema: Schema;
description: string;
run: (args: NoInfer<FromSchema<Schema>>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
}): BetaRunnableTool<NoInfer<FromSchema<Schema>>>;
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
*/
export declare function betaJSONSchemaOutputFormat<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(jsonSchema: Schema, options?: {
transform?: boolean;
}): AutoParseableBetaOutputFormat<NoInfer<FromSchema<Schema>>>;
export {};
//# sourceMappingURL=json-schema.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.d.mts","sourceRoot":"","sources":["../../src/helpers/beta/json-schema.ts"],"names":[],"mappings":"OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB;OACnD,EAAE,UAAU,EAAE,gBAAgB,EAAE;OAChC,EAAE,+BAA+B,EAAE;OACnC,EAAE,6BAA6B,EAAE;AAIxC,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAAE,OAAO,EAAE;IACxG,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;CACzG,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAehD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAEtE,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,6BAA6B,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAyB5D"}

View File

@@ -0,0 +1,31 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { Promisable, BetaRunnableTool } from "../../lib/tools/BetaRunnableTool.js";
import { BetaToolResultContentBlockParam } from "../../resources/beta.js";
import { AutoParseableBetaOutputFormat } from "../../lib/beta-parser.js";
type NoInfer<T> = T extends infer R ? R : never;
/**
* Creates a Tool with a provided JSON schema that can be passed
* to the `.toolRunner()` method. The schema is used to automatically validate
* the input arguments for the tool.
*/
export declare function betaTool<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(options: {
name: string;
inputSchema: Schema;
description: string;
run: (args: NoInfer<FromSchema<Schema>>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
}): BetaRunnableTool<NoInfer<FromSchema<Schema>>>;
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
*/
export declare function betaJSONSchemaOutputFormat<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(jsonSchema: Schema, options?: {
transform?: boolean;
}): AutoParseableBetaOutputFormat<NoInfer<FromSchema<Schema>>>;
export {};
//# sourceMappingURL=json-schema.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../src/helpers/beta/json-schema.ts"],"names":[],"mappings":"OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB;OACnD,EAAE,UAAU,EAAE,gBAAgB,EAAE;OAChC,EAAE,+BAA+B,EAAE;OACnC,EAAE,6BAA6B,EAAE;AAIxC,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAAE,OAAO,EAAE;IACxG,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;CACzG,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAehD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAEtE,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,6BAA6B,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAyB5D"}

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.betaTool = betaTool;
exports.betaJSONSchemaOutputFormat = betaJSONSchemaOutputFormat;
const __1 = require("../../index.js");
const transform_json_schema_1 = require("../../lib/transform-json-schema.js");
/**
* Creates a Tool with a provided JSON schema that can be passed
* to the `.toolRunner()` method. The schema is used to automatically validate
* the input arguments for the tool.
*/
function betaTool(options) {
if (options.inputSchema.type !== 'object') {
throw new Error(`JSON schema for tool "${options.name}" must be an object, but got ${options.inputSchema.type}`);
}
return {
type: 'custom',
name: options.name,
input_schema: options.inputSchema,
description: options.description,
run: options.run,
parse: (content) => content,
};
}
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
*/
function betaJSONSchemaOutputFormat(jsonSchema, options) {
if (jsonSchema.type !== 'object') {
throw new Error(`JSON schema for tool must be an object, but got ${jsonSchema.type}`);
}
const transform = options?.transform ?? true;
if (transform) {
// todo: doing this is arguably necessary, but it does change the schema the user passed in
// so I'm not sure how we should handle that
jsonSchema = (0, transform_json_schema_1.transformJSONSchema)(jsonSchema);
}
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
try {
return JSON.parse(content);
}
catch (error) {
throw new __1.AnthropicError(`Failed to parse structured output: ${error}`);
}
},
};
}
//# sourceMappingURL=json-schema.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../src/helpers/beta/json-schema.ts"],"names":[],"mappings":";;AAcA,4BAoBC;AAQD,gEAgCC;AAtED,sCAAuC;AACvC,8EAAsE;AAItE;;;;GAIG;AACH,SAAgB,QAAQ,CAAyE,OAKhG;IACC,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,IAAI,gCAAgC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAChG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,OAAO,CAAC,WAAW;QACjC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,OAA6B;KACpD,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,SAAgB,0BAA0B,CAGxC,UAAkB,EAClB,OAEC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,2FAA2F;QAC3F,4CAA4C;QAC5C,UAAU,GAAG,IAAA,2CAAmB,EAAC,UAAU,CAAW,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,kBAAc,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,52 @@
import { AnthropicError } from "../../index.mjs";
import { transformJSONSchema } from "../../lib/transform-json-schema.mjs";
/**
* Creates a Tool with a provided JSON schema that can be passed
* to the `.toolRunner()` method. The schema is used to automatically validate
* the input arguments for the tool.
*/
export function betaTool(options) {
if (options.inputSchema.type !== 'object') {
throw new Error(`JSON schema for tool "${options.name}" must be an object, but got ${options.inputSchema.type}`);
}
return {
type: 'custom',
name: options.name,
input_schema: options.inputSchema,
description: options.description,
run: options.run,
parse: (content) => content,
};
}
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
*/
export function betaJSONSchemaOutputFormat(jsonSchema, options) {
if (jsonSchema.type !== 'object') {
throw new Error(`JSON schema for tool must be an object, but got ${jsonSchema.type}`);
}
const transform = options?.transform ?? true;
if (transform) {
// todo: doing this is arguably necessary, but it does change the schema the user passed in
// so I'm not sure how we should handle that
jsonSchema = transformJSONSchema(jsonSchema);
}
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
try {
return JSON.parse(content);
}
catch (error) {
throw new AnthropicError(`Failed to parse structured output: ${error}`);
}
},
};
}
//# sourceMappingURL=json-schema.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.mjs","sourceRoot":"","sources":["../../src/helpers/beta/json-schema.ts"],"names":[],"mappings":"OAIO,EAAE,cAAc,EAAE;OAClB,EAAE,mBAAmB,EAAE;AAI9B;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAyE,OAKhG;IACC,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,IAAI,gCAAgC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAChG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,OAAO,CAAC,WAAW;QACjC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,OAA6B;KACpD,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAGxC,UAAkB,EAClB,OAEC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,2FAA2F;QAC3F,4CAA4C;QAC5C,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAW,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,303 @@
/**
* Helper functions for integrating MCP (Model Context Protocol) SDK types
* with the Anthropic SDK.
*
* These helpers reduce boilerplate when converting between MCP types and
* Anthropic API types. The interfaces defined here use TypeScript's structural
* typing to match MCP SDK types without requiring a direct dependency.
*/
import { BetaRunnableTool } from "../../lib/tools/BetaRunnableTool.mjs";
import { BetaTool, BetaMessageParam, BetaTextBlockParam, BetaImageBlockParam, BetaRequestDocumentBlock } from "../../resources/beta.mjs";
import { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader } from "../../lib/stainless-helper-header.mjs";
export { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader };
/**
* Represents an MCP tool definition.
* Matches the shape returned by `mcpClient.listTools()`.
*/
export interface MCPToolLike {
name: string;
description?: string | undefined;
inputSchema: {
type: 'object';
properties?: Record<string, unknown> | null | undefined;
required?: string[] | readonly string[] | null | undefined;
[key: string]: unknown;
};
}
/**
* Represents the result of calling an MCP tool.
* Matches the shape returned by `mcpClient.callTool()`.
*/
export interface MCPCallToolResultLike {
content: MCPToolResultContentLike[];
structuredContent?: object | undefined;
isError?: boolean | undefined;
}
export type MCPToolResultContentLike = MCPTextContentLike | MCPImageContentLike | MCPAudioContentLike | MCPEmbeddedResourceLike | MCPResourceLinkLike;
export interface MCPTextContentLike {
type: 'text';
text: string;
}
export interface MCPImageContentLike {
type: 'image';
data: string;
mimeType: string;
}
export interface MCPAudioContentLike {
type: 'audio';
data: string;
mimeType: string;
}
export interface MCPEmbeddedResourceLike {
type: 'resource';
resource: MCPResourceContentsLike;
}
export interface MCPResourceLinkLike {
type: 'resource_link';
uri: string;
name: string;
mimeType?: string | undefined;
}
/**
* Text resource contents from MCP.
*/
export interface MCPTextResourceContentsLike {
uri: string;
mimeType?: string | undefined;
text: string;
}
/**
* Blob (binary) resource contents from MCP.
*/
export interface MCPBlobResourceContentsLike {
uri: string;
mimeType?: string | undefined;
blob: string;
}
/**
* Resource contents - either text or blob.
* Matches `TextResourceContents | BlobResourceContents` from MCP SDK.
*/
export type MCPResourceContentsLike = MCPTextResourceContentsLike | MCPBlobResourceContentsLike;
/**
* Interface for an MCP client that can call tools.
* Matches the relevant methods of `Client` from `@modelcontextprotocol/sdk`.
*/
export interface MCPClientLike {
callTool(params: {
name: string;
arguments?: Record<string, unknown>;
}): Promise<MCPCallToolResultLike>;
}
/**
* Represents a message from an MCP prompt.
* Matches the shape returned by `mcpClient.getPrompt()`.
*/
export interface MCPPromptMessageLike {
role: 'user' | 'assistant';
content: MCPPromptContentLike;
}
export type MCPPromptContentLike = MCPTextContentLike | MCPImageContentLike | MCPAudioContentLike | MCPEmbeddedResourceLike | MCPResourceLinkLike;
/**
* Represents the contents of an MCP resource.
* Matches the shape returned by `mcpClient.readResource()`.
*/
export interface MCPReadResourceResultLike {
contents: MCPResourceContentsLike[];
}
/**
* Error thrown when an MCP value cannot be converted to a format supported by the Claude API.
*/
export declare class UnsupportedMCPValueError extends Error {
constructor(message: string);
}
/**
* Converts an MCP tool to a BetaRunnableTool for use with the Anthropic SDK's
* `toolRunner()` method.
*
* @param tool The MCP tool definition from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tool
* @param extraProps Additional Claude API properties to include in the tool definition
* @returns A runnable tool for use with `anthropic.beta.messages.toolRunner()`
* @throws {UnsupportedMCPValueError} When the tool returns unsupported content types
* @throws {UnsupportedMCPValueError} When the tool returns unsupported resource links
* @throws {UnsupportedMCPValueError} When the tool returns resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpTool } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const tools = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: tools.tools.map(tool => mcpTool(tool, mcpClient)),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export declare function mcpTool(tool: MCPToolLike, mcpClient: MCPClientLike, extraProps?: Partial<Omit<BetaTool, 'name' | 'description' | 'input_schema'>>): BetaRunnableTool<Record<string, unknown>>;
/**
* Converts an array of MCP tools to BetaRunnableTools.
*
* @param tools Array of MCP tool definitions from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tools
* @param extraProps Additional Claude API properties to include in each tool definition
* @returns An array of runnable tools for use with `anthropic.beta.messages.toolRunner()`
*
* @example
* ```ts
* const { tools } = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: mcpTools(tools, mcpClient),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export declare function mcpTools(tools: MCPToolLike[], mcpClient: MCPClientLike, extraProps?: Partial<Omit<BetaTool, 'name' | 'description' | 'input_schema'>>): BetaRunnableTool<Record<string, unknown>>[];
/**
* Converts an MCP prompt message to an Anthropic BetaMessageParam.
*
* @param mcpMessage The MCP prompt message from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns A message parameter for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When the message contains unsupported content types
* @throws {UnsupportedMCPValueError} When the message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When the message contains resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpMessage } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const prompt = await mcpClient.getPrompt({
* name: "example-prompt",
* arguments: { arg1: "value" },
* });
*
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: prompt.messages.map(msg => mcpMessage(msg)),
* });
* ```
*/
export declare function mcpMessage(mcpMessage: MCPPromptMessageLike, extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaMessageParam;
/**
* Converts an array of MCP prompt messages to Anthropic BetaMessageParams.
*
* @param messages Array of MCP prompt messages from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns An array of message parameters for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When any message contains unsupported content types
* @throws {UnsupportedMCPValueError} When any message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When any message contains resources with unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "example-prompt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: mcpMessages(messages),
* });
* ```
*/
export declare function mcpMessages(messages: MCPPromptMessageLike[], extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaMessageParam[];
/**
* Converts a single MCP prompt content item to an Anthropic content block.
*
* @param content The MCP content item (text, image, or embedded resource)
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block for use in a message's content array
* @throws {UnsupportedMCPValueError} When the content type is not supported (e.g., 'audio')
* @throws {UnsupportedMCPValueError} When resource links use non-http/https protocols
* @throws {UnsupportedMCPValueError} When resources have unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "my-prompt" });
* // If you need to mix MCP content with other content:
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [
* mcpContent(messages[0].content),
* { type: "text", text: "Additional context" },
* ],
* }],
* });
* ```
*/
export declare function mcpContent(content: MCPPromptContentLike, extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaTextBlockParam | BetaImageBlockParam | BetaRequestDocumentBlock;
/**
* Converts MCP resource contents to an Anthropic content block.
*
* This helper is useful when you have resource contents from `mcpClient.readResource()`
* and want to include them in a message or as a document source. It automatically
* finds the first resource with a supported MIME type.
*
* @param result The result from `mcpClient.readResource()`
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block
* @throws {UnsupportedMCPValueError} When contents array is empty or none have a supported MIME type
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToContent } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///example.txt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [mcpResourceToContent(resource)],
* }],
* });
* ```
*/
export declare function mcpResourceToContent(result: MCPReadResourceResultLike, extraProps?: Partial<Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaTextBlockParam | BetaImageBlockParam | BetaRequestDocumentBlock;
/**
* Converts an MCP resource to a File object suitable for uploading via `anthropic.beta.files.upload()`.
*
* @param result The result from `mcpClient.readResource()`
* @returns A File object for use with `anthropic.beta.files.upload()`
* @throws {UnsupportedMCPValueError} When contents array is empty
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToFile } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///document.pdf" });
*
* const uploaded = await anthropic.beta.files.upload({
* file: mcpResourceToFile(resource),
* });
* ```
*/
export declare function mcpResourceToFile(result: MCPReadResourceResultLike): File;
//# sourceMappingURL=mcp.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"mcp.d.mts","sourceRoot":"","sources":["../../src/helpers/beta/mcp.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,303 @@
/**
* Helper functions for integrating MCP (Model Context Protocol) SDK types
* with the Anthropic SDK.
*
* These helpers reduce boilerplate when converting between MCP types and
* Anthropic API types. The interfaces defined here use TypeScript's structural
* typing to match MCP SDK types without requiring a direct dependency.
*/
import { BetaRunnableTool } from "../../lib/tools/BetaRunnableTool.js";
import { BetaTool, BetaMessageParam, BetaTextBlockParam, BetaImageBlockParam, BetaRequestDocumentBlock } from "../../resources/beta.js";
import { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader } from "../../lib/stainless-helper-header.js";
export { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader };
/**
* Represents an MCP tool definition.
* Matches the shape returned by `mcpClient.listTools()`.
*/
export interface MCPToolLike {
name: string;
description?: string | undefined;
inputSchema: {
type: 'object';
properties?: Record<string, unknown> | null | undefined;
required?: string[] | readonly string[] | null | undefined;
[key: string]: unknown;
};
}
/**
* Represents the result of calling an MCP tool.
* Matches the shape returned by `mcpClient.callTool()`.
*/
export interface MCPCallToolResultLike {
content: MCPToolResultContentLike[];
structuredContent?: object | undefined;
isError?: boolean | undefined;
}
export type MCPToolResultContentLike = MCPTextContentLike | MCPImageContentLike | MCPAudioContentLike | MCPEmbeddedResourceLike | MCPResourceLinkLike;
export interface MCPTextContentLike {
type: 'text';
text: string;
}
export interface MCPImageContentLike {
type: 'image';
data: string;
mimeType: string;
}
export interface MCPAudioContentLike {
type: 'audio';
data: string;
mimeType: string;
}
export interface MCPEmbeddedResourceLike {
type: 'resource';
resource: MCPResourceContentsLike;
}
export interface MCPResourceLinkLike {
type: 'resource_link';
uri: string;
name: string;
mimeType?: string | undefined;
}
/**
* Text resource contents from MCP.
*/
export interface MCPTextResourceContentsLike {
uri: string;
mimeType?: string | undefined;
text: string;
}
/**
* Blob (binary) resource contents from MCP.
*/
export interface MCPBlobResourceContentsLike {
uri: string;
mimeType?: string | undefined;
blob: string;
}
/**
* Resource contents - either text or blob.
* Matches `TextResourceContents | BlobResourceContents` from MCP SDK.
*/
export type MCPResourceContentsLike = MCPTextResourceContentsLike | MCPBlobResourceContentsLike;
/**
* Interface for an MCP client that can call tools.
* Matches the relevant methods of `Client` from `@modelcontextprotocol/sdk`.
*/
export interface MCPClientLike {
callTool(params: {
name: string;
arguments?: Record<string, unknown>;
}): Promise<MCPCallToolResultLike>;
}
/**
* Represents a message from an MCP prompt.
* Matches the shape returned by `mcpClient.getPrompt()`.
*/
export interface MCPPromptMessageLike {
role: 'user' | 'assistant';
content: MCPPromptContentLike;
}
export type MCPPromptContentLike = MCPTextContentLike | MCPImageContentLike | MCPAudioContentLike | MCPEmbeddedResourceLike | MCPResourceLinkLike;
/**
* Represents the contents of an MCP resource.
* Matches the shape returned by `mcpClient.readResource()`.
*/
export interface MCPReadResourceResultLike {
contents: MCPResourceContentsLike[];
}
/**
* Error thrown when an MCP value cannot be converted to a format supported by the Claude API.
*/
export declare class UnsupportedMCPValueError extends Error {
constructor(message: string);
}
/**
* Converts an MCP tool to a BetaRunnableTool for use with the Anthropic SDK's
* `toolRunner()` method.
*
* @param tool The MCP tool definition from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tool
* @param extraProps Additional Claude API properties to include in the tool definition
* @returns A runnable tool for use with `anthropic.beta.messages.toolRunner()`
* @throws {UnsupportedMCPValueError} When the tool returns unsupported content types
* @throws {UnsupportedMCPValueError} When the tool returns unsupported resource links
* @throws {UnsupportedMCPValueError} When the tool returns resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpTool } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const tools = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: tools.tools.map(tool => mcpTool(tool, mcpClient)),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export declare function mcpTool(tool: MCPToolLike, mcpClient: MCPClientLike, extraProps?: Partial<Omit<BetaTool, 'name' | 'description' | 'input_schema'>>): BetaRunnableTool<Record<string, unknown>>;
/**
* Converts an array of MCP tools to BetaRunnableTools.
*
* @param tools Array of MCP tool definitions from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tools
* @param extraProps Additional Claude API properties to include in each tool definition
* @returns An array of runnable tools for use with `anthropic.beta.messages.toolRunner()`
*
* @example
* ```ts
* const { tools } = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: mcpTools(tools, mcpClient),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export declare function mcpTools(tools: MCPToolLike[], mcpClient: MCPClientLike, extraProps?: Partial<Omit<BetaTool, 'name' | 'description' | 'input_schema'>>): BetaRunnableTool<Record<string, unknown>>[];
/**
* Converts an MCP prompt message to an Anthropic BetaMessageParam.
*
* @param mcpMessage The MCP prompt message from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns A message parameter for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When the message contains unsupported content types
* @throws {UnsupportedMCPValueError} When the message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When the message contains resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpMessage } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const prompt = await mcpClient.getPrompt({
* name: "example-prompt",
* arguments: { arg1: "value" },
* });
*
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: prompt.messages.map(msg => mcpMessage(msg)),
* });
* ```
*/
export declare function mcpMessage(mcpMessage: MCPPromptMessageLike, extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaMessageParam;
/**
* Converts an array of MCP prompt messages to Anthropic BetaMessageParams.
*
* @param messages Array of MCP prompt messages from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns An array of message parameters for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When any message contains unsupported content types
* @throws {UnsupportedMCPValueError} When any message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When any message contains resources with unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "example-prompt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: mcpMessages(messages),
* });
* ```
*/
export declare function mcpMessages(messages: MCPPromptMessageLike[], extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaMessageParam[];
/**
* Converts a single MCP prompt content item to an Anthropic content block.
*
* @param content The MCP content item (text, image, or embedded resource)
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block for use in a message's content array
* @throws {UnsupportedMCPValueError} When the content type is not supported (e.g., 'audio')
* @throws {UnsupportedMCPValueError} When resource links use non-http/https protocols
* @throws {UnsupportedMCPValueError} When resources have unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "my-prompt" });
* // If you need to mix MCP content with other content:
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [
* mcpContent(messages[0].content),
* { type: "text", text: "Additional context" },
* ],
* }],
* });
* ```
*/
export declare function mcpContent(content: MCPPromptContentLike, extraProps?: Partial<Omit<BetaTextBlockParam, 'type' | 'text' | 'source'> & Omit<BetaImageBlockParam, 'type' | 'source'> & Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaTextBlockParam | BetaImageBlockParam | BetaRequestDocumentBlock;
/**
* Converts MCP resource contents to an Anthropic content block.
*
* This helper is useful when you have resource contents from `mcpClient.readResource()`
* and want to include them in a message or as a document source. It automatically
* finds the first resource with a supported MIME type.
*
* @param result The result from `mcpClient.readResource()`
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block
* @throws {UnsupportedMCPValueError} When contents array is empty or none have a supported MIME type
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToContent } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///example.txt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [mcpResourceToContent(resource)],
* }],
* });
* ```
*/
export declare function mcpResourceToContent(result: MCPReadResourceResultLike, extraProps?: Partial<Omit<BetaRequestDocumentBlock, 'type' | 'source'>>): BetaTextBlockParam | BetaImageBlockParam | BetaRequestDocumentBlock;
/**
* Converts an MCP resource to a File object suitable for uploading via `anthropic.beta.files.upload()`.
*
* @param result The result from `mcpClient.readResource()`
* @returns A File object for use with `anthropic.beta.files.upload()`
* @throws {UnsupportedMCPValueError} When contents array is empty
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToFile } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///document.pdf" });
*
* const uploaded = await anthropic.beta.files.upload({
* file: mcpResourceToFile(resource),
* });
* ```
*/
export declare function mcpResourceToFile(result: MCPReadResourceResultLike): File;
//# sourceMappingURL=mcp.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/helpers/beta/mcp.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,419 @@
"use strict";
/**
* Helper functions for integrating MCP (Model Context Protocol) SDK types
* with the Anthropic SDK.
*
* These helpers reduce boilerplate when converting between MCP types and
* Anthropic API types. The interfaces defined here use TypeScript's structural
* typing to match MCP SDK types without requiring a direct dependency.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnsupportedMCPValueError = exports.stainlessHelperHeader = exports.collectStainlessHelpers = exports.SDK_HELPER_SYMBOL = void 0;
exports.mcpTool = mcpTool;
exports.mcpTools = mcpTools;
exports.mcpMessage = mcpMessage;
exports.mcpMessages = mcpMessages;
exports.mcpContent = mcpContent;
exports.mcpResourceToContent = mcpResourceToContent;
exports.mcpResourceToFile = mcpResourceToFile;
const ToolError_1 = require("../../lib/tools/ToolError.js");
const stainless_helper_header_1 = require("../../lib/stainless-helper-header.js");
Object.defineProperty(exports, "SDK_HELPER_SYMBOL", { enumerable: true, get: function () { return stainless_helper_header_1.SDK_HELPER_SYMBOL; } });
Object.defineProperty(exports, "collectStainlessHelpers", { enumerable: true, get: function () { return stainless_helper_header_1.collectStainlessHelpers; } });
Object.defineProperty(exports, "stainlessHelperHeader", { enumerable: true, get: function () { return stainless_helper_header_1.stainlessHelperHeader; } });
const base64_1 = require("../../internal/utils/base64.js");
// -----------------------------------------------------------------------------
// Supported MIME types
// -----------------------------------------------------------------------------
const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
function isSupportedImageType(mimeType) {
return SUPPORTED_IMAGE_TYPES.includes(mimeType);
}
function isSupportedResourceMimeType(mimeType) {
return (!mimeType ||
mimeType.startsWith('text/') ||
mimeType === 'application/pdf' ||
isSupportedImageType(mimeType));
}
// -----------------------------------------------------------------------------
// Error classes
// -----------------------------------------------------------------------------
/**
* Error thrown when an MCP value cannot be converted to a format supported by the Claude API.
*/
class UnsupportedMCPValueError extends Error {
constructor(message) {
super(message);
this.name = 'UnsupportedMCPValueError';
}
}
exports.UnsupportedMCPValueError = UnsupportedMCPValueError;
// -----------------------------------------------------------------------------
// Helper functions
// -----------------------------------------------------------------------------
/**
* Converts an MCP tool to a BetaRunnableTool for use with the Anthropic SDK's
* `toolRunner()` method.
*
* @param tool The MCP tool definition from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tool
* @param extraProps Additional Claude API properties to include in the tool definition
* @returns A runnable tool for use with `anthropic.beta.messages.toolRunner()`
* @throws {UnsupportedMCPValueError} When the tool returns unsupported content types
* @throws {UnsupportedMCPValueError} When the tool returns unsupported resource links
* @throws {UnsupportedMCPValueError} When the tool returns resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpTool } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const tools = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: tools.tools.map(tool => mcpTool(tool, mcpClient)),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
function mcpTool(tool, mcpClient, extraProps) {
// Transform inputSchema to match BetaTool.InputSchema (convert undefined to null)
const inputSchema = {
...tool.inputSchema,
type: 'object',
properties: tool.inputSchema.properties ?? null,
required: tool.inputSchema.required ?? null,
};
const betaTool = {
name: tool.name,
input_schema: inputSchema,
...(tool.description !== undefined ? { description: tool.description } : {}),
...extraProps,
};
const runnableTool = {
...betaTool,
run: async (input) => {
const result = await mcpClient.callTool({
name: tool.name,
arguments: input,
});
if (result.isError) {
const content = result.content.map((item) => mcpContent(item));
throw new ToolError_1.ToolError(content);
}
// If content is empty but structuredContent is present, JSON encode it
// Spec: "For backwards compatibility, a tool that returns structured content SHOULD also return the serialized JSON in a TextContent block."
// meaning it's not required and cannot be assumed.
if (result.content.length === 0 &&
// Spec: "Structured content is returned as a JSON object in the structuredContent field of a result."
typeof result.structuredContent === 'object' &&
result.structuredContent !== null) {
return JSON.stringify(result.structuredContent);
}
return result.content.map((item) => mcpContent(item));
},
parse: (content) => content,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: 'mcpTool',
};
return runnableTool;
}
/**
* Converts an array of MCP tools to BetaRunnableTools.
*
* @param tools Array of MCP tool definitions from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tools
* @param extraProps Additional Claude API properties to include in each tool definition
* @returns An array of runnable tools for use with `anthropic.beta.messages.toolRunner()`
*
* @example
* ```ts
* const { tools } = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: mcpTools(tools, mcpClient),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
function mcpTools(tools, mcpClient, extraProps) {
return tools.map((tool) => mcpTool(tool, mcpClient, extraProps));
}
/**
* Converts an MCP prompt message to an Anthropic BetaMessageParam.
*
* @param mcpMessage The MCP prompt message from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns A message parameter for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When the message contains unsupported content types
* @throws {UnsupportedMCPValueError} When the message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When the message contains resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpMessage } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const prompt = await mcpClient.getPrompt({
* name: "example-prompt",
* arguments: { arg1: "value" },
* });
*
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: prompt.messages.map(msg => mcpMessage(msg)),
* });
* ```
*/
function mcpMessage(mcpMessage, extraProps) {
const message = {
role: mcpMessage.role,
content: [mcpContent(mcpMessage.content, extraProps)],
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: 'mcpMessage',
};
return message;
}
/**
* Converts an array of MCP prompt messages to Anthropic BetaMessageParams.
*
* @param messages Array of MCP prompt messages from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns An array of message parameters for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When any message contains unsupported content types
* @throws {UnsupportedMCPValueError} When any message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When any message contains resources with unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "example-prompt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: mcpMessages(messages),
* });
* ```
*/
function mcpMessages(messages, extraProps) {
return messages.map((message) => mcpMessage(message, extraProps));
}
/**
* Converts a single MCP prompt content item to an Anthropic content block.
*
* @param content The MCP content item (text, image, or embedded resource)
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block for use in a message's content array
* @throws {UnsupportedMCPValueError} When the content type is not supported (e.g., 'audio')
* @throws {UnsupportedMCPValueError} When resource links use non-http/https protocols
* @throws {UnsupportedMCPValueError} When resources have unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "my-prompt" });
* // If you need to mix MCP content with other content:
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [
* mcpContent(messages[0].content),
* { type: "text", text: "Additional context" },
* ],
* }],
* });
* ```
*/
function mcpContent(content, extraProps) {
switch (content.type) {
case 'text': {
const textBlock = {
type: 'text',
text: content.text,
...extraProps,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: 'mcpContent',
};
return textBlock;
}
case 'image': {
if (!isSupportedImageType(content.mimeType)) {
throw new UnsupportedMCPValueError(`Unsupported image MIME type: ${content.mimeType}`);
}
const imageBlock = {
type: 'image',
source: {
type: 'base64',
data: content.data,
media_type: content.mimeType,
},
...extraProps,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: 'mcpContent',
};
return imageBlock;
}
case 'resource':
return mcpResourceContentToContentBlock(content.resource, extraProps, 'mcpContent');
case 'resource_link':
case 'audio':
throw new UnsupportedMCPValueError(`Unsupported MCP content type: ${content.type}`);
default:
// This should never happen as we handle all MCPPromptContentLike types
content;
throw new UnsupportedMCPValueError(`Unsupported MCP content type: ${content.type}`);
}
}
/**
* Converts a single MCP resource contents item to an Anthropic content block.
*/
function mcpResourceContentToContentBlock(resourceContent, extraProps, helperName = 'mcpResourceToContent') {
const mimeType = resourceContent.mimeType;
// Handle images (requires blob - base64-encoded binary data)
if (mimeType && isSupportedImageType(mimeType)) {
if (!('blob' in resourceContent)) {
throw new UnsupportedMCPValueError(`Image resource must have blob data, not text. URI: ${resourceContent.uri}`);
}
const imageBlock = {
type: 'image',
source: {
type: 'base64',
data: resourceContent.blob,
media_type: mimeType,
},
...extraProps,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: helperName,
};
return imageBlock;
}
// Handle PDFs (requires blob - base64-encoded binary data)
if (mimeType === 'application/pdf') {
if (!('blob' in resourceContent)) {
throw new UnsupportedMCPValueError(`PDF resource must have blob data, not text. URI: ${resourceContent.uri}`);
}
const pdfBlock = {
type: 'document',
source: {
type: 'base64',
data: resourceContent.blob,
media_type: 'application/pdf',
},
...extraProps,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: helperName,
};
return pdfBlock;
}
// Handle text types (text/*, or no MIME type defaults to text)
if (!mimeType || mimeType.startsWith('text/')) {
const textDocBlock = {
type: 'document',
source: textSourceFromResource(resourceContent),
...extraProps,
[stainless_helper_header_1.SDK_HELPER_SYMBOL]: helperName,
};
return textDocBlock;
}
throw new UnsupportedMCPValueError(`Unsupported MIME type "${mimeType}" for resource: ${resourceContent.uri}`);
}
/**
* Converts MCP resource contents to an Anthropic content block.
*
* This helper is useful when you have resource contents from `mcpClient.readResource()`
* and want to include them in a message or as a document source. It automatically
* finds the first resource with a supported MIME type.
*
* @param result The result from `mcpClient.readResource()`
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block
* @throws {UnsupportedMCPValueError} When contents array is empty or none have a supported MIME type
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToContent } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///example.txt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [mcpResourceToContent(resource)],
* }],
* });
* ```
*/
function mcpResourceToContent(result, extraProps) {
if (result.contents.length === 0) {
throw new UnsupportedMCPValueError('Resource contents array must contain at least one item');
}
const supported = result.contents.find((c) => isSupportedResourceMimeType(c.mimeType));
if (!supported) {
const mimeTypes = result.contents.map((c) => c.mimeType).filter((m) => m !== undefined);
throw new UnsupportedMCPValueError(`No supported MIME type found in resource contents. Available: ${mimeTypes.join(', ')}`);
}
return mcpResourceContentToContentBlock(supported, extraProps);
}
/**
* Gets the raw bytes from an MCP resource.
*/
function bytesFromResource(resource) {
if ('blob' in resource) {
return (0, base64_1.fromBase64)(resource.blob);
}
return new TextEncoder().encode(resource.text);
}
/**
* Creates a text document source from an MCP resource, decoding base64 blob to UTF-8 if needed.
*/
function textSourceFromResource(resource) {
const data = 'text' in resource ? resource.text : new TextDecoder().decode((0, base64_1.fromBase64)(resource.blob));
return { type: 'text', data, media_type: 'text/plain' };
}
/**
* Converts an MCP resource to a File object suitable for uploading via `anthropic.beta.files.upload()`.
*
* @param result The result from `mcpClient.readResource()`
* @returns A File object for use with `anthropic.beta.files.upload()`
* @throws {UnsupportedMCPValueError} When contents array is empty
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToFile } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///document.pdf" });
*
* const uploaded = await anthropic.beta.files.upload({
* file: mcpResourceToFile(resource),
* });
* ```
*/
function mcpResourceToFile(result) {
if (result.contents.length === 0) {
throw new UnsupportedMCPValueError('Resource contents array must contain at least one item');
}
const resourceContents = result.contents[0];
const name = new URL(resourceContents.uri).pathname.split('/').at(-1) || 'file';
const type = resourceContents.mimeType;
const data = bytesFromResource(resourceContents);
const file = new File([data], name, type ? { type } : undefined);
file[stainless_helper_header_1.SDK_HELPER_SYMBOL] = 'mcpResourceToFile';
return file;
}
//# sourceMappingURL=mcp.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,406 @@
/**
* Helper functions for integrating MCP (Model Context Protocol) SDK types
* with the Anthropic SDK.
*
* These helpers reduce boilerplate when converting between MCP types and
* Anthropic API types. The interfaces defined here use TypeScript's structural
* typing to match MCP SDK types without requiring a direct dependency.
*/
import { ToolError } from "../../lib/tools/ToolError.mjs";
import { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader, } from "../../lib/stainless-helper-header.mjs";
import { fromBase64 } from "../../internal/utils/base64.mjs";
export { SDK_HELPER_SYMBOL, collectStainlessHelpers, stainlessHelperHeader };
// -----------------------------------------------------------------------------
// Supported MIME types
// -----------------------------------------------------------------------------
const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
function isSupportedImageType(mimeType) {
return SUPPORTED_IMAGE_TYPES.includes(mimeType);
}
function isSupportedResourceMimeType(mimeType) {
return (!mimeType ||
mimeType.startsWith('text/') ||
mimeType === 'application/pdf' ||
isSupportedImageType(mimeType));
}
// -----------------------------------------------------------------------------
// Error classes
// -----------------------------------------------------------------------------
/**
* Error thrown when an MCP value cannot be converted to a format supported by the Claude API.
*/
export class UnsupportedMCPValueError extends Error {
constructor(message) {
super(message);
this.name = 'UnsupportedMCPValueError';
}
}
// -----------------------------------------------------------------------------
// Helper functions
// -----------------------------------------------------------------------------
/**
* Converts an MCP tool to a BetaRunnableTool for use with the Anthropic SDK's
* `toolRunner()` method.
*
* @param tool The MCP tool definition from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tool
* @param extraProps Additional Claude API properties to include in the tool definition
* @returns A runnable tool for use with `anthropic.beta.messages.toolRunner()`
* @throws {UnsupportedMCPValueError} When the tool returns unsupported content types
* @throws {UnsupportedMCPValueError} When the tool returns unsupported resource links
* @throws {UnsupportedMCPValueError} When the tool returns resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpTool } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const tools = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: tools.tools.map(tool => mcpTool(tool, mcpClient)),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export function mcpTool(tool, mcpClient, extraProps) {
// Transform inputSchema to match BetaTool.InputSchema (convert undefined to null)
const inputSchema = {
...tool.inputSchema,
type: 'object',
properties: tool.inputSchema.properties ?? null,
required: tool.inputSchema.required ?? null,
};
const betaTool = {
name: tool.name,
input_schema: inputSchema,
...(tool.description !== undefined ? { description: tool.description } : {}),
...extraProps,
};
const runnableTool = {
...betaTool,
run: async (input) => {
const result = await mcpClient.callTool({
name: tool.name,
arguments: input,
});
if (result.isError) {
const content = result.content.map((item) => mcpContent(item));
throw new ToolError(content);
}
// If content is empty but structuredContent is present, JSON encode it
// Spec: "For backwards compatibility, a tool that returns structured content SHOULD also return the serialized JSON in a TextContent block."
// meaning it's not required and cannot be assumed.
if (result.content.length === 0 &&
// Spec: "Structured content is returned as a JSON object in the structuredContent field of a result."
typeof result.structuredContent === 'object' &&
result.structuredContent !== null) {
return JSON.stringify(result.structuredContent);
}
return result.content.map((item) => mcpContent(item));
},
parse: (content) => content,
[SDK_HELPER_SYMBOL]: 'mcpTool',
};
return runnableTool;
}
/**
* Converts an array of MCP tools to BetaRunnableTools.
*
* @param tools Array of MCP tool definitions from `mcpClient.listTools()`
* @param mcpClient The MCP client instance used to call the tools
* @param extraProps Additional Claude API properties to include in each tool definition
* @returns An array of runnable tools for use with `anthropic.beta.messages.toolRunner()`
*
* @example
* ```ts
* const { tools } = await mcpClient.listTools();
* const runner = await anthropic.beta.messages.toolRunner({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* tools: mcpTools(tools, mcpClient),
* messages: [{ role: "user", content: "Use the available tools" }],
* });
* ```
*/
export function mcpTools(tools, mcpClient, extraProps) {
return tools.map((tool) => mcpTool(tool, mcpClient, extraProps));
}
/**
* Converts an MCP prompt message to an Anthropic BetaMessageParam.
*
* @param mcpMessage The MCP prompt message from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns A message parameter for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When the message contains unsupported content types
* @throws {UnsupportedMCPValueError} When the message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When the message contains resources with unsupported MIME types
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpMessage } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const prompt = await mcpClient.getPrompt({
* name: "example-prompt",
* arguments: { arg1: "value" },
* });
*
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: prompt.messages.map(msg => mcpMessage(msg)),
* });
* ```
*/
export function mcpMessage(mcpMessage, extraProps) {
const message = {
role: mcpMessage.role,
content: [mcpContent(mcpMessage.content, extraProps)],
[SDK_HELPER_SYMBOL]: 'mcpMessage',
};
return message;
}
/**
* Converts an array of MCP prompt messages to Anthropic BetaMessageParams.
*
* @param messages Array of MCP prompt messages from `mcpClient.getPrompt()`
* @param extraProps Additional Claude API properties to include in content blocks (e.g., `cache_control`)
* @returns An array of message parameters for use with `anthropic.beta.messages.create()`
* @throws {UnsupportedMCPValueError} When any message contains unsupported content types
* @throws {UnsupportedMCPValueError} When any message contains unsupported resource links
* @throws {UnsupportedMCPValueError} When any message contains resources with unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "example-prompt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: mcpMessages(messages),
* });
* ```
*/
export function mcpMessages(messages, extraProps) {
return messages.map((message) => mcpMessage(message, extraProps));
}
/**
* Converts a single MCP prompt content item to an Anthropic content block.
*
* @param content The MCP content item (text, image, or embedded resource)
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block for use in a message's content array
* @throws {UnsupportedMCPValueError} When the content type is not supported (e.g., 'audio')
* @throws {UnsupportedMCPValueError} When resource links use non-http/https protocols
* @throws {UnsupportedMCPValueError} When resources have unsupported MIME types
*
* @example
* ```ts
* const { messages } = await mcpClient.getPrompt({ name: "my-prompt" });
* // If you need to mix MCP content with other content:
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [
* mcpContent(messages[0].content),
* { type: "text", text: "Additional context" },
* ],
* }],
* });
* ```
*/
export function mcpContent(content, extraProps) {
switch (content.type) {
case 'text': {
const textBlock = {
type: 'text',
text: content.text,
...extraProps,
[SDK_HELPER_SYMBOL]: 'mcpContent',
};
return textBlock;
}
case 'image': {
if (!isSupportedImageType(content.mimeType)) {
throw new UnsupportedMCPValueError(`Unsupported image MIME type: ${content.mimeType}`);
}
const imageBlock = {
type: 'image',
source: {
type: 'base64',
data: content.data,
media_type: content.mimeType,
},
...extraProps,
[SDK_HELPER_SYMBOL]: 'mcpContent',
};
return imageBlock;
}
case 'resource':
return mcpResourceContentToContentBlock(content.resource, extraProps, 'mcpContent');
case 'resource_link':
case 'audio':
throw new UnsupportedMCPValueError(`Unsupported MCP content type: ${content.type}`);
default:
// This should never happen as we handle all MCPPromptContentLike types
content;
throw new UnsupportedMCPValueError(`Unsupported MCP content type: ${content.type}`);
}
}
/**
* Converts a single MCP resource contents item to an Anthropic content block.
*/
function mcpResourceContentToContentBlock(resourceContent, extraProps, helperName = 'mcpResourceToContent') {
const mimeType = resourceContent.mimeType;
// Handle images (requires blob - base64-encoded binary data)
if (mimeType && isSupportedImageType(mimeType)) {
if (!('blob' in resourceContent)) {
throw new UnsupportedMCPValueError(`Image resource must have blob data, not text. URI: ${resourceContent.uri}`);
}
const imageBlock = {
type: 'image',
source: {
type: 'base64',
data: resourceContent.blob,
media_type: mimeType,
},
...extraProps,
[SDK_HELPER_SYMBOL]: helperName,
};
return imageBlock;
}
// Handle PDFs (requires blob - base64-encoded binary data)
if (mimeType === 'application/pdf') {
if (!('blob' in resourceContent)) {
throw new UnsupportedMCPValueError(`PDF resource must have blob data, not text. URI: ${resourceContent.uri}`);
}
const pdfBlock = {
type: 'document',
source: {
type: 'base64',
data: resourceContent.blob,
media_type: 'application/pdf',
},
...extraProps,
[SDK_HELPER_SYMBOL]: helperName,
};
return pdfBlock;
}
// Handle text types (text/*, or no MIME type defaults to text)
if (!mimeType || mimeType.startsWith('text/')) {
const textDocBlock = {
type: 'document',
source: textSourceFromResource(resourceContent),
...extraProps,
[SDK_HELPER_SYMBOL]: helperName,
};
return textDocBlock;
}
throw new UnsupportedMCPValueError(`Unsupported MIME type "${mimeType}" for resource: ${resourceContent.uri}`);
}
/**
* Converts MCP resource contents to an Anthropic content block.
*
* This helper is useful when you have resource contents from `mcpClient.readResource()`
* and want to include them in a message or as a document source. It automatically
* finds the first resource with a supported MIME type.
*
* @param result The result from `mcpClient.readResource()`
* @param extraProps Additional Claude API properties to include in the content block (e.g., `cache_control`)
* @returns A Claude content block
* @throws {UnsupportedMCPValueError} When contents array is empty or none have a supported MIME type
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToContent } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///example.txt" });
* await anthropic.beta.messages.create({
* model: "claude-sonnet-4-20250514",
* max_tokens: 1024,
* messages: [{
* role: "user",
* content: [mcpResourceToContent(resource)],
* }],
* });
* ```
*/
export function mcpResourceToContent(result, extraProps) {
if (result.contents.length === 0) {
throw new UnsupportedMCPValueError('Resource contents array must contain at least one item');
}
const supported = result.contents.find((c) => isSupportedResourceMimeType(c.mimeType));
if (!supported) {
const mimeTypes = result.contents.map((c) => c.mimeType).filter((m) => m !== undefined);
throw new UnsupportedMCPValueError(`No supported MIME type found in resource contents. Available: ${mimeTypes.join(', ')}`);
}
return mcpResourceContentToContentBlock(supported, extraProps);
}
/**
* Gets the raw bytes from an MCP resource.
*/
function bytesFromResource(resource) {
if ('blob' in resource) {
return fromBase64(resource.blob);
}
return new TextEncoder().encode(resource.text);
}
/**
* Creates a text document source from an MCP resource, decoding base64 blob to UTF-8 if needed.
*/
function textSourceFromResource(resource) {
const data = 'text' in resource ? resource.text : new TextDecoder().decode(fromBase64(resource.blob));
return { type: 'text', data, media_type: 'text/plain' };
}
/**
* Converts an MCP resource to a File object suitable for uploading via `anthropic.beta.files.upload()`.
*
* @param result The result from `mcpClient.readResource()`
* @returns A File object for use with `anthropic.beta.files.upload()`
* @throws {UnsupportedMCPValueError} When contents array is empty
*
* @example
* ```ts
* import { Client } from "@modelcontextprotocol/sdk/client/index.js";
* import Anthropic from "@anthropic-ai/sdk";
* import { mcpResourceToFile } from "@anthropic-ai/sdk/helpers/beta/mcp";
*
* const mcpClient = new Client({ name: "example", version: "1.0.0" });
* const anthropic = new Anthropic();
*
* const resource = await mcpClient.readResource({ uri: "file:///document.pdf" });
*
* const uploaded = await anthropic.beta.files.upload({
* file: mcpResourceToFile(resource),
* });
* ```
*/
export function mcpResourceToFile(result) {
if (result.contents.length === 0) {
throw new UnsupportedMCPValueError('Resource contents array must contain at least one item');
}
const resourceContents = result.contents[0];
const name = new URL(resourceContents.uri).pathname.split('/').at(-1) || 'file';
const type = resourceContents.mimeType;
const data = bytesFromResource(resourceContents);
const file = new File([data], name, type ? { type } : undefined);
file[SDK_HELPER_SYMBOL] = 'mcpResourceToFile';
return file;
}
//# sourceMappingURL=mcp.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
import { BetaRunnableTool, Promisable } from "../../lib/tools/BetaRunnableTool.mjs";
import { BetaMemoryTool20250818Command, BetaToolResultContentBlockParam } from "../../resources/beta.mjs";
type Command = BetaMemoryTool20250818Command['command'];
export type MemoryToolHandlers = {
[K in Command]: (command: Extract<BetaMemoryTool20250818Command, {
command: K;
}>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
};
export declare function betaMemoryTool(handlers: MemoryToolHandlers): BetaRunnableTool<BetaMemoryTool20250818Command>;
export {};
//# sourceMappingURL=memory.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"memory.d.mts","sourceRoot":"","sources":["../../src/helpers/beta/memory.ts"],"names":[],"mappings":"OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE;OAChC,EAAE,6BAA6B,EAAE,+BAA+B,EAAE;AAEzE,KAAK,OAAO,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG;KAC9B,CAAC,IAAI,OAAO,GAAG,CACd,OAAO,EAAE,OAAO,CAAC,6BAA6B,EAAE;QAAE,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC,KAC5D,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC;CACjE,CAAC;AAEF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,kBAAkB,GAC3B,gBAAgB,CAAC,6BAA6B,CAAC,CAcjD"}

View File

@@ -0,0 +1,11 @@
import { BetaRunnableTool, Promisable } from "../../lib/tools/BetaRunnableTool.js";
import { BetaMemoryTool20250818Command, BetaToolResultContentBlockParam } from "../../resources/beta.js";
type Command = BetaMemoryTool20250818Command['command'];
export type MemoryToolHandlers = {
[K in Command]: (command: Extract<BetaMemoryTool20250818Command, {
command: K;
}>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
};
export declare function betaMemoryTool(handlers: MemoryToolHandlers): BetaRunnableTool<BetaMemoryTool20250818Command>;
export {};
//# sourceMappingURL=memory.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/helpers/beta/memory.ts"],"names":[],"mappings":"OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE;OAChC,EAAE,6BAA6B,EAAE,+BAA+B,EAAE;AAEzE,KAAK,OAAO,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG;KAC9B,CAAC,IAAI,OAAO,GAAG,CACd,OAAO,EAAE,OAAO,CAAC,6BAA6B,EAAE;QAAE,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC,KAC5D,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC;CACjE,CAAC;AAEF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,kBAAkB,GAC3B,gBAAgB,CAAC,6BAA6B,CAAC,CAcjD"}

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.betaMemoryTool = betaMemoryTool;
function betaMemoryTool(handlers) {
return {
type: 'memory_20250818',
name: 'memory',
parse: (content) => content,
run: (args) => {
const handler = handlers[args.command];
if (!handler) {
throw new Error(`${args.command} not implemented`);
}
return handler.bind(handlers)(args);
},
};
}
//# sourceMappingURL=memory.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/helpers/beta/memory.ts"],"names":[],"mappings":";;AAWA,wCAgBC;AAhBD,SAAgB,cAAc,CAC5B,QAA4B;IAE5B,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAwC;QAC5D,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAW,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,15 @@
export function betaMemoryTool(handlers) {
return {
type: 'memory_20250818',
name: 'memory',
parse: (content) => content,
run: (args) => {
const handler = handlers[args.command];
if (!handler) {
throw new Error(`${args.command} not implemented`);
}
return handler.bind(handlers)(args);
},
};
}
//# sourceMappingURL=memory.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"memory.mjs","sourceRoot":"","sources":["../../src/helpers/beta/memory.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,cAAc,CAC5B,QAA4B;IAE5B,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAwC;QAC5D,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAW,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,27 @@
import type { infer as zodInfer, ZodType } from 'zod';
import { AutoParseableBetaOutputFormat } from "../../lib/beta-parser.mjs";
import { BetaRunnableTool, Promisable } from "../../lib/tools/BetaRunnableTool.mjs";
import { BetaToolResultContentBlockParam } from "../../resources/beta.mjs";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export declare function betaZodOutputFormat<ZodInput extends ZodType>(zodObject: ZodInput): AutoParseableBetaOutputFormat<zodInfer<ZodInput>>;
/**
* Creates a tool using the provided Zod schema that can be passed
* into the `.toolRunner()` method. The Zod schema will automatically be
* converted into JSON Schema when passed to the API. The provided function's
* input arguments will also be validated against the provided schema.
*/
export declare function betaZodTool<InputSchema extends ZodType>(options: {
name: string;
inputSchema: InputSchema;
description: string;
run: (args: zodInfer<InputSchema>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
}): BetaRunnableTool<zodInfer<InputSchema>>;
//# sourceMappingURL=zod.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.d.mts","sourceRoot":"","sources":["../../src/helpers/beta/zod.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK;OAG9C,EAAE,6BAA6B,EAAE;OACjC,EAAE,gBAAgB,EAAE,UAAU,EAAE;OAChC,EAAE,+BAA+B,EAAE;AAC1C;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,OAAO,EAC1D,SAAS,EAAE,QAAQ,GAClB,6BAA6B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAsBnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,SAAS,OAAO,EAAE,OAAO,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;CACnG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAkB1C"}

View File

@@ -0,0 +1,27 @@
import type { infer as zodInfer, ZodType } from 'zod';
import { AutoParseableBetaOutputFormat } from "../../lib/beta-parser.js";
import { BetaRunnableTool, Promisable } from "../../lib/tools/BetaRunnableTool.js";
import { BetaToolResultContentBlockParam } from "../../resources/beta.js";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export declare function betaZodOutputFormat<ZodInput extends ZodType>(zodObject: ZodInput): AutoParseableBetaOutputFormat<zodInfer<ZodInput>>;
/**
* Creates a tool using the provided Zod schema that can be passed
* into the `.toolRunner()` method. The Zod schema will automatically be
* converted into JSON Schema when passed to the API. The provided function's
* input arguments will also be validated against the provided schema.
*/
export declare function betaZodTool<InputSchema extends ZodType>(options: {
name: string;
inputSchema: InputSchema;
description: string;
run: (args: zodInfer<InputSchema>) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
}): BetaRunnableTool<zodInfer<InputSchema>>;
//# sourceMappingURL=zod.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/helpers/beta/zod.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK;OAG9C,EAAE,6BAA6B,EAAE;OACjC,EAAE,gBAAgB,EAAE,UAAU,EAAE;OAChC,EAAE,+BAA+B,EAAE;AAC1C;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,OAAO,EAC1D,SAAS,EAAE,QAAQ,GAClB,6BAA6B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAsBnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,SAAS,OAAO,EAAE,OAAO,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;CACnG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAkB1C"}

View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.betaZodOutputFormat = betaZodOutputFormat;
exports.betaZodTool = betaZodTool;
const tslib_1 = require("../../internal/tslib.js");
const transform_json_schema_1 = require("../..//lib/transform-json-schema.js");
const z = tslib_1.__importStar(require("zod/v4"));
const error_1 = require("../../core/error.js");
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
function betaZodOutputFormat(zodObject) {
let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
jsonSchema = (0, transform_json_schema_1.transformJSONSchema)(jsonSchema);
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
const output = zodObject.safeParse(JSON.parse(content));
if (!output.success) {
throw new error_1.AnthropicError(`Failed to parse structured output: ${output.error.message} cause: ${output.error.issues}`);
}
return output.data;
},
};
}
/**
* Creates a tool using the provided Zod schema that can be passed
* into the `.toolRunner()` method. The Zod schema will automatically be
* converted into JSON Schema when passed to the API. The provided function's
* input arguments will also be validated against the provided schema.
*/
function betaZodTool(options) {
const jsonSchema = z.toJSONSchema(options.inputSchema, { reused: 'ref' });
if (jsonSchema.type !== 'object') {
throw new Error(`Zod schema for tool "${options.name}" must be an object, but got ${jsonSchema.type}`);
}
// TypeScript doesn't narrow the type after the runtime check, so we need to assert it
const objectSchema = jsonSchema;
return {
type: 'custom',
name: options.name,
input_schema: objectSchema,
description: options.description,
run: options.run,
parse: (args) => options.inputSchema.parse(args),
};
}
//# sourceMappingURL=zod.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/helpers/beta/zod.ts"],"names":[],"mappings":";;AAgBA,kDAwBC;AAQD,kCAuBC;;AAvED,+EAAuE;AAEvE,kDAA4B;AAC5B,+CAAkD;AAIlD;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CACjC,SAAmB;IAEnB,IAAI,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE9D,UAAU,GAAG,IAAA,2CAAmB,EAAC,UAAU,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAExD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,sBAAc,CACtB,sCAAsC,MAAM,CAAC,KAAK,CAAC,OAAO,WAAW,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAC3F,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAA8B,OAKxD;IACC,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE1E,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,IAAI,gCAAgC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,sFAAsF;IACtF,MAAM,YAAY,GAAG,UAAoD,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,YAAY;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAA0B;KACnF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,52 @@
import { transformJSONSchema } from "../..//lib/transform-json-schema.mjs";
import * as z from 'zod/v4';
import { AnthropicError } from "../../core/error.mjs";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export function betaZodOutputFormat(zodObject) {
let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
jsonSchema = transformJSONSchema(jsonSchema);
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
const output = zodObject.safeParse(JSON.parse(content));
if (!output.success) {
throw new AnthropicError(`Failed to parse structured output: ${output.error.message} cause: ${output.error.issues}`);
}
return output.data;
},
};
}
/**
* Creates a tool using the provided Zod schema that can be passed
* into the `.toolRunner()` method. The Zod schema will automatically be
* converted into JSON Schema when passed to the API. The provided function's
* input arguments will also be validated against the provided schema.
*/
export function betaZodTool(options) {
const jsonSchema = z.toJSONSchema(options.inputSchema, { reused: 'ref' });
if (jsonSchema.type !== 'object') {
throw new Error(`Zod schema for tool "${options.name}" must be an object, but got ${jsonSchema.type}`);
}
// TypeScript doesn't narrow the type after the runtime check, so we need to assert it
const objectSchema = jsonSchema;
return {
type: 'custom',
name: options.name,
input_schema: objectSchema,
description: options.description,
run: options.run,
parse: (args) => options.inputSchema.parse(args),
};
}
//# sourceMappingURL=zod.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.mjs","sourceRoot":"","sources":["../../src/helpers/beta/zod.ts"],"names":[],"mappings":"OAAO,EAAE,mBAAmB,EAAE;OAEvB,KAAK,CAAC,MAAM,QAAQ;OACpB,EAAE,cAAc,EAAE;AAIzB;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAmB;IAEnB,IAAI,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE9D,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAExD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,cAAc,CACtB,sCAAsC,MAAM,CAAC,KAAK,CAAC,OAAO,WAAW,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAC3F,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAA8B,OAKxD;IACC,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE1E,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,IAAI,gCAAgC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,sFAAsF;IACtF,MAAM,YAAY,GAAG,UAAoD,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,YAAY;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAA0B;KACnF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,3 @@
export { jsonSchemaOutputFormat } from "./json-schema.mjs";
export { zodOutputFormat } from "./zod.mjs";
//# sourceMappingURL=index.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/helpers/index.ts"],"names":[],"mappings":"OAAO,EAAE,sBAAsB,EAAE;OAC1B,EAAE,eAAe,EAAE"}

View File

@@ -0,0 +1,3 @@
export { jsonSchemaOutputFormat } from "./json-schema.js";
export { zodOutputFormat } from "./zod.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/helpers/index.ts"],"names":[],"mappings":"OAAO,EAAE,sBAAsB,EAAE;OAC1B,EAAE,eAAe,EAAE"}

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.zodOutputFormat = exports.jsonSchemaOutputFormat = void 0;
var json_schema_1 = require("./json-schema.js");
Object.defineProperty(exports, "jsonSchemaOutputFormat", { enumerable: true, get: function () { return json_schema_1.jsonSchemaOutputFormat; } });
var zod_1 = require("./zod.js");
Object.defineProperty(exports, "zodOutputFormat", { enumerable: true, get: function () { return zod_1.zodOutputFormat; } });
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/helpers/index.ts"],"names":[],"mappings":";;;AAAA,gDAAuD;AAA9C,qHAAA,sBAAsB,OAAA;AAC/B,gCAAwC;AAA/B,sGAAA,eAAe,OAAA"}

View File

@@ -0,0 +1,3 @@
export { jsonSchemaOutputFormat } from "./json-schema.mjs";
export { zodOutputFormat } from "./zod.mjs";
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/helpers/index.ts"],"names":[],"mappings":"OAAO,EAAE,sBAAsB,EAAE;OAC1B,EAAE,eAAe,EAAE"}

View File

@@ -0,0 +1,18 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { AutoParseableOutputFormat } from "../lib/parser.mjs";
type NoInfer<T> = T extends infer R ? R : never;
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
* Note: When `transform` is enabled (the default), the schema is deep-cloned before transformation,
* so the original schema object is not modified.
*/
export declare function jsonSchemaOutputFormat<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(jsonSchema: Schema, options?: {
transform?: boolean;
}): AutoParseableOutputFormat<NoInfer<FromSchema<Schema>>>;
export {};
//# sourceMappingURL=json-schema.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.d.mts","sourceRoot":"","sources":["../src/helpers/json-schema.ts"],"names":[],"mappings":"OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB;OACnD,EAAE,yBAAyB,EAAE;AAIpC,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAEtE,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,yBAAyB,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAyBxD"}

View File

@@ -0,0 +1,18 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { AutoParseableOutputFormat } from "../lib/parser.js";
type NoInfer<T> = T extends infer R ? R : never;
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
* Note: When `transform` is enabled (the default), the schema is deep-cloned before transformation,
* so the original schema object is not modified.
*/
export declare function jsonSchemaOutputFormat<const Schema extends Exclude<JSONSchema, boolean> & {
type: 'object';
}>(jsonSchema: Schema, options?: {
transform?: boolean;
}): AutoParseableOutputFormat<NoInfer<FromSchema<Schema>>>;
export {};
//# sourceMappingURL=json-schema.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../src/helpers/json-schema.ts"],"names":[],"mappings":"OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB;OACnD,EAAE,yBAAyB,EAAE;AAIpC,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,MAAM,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAEtE,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,yBAAyB,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAyBxD"}

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.jsonSchemaOutputFormat = jsonSchemaOutputFormat;
const error_1 = require("../core/error.js");
const transform_json_schema_1 = require("../lib/transform-json-schema.js");
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
* Note: When `transform` is enabled (the default), the schema is deep-cloned before transformation,
* so the original schema object is not modified.
*/
function jsonSchemaOutputFormat(jsonSchema, options) {
if (jsonSchema.type !== 'object') {
throw new Error(`JSON schema must be an object, but got ${jsonSchema.type}`);
}
const transform = options?.transform ?? true;
if (transform) {
jsonSchema = (0, transform_json_schema_1.transformJSONSchema)(jsonSchema);
}
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
try {
return JSON.parse(content);
}
catch (error) {
throw new error_1.AnthropicError(`Failed to parse structured output: ${error instanceof Error ? error.message : String(error)}`);
}
},
};
}
//# sourceMappingURL=json-schema.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../src/helpers/json-schema.ts"],"names":[],"mappings":";;AAeA,wDAgCC;AA7CD,4CAA+C;AAC/C,2EAAmE;AAInE;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CAGpC,UAAkB,EAClB,OAEC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0CAA0C,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,UAAU,GAAG,IAAA,2CAAmB,EAAC,UAAU,CAAW,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,sBAAc,CACtB,sCAAsC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC/F,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,34 @@
import { AnthropicError } from "../core/error.mjs";
import { transformJSONSchema } from "../lib/transform-json-schema.mjs";
/**
* Creates a JSON schema output format object from the given JSON schema.
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
*
* Note: When `transform` is enabled (the default), the schema is deep-cloned before transformation,
* so the original schema object is not modified.
*/
export function jsonSchemaOutputFormat(jsonSchema, options) {
if (jsonSchema.type !== 'object') {
throw new Error(`JSON schema must be an object, but got ${jsonSchema.type}`);
}
const transform = options?.transform ?? true;
if (transform) {
jsonSchema = transformJSONSchema(jsonSchema);
}
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
try {
return JSON.parse(content);
}
catch (error) {
throw new AnthropicError(`Failed to parse structured output: ${error instanceof Error ? error.message : String(error)}`);
}
},
};
}
//# sourceMappingURL=json-schema.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"json-schema.mjs","sourceRoot":"","sources":["../src/helpers/json-schema.ts"],"names":[],"mappings":"OAEO,EAAE,cAAc,EAAE;OAClB,EAAE,mBAAmB,EAAE;AAI9B;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAGpC,UAAkB,EAClB,OAEC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0CAA0C,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAW,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CACtB,sCAAsC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC/F,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,13 @@
import type { infer as zodInfer, ZodType } from 'zod';
import { AutoParseableOutputFormat } from "../lib/parser.mjs";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export declare function zodOutputFormat<ZodInput extends ZodType>(zodObject: ZodInput): AutoParseableOutputFormat<zodInfer<ZodInput>>;
//# sourceMappingURL=zod.d.mts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.d.mts","sourceRoot":"","sources":["../src/helpers/zod.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK;OAG9C,EAAE,yBAAyB,EAAE;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,QAAQ,SAAS,OAAO,EACtD,SAAS,EAAE,QAAQ,GAClB,yBAAyB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAwC/C"}

View File

@@ -0,0 +1,13 @@
import type { infer as zodInfer, ZodType } from 'zod';
import { AutoParseableOutputFormat } from "../lib/parser.js";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export declare function zodOutputFormat<ZodInput extends ZodType>(zodObject: ZodInput): AutoParseableOutputFormat<zodInfer<ZodInput>>;
//# sourceMappingURL=zod.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../src/helpers/zod.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK;OAG9C,EAAE,yBAAyB,EAAE;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,QAAQ,SAAS,OAAO,EACtD,SAAS,EAAE,QAAQ,GAClB,yBAAyB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAwC/C"}

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.zodOutputFormat = zodOutputFormat;
const tslib_1 = require("../internal/tslib.js");
const transform_json_schema_1 = require("../lib/transform-json-schema.js");
const z = tslib_1.__importStar(require("zod/v4"));
const error_1 = require("../core/error.js");
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
function zodOutputFormat(zodObject) {
let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
jsonSchema = (0, transform_json_schema_1.transformJSONSchema)(jsonSchema);
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
let parsed;
try {
parsed = JSON.parse(content);
}
catch (error) {
throw new error_1.AnthropicError(`Failed to parse structured output as JSON: ${error instanceof Error ? error.message : String(error)}`);
}
const output = zodObject.safeParse(parsed);
if (!output.success) {
const formattedIssues = output.error.issues
.slice(0, 5)
.map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)
.join('\n');
const issueCount = output.error.issues.length;
const suffix = issueCount > 5 ? `\n ... and ${issueCount - 5} more issue(s)` : '';
throw new error_1.AnthropicError(`Failed to parse structured output: ${output.error.message}\nValidation issues:\n${formattedIssues}${suffix}`);
}
return output.data;
},
};
}
//# sourceMappingURL=zod.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.js","sourceRoot":"","sources":["../src/helpers/zod.ts"],"names":[],"mappings":";;AAeA,0CA0CC;;AAzDD,2EAAmE;AAEnE,kDAA4B;AAC5B,4CAA+C;AAG/C;;;;;;;;GAQG;AACH,SAAgB,eAAe,CAC7B,SAAmB;IAEnB,IAAI,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE9D,UAAU,GAAG,IAAA,2CAAmB,EAAC,UAAU,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,sBAAc,CACtB,8CACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAE3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;qBACxC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;qBAC/D,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC9C,MAAM,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,UAAU,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEnF,MAAM,IAAI,sBAAc,CACtB,sCAAsC,MAAM,CAAC,KAAK,CAAC,OAAO,yBAAyB,eAAe,GAAG,MAAM,EAAE,CAC9G,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,43 @@
import { transformJSONSchema } from "../lib/transform-json-schema.mjs";
import * as z from 'zod/v4';
import { AnthropicError } from "../core/error.mjs";
/**
* Creates a JSON schema output format object from the given Zod schema.
*
* If this is passed to the `.parse()` method then the response message will contain a
* `.parsed_output` property that is the result of parsing the content with the given Zod object.
*
* This can be passed directly to the `.create()` method but will not
* result in any automatic parsing, you'll have to parse the response yourself.
*/
export function zodOutputFormat(zodObject) {
let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
jsonSchema = transformJSONSchema(jsonSchema);
return {
type: 'json_schema',
schema: {
...jsonSchema,
},
parse: (content) => {
let parsed;
try {
parsed = JSON.parse(content);
}
catch (error) {
throw new AnthropicError(`Failed to parse structured output as JSON: ${error instanceof Error ? error.message : String(error)}`);
}
const output = zodObject.safeParse(parsed);
if (!output.success) {
const formattedIssues = output.error.issues
.slice(0, 5)
.map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)
.join('\n');
const issueCount = output.error.issues.length;
const suffix = issueCount > 5 ? `\n ... and ${issueCount - 5} more issue(s)` : '';
throw new AnthropicError(`Failed to parse structured output: ${output.error.message}\nValidation issues:\n${formattedIssues}${suffix}`);
}
return output.data;
},
};
}
//# sourceMappingURL=zod.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"zod.mjs","sourceRoot":"","sources":["../src/helpers/zod.ts"],"names":[],"mappings":"OAAO,EAAE,mBAAmB,EAAE;OAEvB,KAAK,CAAC,MAAM,QAAQ;OACpB,EAAE,cAAc,EAAE;AAGzB;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAmB;IAEnB,IAAI,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE9D,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,GAAG,UAAU;SACd;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CACtB,8CACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAE3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;qBACxC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;qBAC/D,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC9C,MAAM,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,UAAU,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEnF,MAAM,IAAI,cAAc,CACtB,sCAAsC,MAAM,CAAC,KAAK,CAAC,OAAO,yBAAyB,eAAe,GAAG,MAAM,EAAE,CAC9G,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}