@agentscope-ai/agentscope 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/dist/agent/index.d.mts +10 -10
- package/dist/agent/index.d.ts +10 -10
- package/dist/agent/index.js +104 -93
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +104 -93
- package/dist/agent/index.mjs.map +1 -1
- package/dist/{base-BOx3UzOl.d.mts → base-1YVBgB4n.d.mts} +2 -2
- package/dist/{base-DYlBMCy_.d.mts → base-B_MQMHWr.d.mts} +3 -3
- package/dist/{base-Cwi4bjze.d.ts → base-BherSLRs.d.ts} +3 -3
- package/dist/{base-NX-knWOv.d.ts → base-CY4DMBH1.d.ts} +1 -1
- package/dist/{base-BoIps2RL.d.ts → base-ChWjyzPL.d.ts} +2 -2
- package/dist/{base-C7jwyH4Z.d.mts → base-ClilytRZ.d.mts} +1 -1
- package/dist/{block-VsnHrllL.d.mts → block-B72uPF1H.d.mts} +7 -5
- package/dist/{block-VsnHrllL.d.ts → block-B72uPF1H.d.ts} +7 -5
- package/dist/event/index.d.mts +105 -89
- package/dist/event/index.d.ts +105 -89
- package/dist/event/index.js +8 -8
- package/dist/event/index.js.map +1 -1
- package/dist/event/index.mjs +8 -8
- package/dist/event/index.mjs.map +1 -1
- package/dist/formatter/index.d.mts +4 -3
- package/dist/formatter/index.d.ts +4 -3
- package/dist/formatter/index.js +17 -17
- package/dist/formatter/index.js.map +1 -1
- package/dist/formatter/index.mjs +17 -17
- package/dist/formatter/index.mjs.map +1 -1
- package/dist/{index-BcatlwXQ.d.ts → index-BNfyKbQN.d.ts} +1 -1
- package/dist/{index-BTJDlKvQ.d.mts → index-UQCwdfet.d.mts} +1 -1
- package/dist/mcp/index.d.mts +2 -2
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/mcp/index.mjs.map +1 -1
- package/dist/message/index.d.mts +3 -2
- package/dist/message/index.d.ts +3 -2
- package/dist/message/index.js +204 -5
- package/dist/message/index.js.map +1 -1
- package/dist/message/index.mjs +200 -5
- package/dist/message/index.mjs.map +1 -1
- package/dist/message-CPZd0NIc.d.ts +133 -0
- package/dist/message-DgpfAaHK.d.mts +133 -0
- package/dist/model/index.d.mts +6 -5
- package/dist/model/index.d.ts +6 -5
- package/dist/model/index.js +39 -28
- package/dist/model/index.js.map +1 -1
- package/dist/model/index.mjs +39 -28
- package/dist/model/index.mjs.map +1 -1
- package/dist/storage/index.d.mts +4 -3
- package/dist/storage/index.d.ts +4 -3
- package/dist/storage/index.js +4 -4
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +4 -4
- package/dist/storage/index.mjs.map +1 -1
- package/dist/tool/index.d.mts +4 -4
- package/dist/tool/index.d.ts +4 -4
- package/dist/{toolkit-CEpulFi0.d.ts → toolkit-DeOlul5Y.d.ts} +2 -2
- package/dist/{toolkit-CGEZSZPa.d.mts → toolkit-jwe7NmVJ.d.mts} +2 -2
- package/package.json +87 -87
- package/src/agent/agent.test.ts +104 -71
- package/src/agent/agent.ts +112 -104
- package/src/agent/test-compression.ts +1 -1
- package/src/event/index.ts +96 -98
- package/src/formatter/base.ts +3 -3
- package/src/formatter/dashscope-chat-formatter.test.ts +11 -8
- package/src/formatter/dashscope-chat-formatter.ts +3 -3
- package/src/formatter/openai-chat-formatter.test.ts +13 -5
- package/src/formatter/openai-chat-formatter.ts +6 -6
- package/src/mcp/base.ts +1 -1
- package/src/mcp/http.test.ts +2 -0
- package/src/mcp/stdio.test.ts +1 -0
- package/src/message/append-event.test.ts +783 -0
- package/src/message/block.ts +8 -4
- package/src/message/index.ts +12 -1
- package/src/message/message.test.ts +3 -1
- package/src/message/message.ts +310 -47
- package/src/model/dashscope-model.test.ts +4 -0
- package/src/model/dashscope-model.ts +3 -0
- package/src/model/deepseek-model.test.ts +2 -0
- package/src/model/deepseek-model.ts +3 -0
- package/src/model/ollama-model.test.ts +1 -0
- package/src/model/ollama-model.ts +2 -0
- package/src/model/openai-model.ts +3 -0
- package/src/permission/index.ts +13 -0
- package/src/storage/file-system.test.ts +4 -3
- package/src/storage/file-system.ts +4 -4
- package/src/tool/toolkit.test.ts +12 -0
- package/dist/message-CkN21KaY.d.mts +0 -99
- package/dist/message-CzLeTlua.d.ts +0 -99
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/message/message.ts","../../src/formatter/base.ts","../../src/formatter/dashscope-chat-formatter.ts","../../src/formatter/deepseek-chat-formatter.ts","../../src/formatter/ollama-chat-formatter.ts","../../src/formatter/openai-chat-formatter.ts"],"sourcesContent":["import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n} from './block';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n timestamp: string;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `timestamp` when omitted.\n *\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.timestamp\n * @param root0.usage\n * @returns A fully-populated {@link Msg} object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n timestamp = new Date().toISOString(),\n usage,\n}: Omit<Msg, 'id' | 'timestamp' | 'metadata'> &\n Partial<Pick<Msg, 'id' | 'timestamp' | 'metadata'>>): Msg {\n return { id, name, role, content, metadata, timestamp, usage } as Msg;\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) {\n return null;\n }\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\n/**\n * Return all {@link TextBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'text'`\n * @returns An array of {@link TextBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\n/**\n * Return all {@link ThinkingBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'thinking'`\n * @returns An array of {@link ThinkingBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\n/**\n * Return all {@link DataBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'video'`\n * @returns An array of {@link DataBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\n/**\n * Return all {@link ToolCallBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_call'`\n * @returns An array of {@link ToolCallBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\n/**\n * Return all {@link ToolResultBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_result'`\n * @returns An array of {@link ToolResultBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n","import { Msg, TextBlock, DataBlock, createMsg } from '../message';\n\n/**\n * Base class for message formatters.\n */\nexport abstract class FormatterBase {\n /**\n * Format the input message objects into the required format by the API.\n *\n * @param root0\n * @param root0.msgs - An array of message objects to be formatted.\n * @returns A promise that resolves to an array of formatted message objects.\n */\n abstract format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]>;\n\n /**\n * Convert the tool output to string format for the LLM APIs that only accept text input. If\n * `promoteMultimodalToolResult` is true, the multimodal content will be promoted to be a user message with\n * \"<system-info></system-info>\" tags. Otherwise, the multimodal content will be saved to a storage and a URL link\n * will be provided in the text output.\n *\n * @param output - The tool output, which can be a string or an array of content blocks.\n * @param promoteMultimodalToolResult - Whether to promote the multimodal content to the prompt messages.\n * @returns An object containing the text output and an optional promoted message.\n */\n convertToolOutputToString(\n output: string | (TextBlock | DataBlock)[],\n promoteMultimodalToolResult: boolean | { image?: boolean; audio?: boolean; video?: boolean }\n ) {\n if (typeof output === 'string') return { text: output, promotedMsg: null };\n\n let textualOutput = [];\n\n const promotedData: { id: string; block: DataBlock }[] = [];\n\n for (const block of output) {\n switch (block.type) {\n case 'text':\n textualOutput.push(block.text);\n break;\n default:\n const type = block.source.mediaType.split('/')[0];\n if (type !== 'image' && type !== 'audio' && type !== 'video') {\n console.log(\n `Unsupported media type '${block.source.mediaType}' in tool output. Only image, audio and video are supported.`\n );\n break;\n }\n if (block.source.type === 'url') {\n textualOutput.push(\n `<system-info>One returned ${type} can be found at: ${block.source.url}</system-info>`\n );\n } else {\n // If we should promote the multimodal content to the prompt messages\n const shouldPromote =\n promoteMultimodalToolResult === true ||\n (typeof promoteMultimodalToolResult === 'object' &&\n promoteMultimodalToolResult[type]);\n\n if (shouldPromote) {\n // Create an ID for the multimodal content first, which should less than 10 characters\n const dataID = Math.random().toString(36).substring(2, 10);\n textualOutput.push(\n `<system-info>One returned ${type} is embedded with ID '${dataID}' and will be attached within '<system-info></system-info>' tags later.</system-info>`\n );\n\n // Record the promoted data\n promotedData.push({ id: dataID, block });\n } else {\n // TODO: save locally\n\n // Save to storage and provide URL link\n textualOutput.push(`The returned ${block.type} is stored locally.`);\n }\n }\n }\n }\n\n // Attach prefix and suffix system-info tags if there are promoted blocks\n const promotedBlocks: (TextBlock | DataBlock)[] = [];\n promotedData.forEach(({ id, block }) => {\n const type = block.source.mediaType.split('/')[0];\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `<${type}_data id='${id}'>`,\n });\n promotedBlocks.push(block);\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `</${type}_data>\\n`,\n });\n });\n\n if (promotedBlocks.length > 0) {\n // The prefix\n const prefix =\n '<system-info>The multimodal contents returned from the tool call are as follows:\\n';\n\n if (promotedBlocks[0].type === 'text') {\n promotedBlocks[0].text = `${prefix}${promotedBlocks[0].text}`;\n } else {\n promotedBlocks.unshift({\n id: crypto.randomUUID(),\n type: 'text',\n text: `${prefix}`,\n });\n }\n\n // The suffix\n const lastBlock = promotedBlocks[promotedBlocks.length - 1];\n if (lastBlock.type === 'text') {\n promotedBlocks[promotedBlocks.length - 1] = {\n id: crypto.randomUUID(),\n type: 'text',\n text: `${lastBlock.text}</system-info>`,\n };\n } else {\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `</system-info>`,\n });\n }\n }\n\n return {\n text: textualOutput.join('\\n'),\n promotedMsg: createMsg({ name: 'user', content: promotedBlocks, role: 'user' }),\n };\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, TextBlock, getContentBlocks } from '../message';\nimport { DataBlock } from '../message';\n\ninterface DashScopeFormatterOptions {\n /**\n * Since DashScope API doesn't support multimodal tool outputs, this option indicates whether to\n * promote the multimodal tool results to the prompt messages, so that LLMs can see them.\n * Note you should ensure your model supports the corresponding modalities.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n *\n */\nexport class DashScopeChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initialize a DashScopeChatFormatter instance.\n *\n * @param promoteMultimodalToolResult - Since DashScope API doesn't support multimodal tool outputs, this option\n * indicates whether to promote the multimodal tool results to the prompt messages, so that LLMs can see them.\n * Note you should ensure your model supports the corresponding modalities.\n * @param promoteMultimodalToolResult.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: DashScopeFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input message objects into the required format by DashScope API.\n *\n * @param msgs - An array of Msg instances to be formatted.\n * @param msgs.msgs\n * @returns A promise that resolves to an array of formatted message objects.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n content: Record<string, unknown>[];\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n content: [],\n };\n\n // The cached messages that should be pushed after the current message, to keep the order of messages correct.\n const cachedMsgs = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n formattedMsg.content.push(this._formatTextBlock(block));\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg) {\n // Insert the promoted message into the array as the next message to be processed\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n formattedMsg.content.push(...this._formatMultimodalBlock(block));\n break;\n }\n }\n if (formattedMsg.content.length > 0 || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n // Process next message\n index++;\n }\n return formattedMsgs;\n }\n\n /**\n * Format a text content block into the required format.\n *\n * @param block - The text content block to format.\n * @returns An object representing the formatted text content.\n */\n _formatTextBlock(block: TextBlock) {\n return { text: block.text };\n }\n\n /**\n * Format a multimodal data block into the required format.\n * In DashScope API, the local file paths should be prefixed with \"file://\". URLs are kept unchanged.\n *\n * @param block - The multimodal content block to format.\n * @returns An object representing the formatted multimodal content.\n */\n _formatMultimodalBlock(block: DataBlock) {\n const type = block.source.mediaType.split('/')[0];\n\n if (!['image', 'audio', 'video'].includes(type)) {\n console.log(\n `Skip unsupported media type ${block.source.mediaType} in DashScopeChatFormatter. Only image, audio and video are supported.`\n );\n return [];\n }\n\n if (block.source.type === 'url') {\n return [{ [type]: block.source.url }];\n }\n\n return [\n {\n [type]: `data:${block.source.mediaType};base64,${block.source.data}`,\n },\n ];\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, getContentBlocks } from '../message';\n\ninterface DeepSeekFormatterOptions {\n /**\n * Most LLM APIs don't support multimodal tool outputs, this option controls whether to\n * promote multimodal tool results to follow-up user messages.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n * Format AgentScope message objects into DeepSeek Chat Completions message format.\n */\nexport class DeepSeekChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initializes a new instance of the DeepSeekChatFormatter class.\n * @param root0\n * @param root0.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: DeepSeekFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input messages into the structure expected by DeepSeek Chat Completions API.\n * @param root0\n * @param root0.msgs\n * @returns An array of formatted message objects ready to be sent to the DeepSeek API.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n name: string;\n content: Record<string, unknown>[] | null;\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n name: msg.name,\n content: null,\n };\n const content: Record<string, unknown>[] = [];\n\n // Cache tool-result messages to keep the sequence right after current message.\n const cachedMsgs: Record<string, unknown>[] = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n content.push({\n type: 'text',\n text: block.text,\n });\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg?.content.length) {\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n console.warn(\n `DeepSeek models don't support multimodal data for now (2026-03), skip the data block in message content.`\n );\n break;\n }\n }\n\n if (content.length > 0) {\n formattedMsg.content = content;\n }\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n index++;\n }\n\n return formattedMsgs;\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, getContentBlocks, getTextContent } from '../message';\n\n/**\n * Format AgentScope message objects into Ollama Chat message format.\n * Ollama expects simple string content, not the multimodal array format.\n */\nexport class OllamaChatFormatter extends FormatterBase {\n // eslint-disable-next-line jsdoc/require-returns\n /**\n * Format messages for Ollama API\n * @param root0\n * @param root0.msgs\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n\n for (const msg of msgs) {\n const formattedMsg: {\n role: string;\n content: string;\n tool_calls?: {\n function: {\n name: string;\n arguments: Record<string, unknown>;\n };\n }[];\n } = {\n role: msg.role,\n content: '',\n };\n\n // Extract text content\n const textContent = getTextContent(msg);\n if (textContent) {\n formattedMsg.content = textContent;\n }\n\n // Handle tool calls\n const toolCalls = getContentBlocks(msg, 'tool_call');\n if (toolCalls.length > 0) {\n formattedMsg.tool_calls = toolCalls.map(toolCall => ({\n function: {\n name: toolCall.name,\n arguments: JSON.parse(toolCall.input),\n },\n }));\n }\n\n // Handle tool results\n const toolResults = getContentBlocks(msg, 'tool_result');\n for (const toolResult of toolResults) {\n const resultText = this.convertToolOutputToString(toolResult.output, false);\n formattedMsgs.push({\n role: 'tool',\n content: resultText.text,\n });\n }\n\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n }\n\n return formattedMsgs;\n }\n}\n","import { existsSync } from 'fs';\nimport { readFile } from 'fs/promises';\nimport { extname } from 'path';\nimport { fileURLToPath } from 'url';\n\nimport { FormatterBase } from './base';\nimport { DataBlock, Msg, TextBlock, getContentBlocks } from '../message';\n\ninterface OpenAIFormatterOptions {\n /**\n * Most LLM APIs don't support multimodal tool outputs, this option controls whether to\n * promote multimodal tool results to follow-up user messages.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n * Format AgentScope message objects into OpenAI Chat Completions message format.\n */\nexport class OpenAIChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initializes a new instance of the OpenAIChatFormatter class.\n * @param root0\n * @param root0.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: OpenAIFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input messages into OpenAI Chat Completions message format.\n * @param root0\n * @param root0.msgs\n * @returns An array of formatted messages compatible with OpenAI Chat Completions API.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n name: string;\n content: Record<string, unknown>[] | null;\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n name: msg.name,\n content: null,\n };\n const content: Record<string, unknown>[] = [];\n\n // Cache tool-result messages to keep the sequence right after current message.\n const cachedMsgs: Record<string, unknown>[] = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n content.push(this._formatTextBlock(block));\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg?.content.length) {\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n content.push(\n ...(await this._formatMultimodalBlock({ block, role: msg.role }))\n );\n break;\n }\n }\n\n if (content.length > 0) {\n formattedMsg.content = content;\n }\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n index++;\n }\n\n return formattedMsgs;\n }\n\n /**\n * Format a text block into OpenAI Chat Completions message content format.\n * @param block\n * @returns An object representing the formatted text block.\n */\n _formatTextBlock(block: TextBlock) {\n return {\n type: 'text',\n text: block.text,\n };\n }\n\n /**\n * Format a multimodal data block into OpenAI Chat Completions message content format.\n * @param root0\n * @param root0.block\n * @param root0.role\n * @returns The formatted content blocks\n */\n async _formatMultimodalBlock({\n block,\n role,\n }: {\n block: DataBlock;\n role: Msg['role'];\n }): Promise<Record<string, unknown>[]> {\n const type = block.source.mediaType.split('/')[0];\n if (type === 'image') {\n return [\n {\n type: 'image_url',\n image_url: {\n url: await this._toOpenAIImageURL(block),\n },\n },\n ];\n }\n\n if (type === 'audio') {\n // Skip assistant output audio to avoid carrying generated audio back into next request.\n if (role === 'assistant') {\n return [];\n }\n return [\n {\n type: 'input_audio',\n input_audio: await this._toOpenAIAudioData(block),\n },\n ];\n }\n\n console.log(\n `Skip unsupported media type ${block.source.mediaType} in OpenAIChatFormatter. Only image and audio are supported.`\n );\n return [];\n }\n\n /**\n * Convert the data block to an OpenAI compatible image URL.\n * @param block\n * @returns A promise that resolves to a string representing the image URL in a format compatible with OpenAI Chat Completions API.\n */\n protected async _toOpenAIImageURL(block: DataBlock): Promise<string> {\n if (block.source.type === 'base64') {\n return `data:${block.source.mediaType};base64,${block.source.data}`;\n }\n\n const sourceUrl = block.source.url;\n if (sourceUrl.startsWith('http://') || sourceUrl.startsWith('https://')) {\n return sourceUrl;\n }\n if (sourceUrl.startsWith('data:')) {\n return sourceUrl;\n }\n\n const localPath = this._toLocalPath(sourceUrl);\n if (!localPath || !existsSync(localPath)) {\n throw new Error(`Image path not found: ${sourceUrl}`);\n }\n\n const ext = extname(localPath).toLowerCase();\n const supportedImageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp'];\n if (!supportedImageExtensions.includes(ext)) {\n throw new TypeError(\n `Unsupported image extension: ${ext}. Supported: ${supportedImageExtensions.join(', ')}`\n );\n }\n\n const file = await readFile(localPath);\n const mime = block.source.mediaType || `image/${ext.slice(1)}`;\n return `data:${mime};base64,${file.toString('base64')}`;\n }\n\n /**\n * Converts a data block to OpenAI compatible audio data format.\n *\n * @param block - The data block containing audio information.\n * @returns A promise that resolves to an object with audio data and format.\n */\n protected async _toOpenAIAudioData(\n block: DataBlock\n ): Promise<{ data: string; format: 'wav' | 'mp3' }> {\n const supportedMediaTypes = new Map<string, 'wav' | 'mp3'>([\n ['audio/wav', 'wav'],\n ['audio/mp3', 'mp3'],\n ['audio/mpeg', 'mp3'],\n ]);\n\n if (block.source.type === 'base64') {\n const format = supportedMediaTypes.get(block.source.mediaType);\n if (!format) {\n throw new TypeError(\n `Unsupported audio media type: ${block.source.mediaType}, only audio/wav and audio/mp3 are supported.`\n );\n }\n return { data: block.source.data, format };\n }\n\n const sourceUrl = block.source.url;\n const localPath = this._toLocalPath(sourceUrl);\n let data: string;\n\n if (localPath && existsSync(localPath)) {\n const file = await readFile(localPath);\n data = file.toString('base64');\n } else if (sourceUrl.startsWith('http://') || sourceUrl.startsWith('https://')) {\n const response = await fetch(sourceUrl);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch audio from URL: ${sourceUrl} (${response.status})`\n );\n }\n const arr = await response.arrayBuffer();\n data = Buffer.from(arr).toString('base64');\n } else {\n throw new Error(\n `Unsupported audio source: ${sourceUrl}, it should be a local file path, file URL, or an HTTP URL.`\n );\n }\n\n const ext = extname(localPath || sourceUrl).toLowerCase();\n const extToFormat = new Map<string, 'wav' | 'mp3'>([\n ['.wav', 'wav'],\n ['.mp3', 'mp3'],\n ]);\n const format = extToFormat.get(ext);\n if (!format) {\n throw new TypeError(`Unsupported audio extension: ${ext}, wav and mp3 are supported.`);\n }\n\n return { data, format };\n }\n\n /**\n * Converts a URL or path to a local file path.\n *\n * @param urlOrPath - The URL or path to convert.\n * @returns The local file path, or null if not a local path.\n */\n protected _toLocalPath(urlOrPath: string) {\n if (urlOrPath.startsWith('file://')) {\n return fileURLToPath(urlOrPath);\n }\n if (!urlOrPath.includes('://')) {\n return urlOrPath;\n }\n return null;\n }\n}\n"],"mappings":"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","names":["format"]}
|
|
1
|
+
{"version":3,"sources":["../../src/message/message.ts","../../src/formatter/base.ts","../../src/formatter/dashscope-chat-formatter.ts","../../src/formatter/deepseek-chat-formatter.ts","../../src/formatter/ollama-chat-formatter.ts","../../src/formatter/openai-chat-formatter.ts"],"sourcesContent":["import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n Base64Source,\n URLSource,\n} from './block';\nimport { AgentEvent, EventType } from '../event';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n created_at: string;\n /** ISO-8601 finished timestamp. */\n finished_at?: string | null;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `created_at` when omitted.\n * A plain string `content` is automatically wrapped in a single {@link TextBlock}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.finished_at\n * @param root0.usage\n * @returns A Msg object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n finished_at,\n usage,\n}: Omit<Msg, 'id' | 'created_at' | 'metadata' | 'content'> &\n Partial<Pick<Msg, 'id' | 'created_at' | 'metadata'>> & {\n content: string | ContentBlock[];\n }): Msg {\n const contentBlocks: ContentBlock[] =\n typeof content === 'string'\n ? [{ id: crypto.randomUUID(), type: 'text', text: content } as TextBlock]\n : content;\n return { id, name, role, content: contentBlocks, metadata, created_at, finished_at, usage };\n}\n\n/**\n * Create a user {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'user'.\n */\nexport function UserMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'user', metadata, id, created_at });\n}\n\n/**\n * Create an assistant {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.usage\n * @returns A Msg object with role 'assistant'.\n */\nexport function AssistantMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n usage,\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n usage?: Msg['usage'];\n}): Msg {\n return createMsg({ name, content, role: 'assistant', metadata, id, created_at, usage });\n}\n\n/**\n * Create a system {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'system'.\n */\nexport function SystemMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'system', metadata, id, created_at });\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) return null;\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n\n/**\n * Find a content block by type and id within a message.\n * @param msg\n * @param blockType\n * @param blockId\n * @returns The matching {@link ContentBlock}, or `undefined` if not found.\n */\nfunction findBlock(msg: Msg, blockType: string, blockId: string): ContentBlock | undefined {\n return msg.content.find(block => block.type === blockType && block.id === blockId);\n}\n\n/**\n * Apply a streaming {@link AgentEvent} to a {@link Msg}, mutating it in place.\n *\n * Only `content` and `finished_at` are ever modified. Events whose\n * `reply_id` does not match `msg.id` are skipped with a warning.\n * @param msg\n * @param event\n * @returns The mutated {@link Msg} object.\n */\nexport function appendEvent(msg: Msg, event: AgentEvent): Msg {\n if (!('reply_id' in event)) return msg;\n if (event.reply_id !== msg.id) {\n console.warn(\n `Event reply_id \"${event.reply_id}\" does not match message id \"${msg.id}\", skipping.`\n );\n return msg;\n }\n\n switch (event.type) {\n case EventType.REPLY_END:\n msg.finished_at = event.created_at;\n break;\n\n case EventType.TEXT_BLOCK_START:\n msg.content.push({ type: 'text', id: event.block_id, text: '' });\n break;\n\n case EventType.TEXT_BLOCK_DELTA: {\n const block = findBlock(msg, 'text', event.block_id);\n if (!block) {\n console.warn(`TextBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as TextBlock).text += event.delta;\n }\n break;\n }\n\n case EventType.TEXT_BLOCK_END:\n break;\n\n case EventType.THINKING_BLOCK_START:\n msg.content.push({ type: 'thinking', id: event.block_id, thinking: '' });\n break;\n\n case EventType.THINKING_BLOCK_DELTA: {\n const block = findBlock(msg, 'thinking', event.block_id);\n if (!block) {\n console.warn(`ThinkingBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as ThinkingBlock).thinking += event.delta;\n }\n break;\n }\n\n case EventType.THINKING_BLOCK_END:\n break;\n\n case EventType.DATA_BLOCK_START:\n msg.content.push({\n type: 'data',\n id: event.block_id,\n source: { type: 'base64', data: '', media_type: event.media_type },\n });\n break;\n\n case EventType.DATA_BLOCK_DELTA: {\n const block = findBlock(msg, 'data', event.block_id);\n if (!block) {\n console.warn(`DataBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n ((block as DataBlock).source as Base64Source).data += event.data;\n }\n break;\n }\n\n case EventType.DATA_BLOCK_END:\n break;\n\n case EventType.TOOL_CALL_START:\n msg.content.push({\n type: 'tool_call',\n id: event.tool_call_id,\n name: event.tool_call_name,\n input: '',\n state: 'pending',\n });\n break;\n\n case EventType.TOOL_CALL_DELTA: {\n const block = findBlock(msg, 'tool_call', event.tool_call_id);\n if (!block) {\n console.warn(`ToolCallBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolCallBlock).input += event.delta;\n }\n break;\n }\n\n case EventType.TOOL_CALL_END:\n break;\n\n case EventType.TOOL_RESULT_START:\n msg.content.push({\n type: 'tool_result',\n id: event.tool_call_id,\n name: event.tool_call_name,\n output: [],\n state: 'running',\n });\n break;\n\n case EventType.TOOL_RESULT_TEXT_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const last = trb.output[trb.output.length - 1];\n if (!last || last.type !== 'text') {\n trb.output.push({\n type: 'text',\n id: event.block_id ?? crypto.randomUUID(),\n text: event.delta,\n });\n } else {\n (last as TextBlock).text += event.delta;\n }\n }\n break;\n }\n\n case EventType.TOOL_RESULT_DATA_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const source: Base64Source | URLSource =\n event.data != null\n ? { type: 'base64', data: event.data, media_type: event.media_type }\n : { type: 'url', url: event.url!, media_type: event.media_type };\n trb.output.push({ type: 'data', id: event.block_id, source });\n }\n break;\n }\n\n case EventType.TOOL_RESULT_END: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolResultBlock).state = event.state;\n }\n break;\n }\n\n case EventType.REQUIRE_USER_CONFIRM:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'asking';\n }\n break;\n\n case EventType.USER_CONFIRM_RESULT:\n for (const result of event.confirm_results) {\n const b = findBlock(msg, 'tool_call', result.tool_call.id);\n if (b) {\n (b as ToolCallBlock).state = result.confirmed ? 'allowed' : 'finished';\n }\n }\n break;\n\n case EventType.REQUIRE_EXTERNAL_EXECUTION:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'submitted';\n }\n break;\n\n case EventType.EXTERNAL_EXECUTION_RESULT:\n for (const result of event.execution_results) {\n msg.content.push(result);\n }\n break;\n }\n\n return msg;\n}\n","import { Msg, TextBlock, DataBlock, createMsg } from '../message';\n\n/**\n * Base class for message formatters.\n */\nexport abstract class FormatterBase {\n /**\n * Format the input message objects into the required format by the API.\n *\n * @param root0\n * @param root0.msgs - An array of message objects to be formatted.\n * @returns A promise that resolves to an array of formatted message objects.\n */\n abstract format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]>;\n\n /**\n * Convert the tool output to string format for the LLM APIs that only accept text input. If\n * `promoteMultimodalToolResult` is true, the multimodal content will be promoted to be a user message with\n * \"<system-info></system-info>\" tags. Otherwise, the multimodal content will be saved to a storage and a URL link\n * will be provided in the text output.\n *\n * @param output - The tool output, which can be a string or an array of content blocks.\n * @param promoteMultimodalToolResult - Whether to promote the multimodal content to the prompt messages.\n * @returns An object containing the text output and an optional promoted message.\n */\n convertToolOutputToString(\n output: string | (TextBlock | DataBlock)[],\n promoteMultimodalToolResult: boolean | { image?: boolean; audio?: boolean; video?: boolean }\n ) {\n if (typeof output === 'string') return { text: output, promotedMsg: null };\n\n let textualOutput = [];\n\n const promotedData: { id: string; block: DataBlock }[] = [];\n\n for (const block of output) {\n switch (block.type) {\n case 'text':\n textualOutput.push(block.text);\n break;\n default:\n const type = block.source.media_type.split('/')[0];\n if (type !== 'image' && type !== 'audio' && type !== 'video') {\n console.log(\n `Unsupported media type '${block.source.media_type}' in tool output. Only image, audio and video are supported.`\n );\n break;\n }\n if (block.source.type === 'url') {\n textualOutput.push(\n `<system-info>One returned ${type} can be found at: ${block.source.url}</system-info>`\n );\n } else {\n // If we should promote the multimodal content to the prompt messages\n const shouldPromote =\n promoteMultimodalToolResult === true ||\n (typeof promoteMultimodalToolResult === 'object' &&\n promoteMultimodalToolResult[type]);\n\n if (shouldPromote) {\n // Create an ID for the multimodal content first, which should less than 10 characters\n const dataID = Math.random().toString(36).substring(2, 10);\n textualOutput.push(\n `<system-info>One returned ${type} is embedded with ID '${dataID}' and will be attached within '<system-info></system-info>' tags later.</system-info>`\n );\n\n // Record the promoted data\n promotedData.push({ id: dataID, block });\n } else {\n // TODO: save locally\n\n // Save to storage and provide URL link\n textualOutput.push(`The returned ${block.type} is stored locally.`);\n }\n }\n }\n }\n\n // Attach prefix and suffix system-info tags if there are promoted blocks\n const promotedBlocks: (TextBlock | DataBlock)[] = [];\n promotedData.forEach(({ id, block }) => {\n const type = block.source.media_type.split('/')[0];\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `<${type}_data id='${id}'>`,\n });\n promotedBlocks.push(block);\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `</${type}_data>\\n`,\n });\n });\n\n if (promotedBlocks.length > 0) {\n // The prefix\n const prefix =\n '<system-info>The multimodal contents returned from the tool call are as follows:\\n';\n\n if (promotedBlocks[0].type === 'text') {\n promotedBlocks[0].text = `${prefix}${promotedBlocks[0].text}`;\n } else {\n promotedBlocks.unshift({\n id: crypto.randomUUID(),\n type: 'text',\n text: `${prefix}`,\n });\n }\n\n // The suffix\n const lastBlock = promotedBlocks[promotedBlocks.length - 1];\n if (lastBlock.type === 'text') {\n promotedBlocks[promotedBlocks.length - 1] = {\n id: crypto.randomUUID(),\n type: 'text',\n text: `${lastBlock.text}</system-info>`,\n };\n } else {\n promotedBlocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: `</system-info>`,\n });\n }\n }\n\n return {\n text: textualOutput.join('\\n'),\n promotedMsg: createMsg({ name: 'user', content: promotedBlocks, role: 'user' }),\n };\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, TextBlock, getContentBlocks } from '../message';\nimport { DataBlock } from '../message';\n\ninterface DashScopeFormatterOptions {\n /**\n * Since DashScope API doesn't support multimodal tool outputs, this option indicates whether to\n * promote the multimodal tool results to the prompt messages, so that LLMs can see them.\n * Note you should ensure your model supports the corresponding modalities.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n *\n */\nexport class DashScopeChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initialize a DashScopeChatFormatter instance.\n *\n * @param promoteMultimodalToolResult - Since DashScope API doesn't support multimodal tool outputs, this option\n * indicates whether to promote the multimodal tool results to the prompt messages, so that LLMs can see them.\n * Note you should ensure your model supports the corresponding modalities.\n * @param promoteMultimodalToolResult.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: DashScopeFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input message objects into the required format by DashScope API.\n *\n * @param msgs - An array of Msg instances to be formatted.\n * @param msgs.msgs\n * @returns A promise that resolves to an array of formatted message objects.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n content: Record<string, unknown>[];\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n content: [],\n };\n\n // The cached messages that should be pushed after the current message, to keep the order of messages correct.\n const cachedMsgs = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n formattedMsg.content.push(this._formatTextBlock(block));\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg) {\n // Insert the promoted message into the array as the next message to be processed\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n formattedMsg.content.push(...this._formatMultimodalBlock(block));\n break;\n }\n }\n if (formattedMsg.content.length > 0 || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n // Process next message\n index++;\n }\n return formattedMsgs;\n }\n\n /**\n * Format a text content block into the required format.\n *\n * @param block - The text content block to format.\n * @returns An object representing the formatted text content.\n */\n _formatTextBlock(block: TextBlock) {\n return { text: block.text };\n }\n\n /**\n * Format a multimodal data block into the required format.\n * In DashScope API, the local file paths should be prefixed with \"file://\". URLs are kept unchanged.\n *\n * @param block - The multimodal content block to format.\n * @returns An object representing the formatted multimodal content.\n */\n _formatMultimodalBlock(block: DataBlock) {\n const type = block.source.media_type.split('/')[0];\n\n if (!['image', 'audio', 'video'].includes(type)) {\n console.log(\n `Skip unsupported media type ${block.source.media_type} in DashScopeChatFormatter. Only image, audio and video are supported.`\n );\n return [];\n }\n\n if (block.source.type === 'url') {\n return [{ [type]: block.source.url }];\n }\n\n return [\n {\n [type]: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n ];\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, getContentBlocks } from '../message';\n\ninterface DeepSeekFormatterOptions {\n /**\n * Most LLM APIs don't support multimodal tool outputs, this option controls whether to\n * promote multimodal tool results to follow-up user messages.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n * Format AgentScope message objects into DeepSeek Chat Completions message format.\n */\nexport class DeepSeekChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initializes a new instance of the DeepSeekChatFormatter class.\n * @param root0\n * @param root0.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: DeepSeekFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input messages into the structure expected by DeepSeek Chat Completions API.\n * @param root0\n * @param root0.msgs\n * @returns An array of formatted message objects ready to be sent to the DeepSeek API.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n name: string;\n content: Record<string, unknown>[] | null;\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n name: msg.name,\n content: null,\n };\n const content: Record<string, unknown>[] = [];\n\n // Cache tool-result messages to keep the sequence right after current message.\n const cachedMsgs: Record<string, unknown>[] = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n content.push({\n type: 'text',\n text: block.text,\n });\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg?.content.length) {\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n console.warn(\n `DeepSeek models don't support multimodal data for now (2026-03), skip the data block in message content.`\n );\n break;\n }\n }\n\n if (content.length > 0) {\n formattedMsg.content = content;\n }\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n index++;\n }\n\n return formattedMsgs;\n }\n}\n","import { FormatterBase } from './base';\nimport { Msg, getContentBlocks, getTextContent } from '../message';\n\n/**\n * Format AgentScope message objects into Ollama Chat message format.\n * Ollama expects simple string content, not the multimodal array format.\n */\nexport class OllamaChatFormatter extends FormatterBase {\n // eslint-disable-next-line jsdoc/require-returns\n /**\n * Format messages for Ollama API\n * @param root0\n * @param root0.msgs\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n\n for (const msg of msgs) {\n const formattedMsg: {\n role: string;\n content: string;\n tool_calls?: {\n function: {\n name: string;\n arguments: Record<string, unknown>;\n };\n }[];\n } = {\n role: msg.role,\n content: '',\n };\n\n // Extract text content\n const textContent = getTextContent(msg);\n if (textContent) {\n formattedMsg.content = textContent;\n }\n\n // Handle tool calls\n const toolCalls = getContentBlocks(msg, 'tool_call');\n if (toolCalls.length > 0) {\n formattedMsg.tool_calls = toolCalls.map(toolCall => ({\n function: {\n name: toolCall.name,\n arguments: JSON.parse(toolCall.input),\n },\n }));\n }\n\n // Handle tool results\n const toolResults = getContentBlocks(msg, 'tool_result');\n for (const toolResult of toolResults) {\n const resultText = this.convertToolOutputToString(toolResult.output, false);\n formattedMsgs.push({\n role: 'tool',\n content: resultText.text,\n });\n }\n\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n }\n\n return formattedMsgs;\n }\n}\n","import { existsSync } from 'fs';\nimport { readFile } from 'fs/promises';\nimport { extname } from 'path';\nimport { fileURLToPath } from 'url';\n\nimport { FormatterBase } from './base';\nimport { DataBlock, Msg, TextBlock, getContentBlocks } from '../message';\n\ninterface OpenAIFormatterOptions {\n /**\n * Most LLM APIs don't support multimodal tool outputs, this option controls whether to\n * promote multimodal tool results to follow-up user messages.\n */\n promoteMultimodalToolResult?:\n | {\n image?: boolean;\n audio?: boolean;\n video?: boolean;\n }\n | boolean;\n}\n\n/**\n * Format AgentScope message objects into OpenAI Chat Completions message format.\n */\nexport class OpenAIChatFormatter extends FormatterBase {\n private promoteMultimodalToolResult:\n | { image?: boolean; audio?: boolean; video?: boolean }\n | boolean;\n\n /**\n * Initializes a new instance of the OpenAIChatFormatter class.\n * @param root0\n * @param root0.promoteMultimodalToolResult\n */\n constructor({ promoteMultimodalToolResult = false }: OpenAIFormatterOptions = {}) {\n super();\n this.promoteMultimodalToolResult = promoteMultimodalToolResult;\n }\n\n /**\n * Format the input messages into OpenAI Chat Completions message format.\n * @param root0\n * @param root0.msgs\n * @returns An array of formatted messages compatible with OpenAI Chat Completions API.\n */\n async format({ msgs }: { msgs: Array<Msg> }): Promise<Record<string, unknown>[]> {\n const formattedMsgs: Array<Record<string, unknown>> = [];\n let index = 0;\n\n while (index < msgs.length) {\n const msg = msgs[index];\n const formattedMsg: {\n role: string;\n name: string;\n content: Record<string, unknown>[] | null;\n tool_calls?: {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }[];\n } = {\n role: msg.role,\n name: msg.name,\n content: null,\n };\n const content: Record<string, unknown>[] = [];\n\n // Cache tool-result messages to keep the sequence right after current message.\n const cachedMsgs: Record<string, unknown>[] = [];\n for (const block of getContentBlocks(msg)) {\n switch (block.type) {\n case 'text':\n content.push(this._formatTextBlock(block));\n break;\n case 'thinking':\n break;\n case 'tool_call':\n if (!formattedMsg.tool_calls) {\n formattedMsg.tool_calls = [];\n }\n formattedMsg.tool_calls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: block.input,\n },\n });\n break;\n case 'tool_result':\n const formattedToolResult = this.convertToolOutputToString(\n block.output,\n this.promoteMultimodalToolResult\n );\n cachedMsgs.push({\n role: 'tool',\n tool_call_id: block.id,\n name: block.name,\n content: formattedToolResult.text,\n });\n if (formattedToolResult.promotedMsg?.content.length) {\n msgs.splice(index + 1, 0, formattedToolResult.promotedMsg);\n }\n break;\n case 'data':\n content.push(\n ...(await this._formatMultimodalBlock({ block, role: msg.role }))\n );\n break;\n }\n }\n\n if (content.length > 0) {\n formattedMsg.content = content;\n }\n if (formattedMsg.content || formattedMsg.tool_calls) {\n formattedMsgs.push(formattedMsg);\n }\n if (cachedMsgs.length > 0) {\n formattedMsgs.push(...cachedMsgs);\n }\n\n index++;\n }\n\n return formattedMsgs;\n }\n\n /**\n * Format a text block into OpenAI Chat Completions message content format.\n * @param block\n * @returns An object representing the formatted text block.\n */\n _formatTextBlock(block: TextBlock) {\n return {\n type: 'text',\n text: block.text,\n };\n }\n\n /**\n * Format a multimodal data block into OpenAI Chat Completions message content format.\n * @param root0\n * @param root0.block\n * @param root0.role\n * @returns The formatted content blocks\n */\n async _formatMultimodalBlock({\n block,\n role,\n }: {\n block: DataBlock;\n role: Msg['role'];\n }): Promise<Record<string, unknown>[]> {\n const type = block.source.media_type.split('/')[0];\n if (type === 'image') {\n return [\n {\n type: 'image_url',\n image_url: {\n url: await this._toOpenAIImageURL(block),\n },\n },\n ];\n }\n\n if (type === 'audio') {\n // Skip assistant output audio to avoid carrying generated audio back into next request.\n if (role === 'assistant') {\n return [];\n }\n return [\n {\n type: 'input_audio',\n input_audio: await this._toOpenAIAudioData(block),\n },\n ];\n }\n\n console.log(\n `Skip unsupported media type ${block.source.media_type} in OpenAIChatFormatter. Only image and audio are supported.`\n );\n return [];\n }\n\n /**\n * Convert the data block to an OpenAI compatible image URL.\n * @param block\n * @returns A promise that resolves to a string representing the image URL in a format compatible with OpenAI Chat Completions API.\n */\n protected async _toOpenAIImageURL(block: DataBlock): Promise<string> {\n if (block.source.type === 'base64') {\n return `data:${block.source.media_type};base64,${block.source.data}`;\n }\n\n const sourceUrl = block.source.url;\n if (sourceUrl.startsWith('http://') || sourceUrl.startsWith('https://')) {\n return sourceUrl;\n }\n if (sourceUrl.startsWith('data:')) {\n return sourceUrl;\n }\n\n const localPath = this._toLocalPath(sourceUrl);\n if (!localPath || !existsSync(localPath)) {\n throw new Error(`Image path not found: ${sourceUrl}`);\n }\n\n const ext = extname(localPath).toLowerCase();\n const supportedImageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp'];\n if (!supportedImageExtensions.includes(ext)) {\n throw new TypeError(\n `Unsupported image extension: ${ext}. Supported: ${supportedImageExtensions.join(', ')}`\n );\n }\n\n const file = await readFile(localPath);\n const mime = block.source.media_type || `image/${ext.slice(1)}`;\n return `data:${mime};base64,${file.toString('base64')}`;\n }\n\n /**\n * Converts a data block to OpenAI compatible audio data format.\n *\n * @param block - The data block containing audio information.\n * @returns A promise that resolves to an object with audio data and format.\n */\n protected async _toOpenAIAudioData(\n block: DataBlock\n ): Promise<{ data: string; format: 'wav' | 'mp3' }> {\n const supportedMediaTypes = new Map<string, 'wav' | 'mp3'>([\n ['audio/wav', 'wav'],\n ['audio/mp3', 'mp3'],\n ['audio/mpeg', 'mp3'],\n ]);\n\n if (block.source.type === 'base64') {\n const format = supportedMediaTypes.get(block.source.media_type);\n if (!format) {\n throw new TypeError(\n `Unsupported audio media type: ${block.source.media_type}, only audio/wav and audio/mp3 are supported.`\n );\n }\n return { data: block.source.data, format };\n }\n\n const sourceUrl = block.source.url;\n const localPath = this._toLocalPath(sourceUrl);\n let data: string;\n\n if (localPath && existsSync(localPath)) {\n const file = await readFile(localPath);\n data = file.toString('base64');\n } else if (sourceUrl.startsWith('http://') || sourceUrl.startsWith('https://')) {\n const response = await fetch(sourceUrl);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch audio from URL: ${sourceUrl} (${response.status})`\n );\n }\n const arr = await response.arrayBuffer();\n data = Buffer.from(arr).toString('base64');\n } else {\n throw new Error(\n `Unsupported audio source: ${sourceUrl}, it should be a local file path, file URL, or an HTTP URL.`\n );\n }\n\n const ext = extname(localPath || sourceUrl).toLowerCase();\n const extToFormat = new Map<string, 'wav' | 'mp3'>([\n ['.wav', 'wav'],\n ['.mp3', 'mp3'],\n ]);\n const format = extToFormat.get(ext);\n if (!format) {\n throw new TypeError(`Unsupported audio extension: ${ext}, wav and mp3 are supported.`);\n }\n\n return { data, format };\n }\n\n /**\n * Converts a URL or path to a local file path.\n *\n * @param urlOrPath - The URL or path to convert.\n * @returns The local file path, or null if not a local path.\n */\n protected _toLocalPath(urlOrPath: string) {\n if (urlOrPath.startsWith('file://')) {\n return fileURLToPath(urlOrPath);\n }\n if (!urlOrPath.includes('://')) {\n return urlOrPath;\n }\n return null;\n }\n}\n"],"mappings":"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","names":["format"]}
|
|
@@ -4,7 +4,7 @@ import { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/
|
|
|
4
4
|
import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
5
5
|
import z$1, { z } from 'zod';
|
|
6
6
|
import { J as JSONSerializableObject, b as ToolInputSchema } from './index-CAxQAkiP.js';
|
|
7
|
-
import { T as TextBlock, D as DataBlock } from './block-
|
|
7
|
+
import { T as TextBlock, D as DataBlock } from './block-B72uPF1H.js';
|
|
8
8
|
import { StdioServerParameters } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -4,7 +4,7 @@ import { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/
|
|
|
4
4
|
import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
5
5
|
import z$1, { z } from 'zod';
|
|
6
6
|
import { J as JSONSerializableObject, b as ToolInputSchema } from './index-CAxQAkiP.mjs';
|
|
7
|
-
import { T as TextBlock, D as DataBlock } from './block-
|
|
7
|
+
import { T as TextBlock, D as DataBlock } from './block-B72uPF1H.mjs';
|
|
8
8
|
import { StdioServerParameters } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
9
9
|
|
|
10
10
|
/**
|
package/dist/mcp/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { H as HTTPMCPClient, S as StdioMCPClient } from '../index-
|
|
1
|
+
export { H as HTTPMCPClient, S as StdioMCPClient } from '../index-UQCwdfet.mjs';
|
|
2
2
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
3
3
|
import '@modelcontextprotocol/sdk/client/sse.js';
|
|
4
4
|
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
5
5
|
import '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '../index-CAxQAkiP.mjs';
|
|
8
|
-
import '../block-
|
|
8
|
+
import '../block-B72uPF1H.mjs';
|
|
9
9
|
import '@modelcontextprotocol/sdk/client/stdio.js';
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { H as HTTPMCPClient, S as StdioMCPClient } from '../index-
|
|
1
|
+
export { H as HTTPMCPClient, S as StdioMCPClient } from '../index-BNfyKbQN.js';
|
|
2
2
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
3
3
|
import '@modelcontextprotocol/sdk/client/sse.js';
|
|
4
4
|
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
5
5
|
import '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '../index-CAxQAkiP.js';
|
|
8
|
-
import '../block-
|
|
8
|
+
import '../block-B72uPF1H.js';
|
|
9
9
|
import '@modelcontextprotocol/sdk/client/stdio.js';
|
package/dist/mcp/index.js
CHANGED
|
@@ -116,7 +116,7 @@ var MCPTool = class {
|
|
|
116
116
|
content.push({
|
|
117
117
|
id: crypto.randomUUID(),
|
|
118
118
|
type: "data",
|
|
119
|
-
source: { type: "base64",
|
|
119
|
+
source: { type: "base64", media_type: item.mimeType, data: item.data }
|
|
120
120
|
});
|
|
121
121
|
} else {
|
|
122
122
|
console.warn(
|
package/dist/mcp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/index.ts","../../src/mcp/http.ts","../../src/mcp/base.ts","../../src/tool/response.ts","../../src/mcp/stdio.ts"],"sourcesContent":["export * from './http';\nexport * from './stdio';\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n SSEClientTransport,\n SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The HTTP MCP client class that connects to an MCP server using either Streamable HTTP or Server-Sent Events (SSE)\n * transport.\n * Note the client is stateful, meaning that developers should manually call the `connect()` and `close()` methods to\n * manage the connection lifecycle.\n */\nexport class HTTPMCPClient {\n name: string;\n private requestOptions?: RequestOptions;\n private client?: Client;\n private transport?: StreamableHTTPClientTransport | SSEClientTransport;\n private transportType: 'streamable-http' | 'sse';\n private url: string;\n private transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n private stateful: boolean;\n\n /**\n * Initialize the HTTPStatefulMCPClient with the specified transport type, URL, and options.\n *\n * @param root0\n * @param root0.name\n * @param root0.transportType\n * @param root0.url\n * @param root0.stateful\n * @param root0.transportOpts\n * @param root0.requestOptions\n */\n constructor({\n name,\n transportType,\n url,\n stateful = true,\n transportOpts,\n requestOptions,\n }: {\n name: string;\n transportType: 'streamable-http' | 'sse';\n url: string;\n stateful?: boolean;\n transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n requestOptions?: RequestOptions;\n }) {\n this.name = name;\n this.transportType = transportType;\n this.transportOpts = transportOpts;\n this.requestOptions = requestOptions;\n this.url = url;\n this.stateful = stateful;\n }\n\n /**\n * Connect to the MCP server with the specified transport and URL. This method must be called before making any\n * requests to the server.\n */\n async connect() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'connect()' method explicitly.`\n );\n } else {\n await this._connect();\n }\n }\n\n /**\n * The internal method to establish the connection to the MCP server. It initializes the appropriate transport\n * based on the specified transport type and creates a new Client instance to manage the connection and requests.\n */\n protected async _connect() {\n const baseUrl = new URL(this.url);\n if (this.transportType === 'streamable-http') {\n this.transport = new StreamableHTTPClientTransport(baseUrl, this.transportOpts);\n } else {\n this.transport = new SSEClientTransport(baseUrl, this.transportOpts);\n }\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport, this.requestOptions);\n console.log(`MCP client '${this.name}' is connected`);\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n let listClient: Client;\n\n if (this.stateful) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n listClient = this.client;\n } else {\n listClient = await this._createClient();\n }\n\n try {\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await listClient.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n if (this.stateful) {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n } else {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: () => this._createClient(),\n releaseClient: async (c: Client) => {\n await c.close();\n },\n });\n }\n });\n } finally {\n if (!this.stateful) {\n await listClient.close();\n }\n }\n }\n\n /**\n * Close the connection to the MCP server and clean up any resources used by the client.\n */\n async close() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'close()' method explicitly.`\n );\n } else {\n await this._close();\n }\n }\n\n /**\n * The internal method to close the connection to the MCP server.\n */\n protected async _close() {\n try {\n await this.client?.close();\n } finally {\n console.log(`MCP client '${this.name} is closed.'`);\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * Create a new client instance without storing it in this.client.\n * Used for stateless operations where each request needs its own client.\n * @returns A new connected Client instance\n */\n protected async _createClient(): Promise<Client> {\n const baseUrl = new URL(this.url);\n const transport =\n this.transportType === 'streamable-http'\n ? new StreamableHTTPClientTransport(baseUrl, this.transportOpts)\n : new SSEClientTransport(baseUrl, this.transportOpts);\n\n const client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await client.connect(transport, this.requestOptions);\n return client;\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (this.stateful && !this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport z from 'zod';\n\nimport { Tool, ToolResponse } from '../tool';\nimport { createToolResponse } from '../tool/response';\nimport { ToolInputSchema } from '../type';\n\n/**\n * Type definition for getting a client instance\n */\ntype GetClient = () => Promise<Client>;\n\n/**\n * Type definition for releasing a client instance\n */\ntype ReleaseClient = (client: Client) => Promise<void>;\n\n/**\n * MCPTool class that wraps an MCP tool and provides a callable interface\n */\nexport class MCPTool implements Tool {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n requireUserConfirm = false;\n call: (input: Record<string, unknown>) => Promise<ToolResponse>;\n\n private getClient: GetClient;\n private releaseClient: ReleaseClient;\n\n /**\n * Initialize an MCPTool instance\n * @param root0\n * @param root0.name\n * @param root0.description\n * @param root0.inputSchema\n * @param root0.getClient\n * @param root0.releaseClient\n */\n constructor({\n name,\n description,\n inputSchema,\n getClient,\n releaseClient,\n }: {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n getClient: GetClient;\n releaseClient: ReleaseClient;\n }) {\n this.name = name;\n this.description = description;\n this.inputSchema = inputSchema;\n this.getClient = getClient;\n this.releaseClient = releaseClient;\n this.call = this._call.bind(this);\n }\n\n /**\n * Call the MCP tool with the specified input arguments. This method sends a request to the MCP server to execute\n * the tool and returns the result as a ToolResponse.\n *\n * @param arguments\n * @param input\n * @returns A ToolResponse object containing the result of the tool execution, or an error message if the call fails.\n */\n async _call(input: Record<string, unknown>) {\n const client = await this.getClient();\n try {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: this.name,\n arguments: input,\n },\n };\n const result = await client.request(request, CallToolResultSchema);\n\n const content: ToolResponse['content'] = [];\n result.content.forEach(item => {\n if (item.type === 'text') {\n content.push({ type: 'text', text: item.text, id: crypto.randomUUID() });\n } else if (item.type === 'image' || item.type === 'audio') {\n content.push({\n id: crypto.randomUUID(),\n type: 'data',\n source: { type: 'base64', mediaType: item.mimeType, data: item.data },\n });\n } else {\n console.warn(\n `Unsupported content type '${item.type}' in tool result, skipping...`\n );\n }\n });\n return createToolResponse({ content, state: 'success' });\n } catch (error) {\n return createToolResponse({\n content: [\n {\n id: crypto.randomUUID(),\n type: 'text',\n text: `Error calling tool '${this.name}': ${error}`,\n },\n ],\n state: 'error',\n });\n } finally {\n await this.releaseClient(client);\n }\n }\n}\n","import { DataBlock, TextBlock } from '../message';\nimport { JSONSerializableObject } from '../type';\n\n/**\n * The tool response structure.\n */\nexport interface ToolResponse {\n content: Array<TextBlock | DataBlock>;\n id: string;\n createdAt: string;\n metadata: Record<string, JSONSerializableObject>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n isLast: boolean;\n isInterrupted: boolean;\n}\n\n/**\n * Create a tool response object with the given parameters.\n *\n * @param root0\n * @param root0.content\n * @param root0.state\n * @param root0.id\n * @param root0.createdAt\n * @param root0.metadata\n * @param root0.stream\n * @param root0.isLast\n * @param root0.isInterrupted\n * @returns A ToolResponse object\n */\nexport function createToolResponse({\n content,\n state,\n id = crypto.randomUUID(),\n createdAt = new Date().toISOString(),\n metadata = {},\n stream = false,\n isLast = true,\n isInterrupted = false,\n}: {\n content: Array<TextBlock | DataBlock>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n id?: string;\n createdAt?: string;\n metadata?: Record<string, JSONSerializableObject>;\n stream?: boolean;\n isLast?: boolean;\n isInterrupted?: boolean;\n}) {\n return {\n content,\n id,\n createdAt,\n metadata,\n state,\n stream,\n isLast,\n isInterrupted,\n } as ToolResponse;\n}\n\n/**\n * If the given object conforms to the ToolResponse structure.\n *\n * @param obj\n * @returns True if the object is a ToolResponse, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolResponse(obj: any): boolean {\n return (\n obj &&\n typeof obj === 'object' &&\n typeof obj.id === 'string' &&\n typeof obj.createdAt === 'string' &&\n Array.isArray(obj.content) &&\n typeof obj.metadata === 'object' &&\n typeof obj.stream === 'boolean' &&\n typeof obj.isLast === 'boolean' &&\n typeof obj.isInterrupted === 'boolean' &&\n ['success', 'error', 'interrupted', 'running'].includes(obj.state)\n );\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n StdioClientTransport,\n StdioServerParameters,\n} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The STDIO MCP client class.\n */\nexport class StdioMCPClient {\n name: string;\n private stdioServerParameters: StdioServerParameters;\n private transport?: StdioClientTransport;\n private client?: Client;\n\n /**\n * Initialize the StdioMCPClient with the given Stdio parameters.\n *\n * @param root0\n * @param root0.name\n */\n constructor({\n name,\n ...rest\n }: {\n name: string;\n } & StdioServerParameters) {\n this.name = name;\n this.stdioServerParameters = rest;\n }\n\n /**\n * Connect to the MCP server using Stdio transport. Note the Stdio client will start an\n * MCP server process under the hood.\n */\n async connect() {\n this.transport = new StdioClientTransport(this.stdioServerParameters);\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport);\n }\n\n /**\n * Close the connection and stop the MCP server process.\n */\n async close() {\n try {\n if (this.client) {\n await this.client.close();\n }\n } finally {\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await this.client.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n });\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n"],"mappings":"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","names":["import_types","import_client","import_types"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/index.ts","../../src/mcp/http.ts","../../src/mcp/base.ts","../../src/tool/response.ts","../../src/mcp/stdio.ts"],"sourcesContent":["export * from './http';\nexport * from './stdio';\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n SSEClientTransport,\n SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The HTTP MCP client class that connects to an MCP server using either Streamable HTTP or Server-Sent Events (SSE)\n * transport.\n * Note the client is stateful, meaning that developers should manually call the `connect()` and `close()` methods to\n * manage the connection lifecycle.\n */\nexport class HTTPMCPClient {\n name: string;\n private requestOptions?: RequestOptions;\n private client?: Client;\n private transport?: StreamableHTTPClientTransport | SSEClientTransport;\n private transportType: 'streamable-http' | 'sse';\n private url: string;\n private transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n private stateful: boolean;\n\n /**\n * Initialize the HTTPStatefulMCPClient with the specified transport type, URL, and options.\n *\n * @param root0\n * @param root0.name\n * @param root0.transportType\n * @param root0.url\n * @param root0.stateful\n * @param root0.transportOpts\n * @param root0.requestOptions\n */\n constructor({\n name,\n transportType,\n url,\n stateful = true,\n transportOpts,\n requestOptions,\n }: {\n name: string;\n transportType: 'streamable-http' | 'sse';\n url: string;\n stateful?: boolean;\n transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n requestOptions?: RequestOptions;\n }) {\n this.name = name;\n this.transportType = transportType;\n this.transportOpts = transportOpts;\n this.requestOptions = requestOptions;\n this.url = url;\n this.stateful = stateful;\n }\n\n /**\n * Connect to the MCP server with the specified transport and URL. This method must be called before making any\n * requests to the server.\n */\n async connect() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'connect()' method explicitly.`\n );\n } else {\n await this._connect();\n }\n }\n\n /**\n * The internal method to establish the connection to the MCP server. It initializes the appropriate transport\n * based on the specified transport type and creates a new Client instance to manage the connection and requests.\n */\n protected async _connect() {\n const baseUrl = new URL(this.url);\n if (this.transportType === 'streamable-http') {\n this.transport = new StreamableHTTPClientTransport(baseUrl, this.transportOpts);\n } else {\n this.transport = new SSEClientTransport(baseUrl, this.transportOpts);\n }\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport, this.requestOptions);\n console.log(`MCP client '${this.name}' is connected`);\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n let listClient: Client;\n\n if (this.stateful) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n listClient = this.client;\n } else {\n listClient = await this._createClient();\n }\n\n try {\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await listClient.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n if (this.stateful) {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n } else {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: () => this._createClient(),\n releaseClient: async (c: Client) => {\n await c.close();\n },\n });\n }\n });\n } finally {\n if (!this.stateful) {\n await listClient.close();\n }\n }\n }\n\n /**\n * Close the connection to the MCP server and clean up any resources used by the client.\n */\n async close() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'close()' method explicitly.`\n );\n } else {\n await this._close();\n }\n }\n\n /**\n * The internal method to close the connection to the MCP server.\n */\n protected async _close() {\n try {\n await this.client?.close();\n } finally {\n console.log(`MCP client '${this.name} is closed.'`);\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * Create a new client instance without storing it in this.client.\n * Used for stateless operations where each request needs its own client.\n * @returns A new connected Client instance\n */\n protected async _createClient(): Promise<Client> {\n const baseUrl = new URL(this.url);\n const transport =\n this.transportType === 'streamable-http'\n ? new StreamableHTTPClientTransport(baseUrl, this.transportOpts)\n : new SSEClientTransport(baseUrl, this.transportOpts);\n\n const client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await client.connect(transport, this.requestOptions);\n return client;\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (this.stateful && !this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport z from 'zod';\n\nimport { Tool, ToolResponse } from '../tool';\nimport { createToolResponse } from '../tool/response';\nimport { ToolInputSchema } from '../type';\n\n/**\n * Type definition for getting a client instance\n */\ntype GetClient = () => Promise<Client>;\n\n/**\n * Type definition for releasing a client instance\n */\ntype ReleaseClient = (client: Client) => Promise<void>;\n\n/**\n * MCPTool class that wraps an MCP tool and provides a callable interface\n */\nexport class MCPTool implements Tool {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n requireUserConfirm = false;\n call: (input: Record<string, unknown>) => Promise<ToolResponse>;\n\n private getClient: GetClient;\n private releaseClient: ReleaseClient;\n\n /**\n * Initialize an MCPTool instance\n * @param root0\n * @param root0.name\n * @param root0.description\n * @param root0.inputSchema\n * @param root0.getClient\n * @param root0.releaseClient\n */\n constructor({\n name,\n description,\n inputSchema,\n getClient,\n releaseClient,\n }: {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n getClient: GetClient;\n releaseClient: ReleaseClient;\n }) {\n this.name = name;\n this.description = description;\n this.inputSchema = inputSchema;\n this.getClient = getClient;\n this.releaseClient = releaseClient;\n this.call = this._call.bind(this);\n }\n\n /**\n * Call the MCP tool with the specified input arguments. This method sends a request to the MCP server to execute\n * the tool and returns the result as a ToolResponse.\n *\n * @param arguments\n * @param input\n * @returns A ToolResponse object containing the result of the tool execution, or an error message if the call fails.\n */\n async _call(input: Record<string, unknown>) {\n const client = await this.getClient();\n try {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: this.name,\n arguments: input,\n },\n };\n const result = await client.request(request, CallToolResultSchema);\n\n const content: ToolResponse['content'] = [];\n result.content.forEach(item => {\n if (item.type === 'text') {\n content.push({ type: 'text', text: item.text, id: crypto.randomUUID() });\n } else if (item.type === 'image' || item.type === 'audio') {\n content.push({\n id: crypto.randomUUID(),\n type: 'data',\n source: { type: 'base64', media_type: item.mimeType, data: item.data },\n });\n } else {\n console.warn(\n `Unsupported content type '${item.type}' in tool result, skipping...`\n );\n }\n });\n return createToolResponse({ content, state: 'success' });\n } catch (error) {\n return createToolResponse({\n content: [\n {\n id: crypto.randomUUID(),\n type: 'text',\n text: `Error calling tool '${this.name}': ${error}`,\n },\n ],\n state: 'error',\n });\n } finally {\n await this.releaseClient(client);\n }\n }\n}\n","import { DataBlock, TextBlock } from '../message';\nimport { JSONSerializableObject } from '../type';\n\n/**\n * The tool response structure.\n */\nexport interface ToolResponse {\n content: Array<TextBlock | DataBlock>;\n id: string;\n createdAt: string;\n metadata: Record<string, JSONSerializableObject>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n isLast: boolean;\n isInterrupted: boolean;\n}\n\n/**\n * Create a tool response object with the given parameters.\n *\n * @param root0\n * @param root0.content\n * @param root0.state\n * @param root0.id\n * @param root0.createdAt\n * @param root0.metadata\n * @param root0.stream\n * @param root0.isLast\n * @param root0.isInterrupted\n * @returns A ToolResponse object\n */\nexport function createToolResponse({\n content,\n state,\n id = crypto.randomUUID(),\n createdAt = new Date().toISOString(),\n metadata = {},\n stream = false,\n isLast = true,\n isInterrupted = false,\n}: {\n content: Array<TextBlock | DataBlock>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n id?: string;\n createdAt?: string;\n metadata?: Record<string, JSONSerializableObject>;\n stream?: boolean;\n isLast?: boolean;\n isInterrupted?: boolean;\n}) {\n return {\n content,\n id,\n createdAt,\n metadata,\n state,\n stream,\n isLast,\n isInterrupted,\n } as ToolResponse;\n}\n\n/**\n * If the given object conforms to the ToolResponse structure.\n *\n * @param obj\n * @returns True if the object is a ToolResponse, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolResponse(obj: any): boolean {\n return (\n obj &&\n typeof obj === 'object' &&\n typeof obj.id === 'string' &&\n typeof obj.createdAt === 'string' &&\n Array.isArray(obj.content) &&\n typeof obj.metadata === 'object' &&\n typeof obj.stream === 'boolean' &&\n typeof obj.isLast === 'boolean' &&\n typeof obj.isInterrupted === 'boolean' &&\n ['success', 'error', 'interrupted', 'running'].includes(obj.state)\n );\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n StdioClientTransport,\n StdioServerParameters,\n} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The STDIO MCP client class.\n */\nexport class StdioMCPClient {\n name: string;\n private stdioServerParameters: StdioServerParameters;\n private transport?: StdioClientTransport;\n private client?: Client;\n\n /**\n * Initialize the StdioMCPClient with the given Stdio parameters.\n *\n * @param root0\n * @param root0.name\n */\n constructor({\n name,\n ...rest\n }: {\n name: string;\n } & StdioServerParameters) {\n this.name = name;\n this.stdioServerParameters = rest;\n }\n\n /**\n * Connect to the MCP server using Stdio transport. Note the Stdio client will start an\n * MCP server process under the hood.\n */\n async connect() {\n this.transport = new StdioClientTransport(this.stdioServerParameters);\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport);\n }\n\n /**\n * Close the connection and stop the MCP server process.\n */\n async close() {\n try {\n if (this.client) {\n await this.client.close();\n }\n } finally {\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await this.client.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n });\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n"],"mappings":"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","names":["import_types","import_client","import_types"]}
|
package/dist/mcp/index.mjs
CHANGED
|
@@ -91,7 +91,7 @@ var MCPTool = class {
|
|
|
91
91
|
content.push({
|
|
92
92
|
id: crypto.randomUUID(),
|
|
93
93
|
type: "data",
|
|
94
|
-
source: { type: "base64",
|
|
94
|
+
source: { type: "base64", media_type: item.mimeType, data: item.data }
|
|
95
95
|
});
|
|
96
96
|
} else {
|
|
97
97
|
console.warn(
|
package/dist/mcp/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/http.ts","../../src/mcp/base.ts","../../src/tool/response.ts","../../src/mcp/stdio.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n SSEClientTransport,\n SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The HTTP MCP client class that connects to an MCP server using either Streamable HTTP or Server-Sent Events (SSE)\n * transport.\n * Note the client is stateful, meaning that developers should manually call the `connect()` and `close()` methods to\n * manage the connection lifecycle.\n */\nexport class HTTPMCPClient {\n name: string;\n private requestOptions?: RequestOptions;\n private client?: Client;\n private transport?: StreamableHTTPClientTransport | SSEClientTransport;\n private transportType: 'streamable-http' | 'sse';\n private url: string;\n private transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n private stateful: boolean;\n\n /**\n * Initialize the HTTPStatefulMCPClient with the specified transport type, URL, and options.\n *\n * @param root0\n * @param root0.name\n * @param root0.transportType\n * @param root0.url\n * @param root0.stateful\n * @param root0.transportOpts\n * @param root0.requestOptions\n */\n constructor({\n name,\n transportType,\n url,\n stateful = true,\n transportOpts,\n requestOptions,\n }: {\n name: string;\n transportType: 'streamable-http' | 'sse';\n url: string;\n stateful?: boolean;\n transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n requestOptions?: RequestOptions;\n }) {\n this.name = name;\n this.transportType = transportType;\n this.transportOpts = transportOpts;\n this.requestOptions = requestOptions;\n this.url = url;\n this.stateful = stateful;\n }\n\n /**\n * Connect to the MCP server with the specified transport and URL. This method must be called before making any\n * requests to the server.\n */\n async connect() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'connect()' method explicitly.`\n );\n } else {\n await this._connect();\n }\n }\n\n /**\n * The internal method to establish the connection to the MCP server. It initializes the appropriate transport\n * based on the specified transport type and creates a new Client instance to manage the connection and requests.\n */\n protected async _connect() {\n const baseUrl = new URL(this.url);\n if (this.transportType === 'streamable-http') {\n this.transport = new StreamableHTTPClientTransport(baseUrl, this.transportOpts);\n } else {\n this.transport = new SSEClientTransport(baseUrl, this.transportOpts);\n }\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport, this.requestOptions);\n console.log(`MCP client '${this.name}' is connected`);\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n let listClient: Client;\n\n if (this.stateful) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n listClient = this.client;\n } else {\n listClient = await this._createClient();\n }\n\n try {\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await listClient.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n if (this.stateful) {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n } else {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: () => this._createClient(),\n releaseClient: async (c: Client) => {\n await c.close();\n },\n });\n }\n });\n } finally {\n if (!this.stateful) {\n await listClient.close();\n }\n }\n }\n\n /**\n * Close the connection to the MCP server and clean up any resources used by the client.\n */\n async close() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'close()' method explicitly.`\n );\n } else {\n await this._close();\n }\n }\n\n /**\n * The internal method to close the connection to the MCP server.\n */\n protected async _close() {\n try {\n await this.client?.close();\n } finally {\n console.log(`MCP client '${this.name} is closed.'`);\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * Create a new client instance without storing it in this.client.\n * Used for stateless operations where each request needs its own client.\n * @returns A new connected Client instance\n */\n protected async _createClient(): Promise<Client> {\n const baseUrl = new URL(this.url);\n const transport =\n this.transportType === 'streamable-http'\n ? new StreamableHTTPClientTransport(baseUrl, this.transportOpts)\n : new SSEClientTransport(baseUrl, this.transportOpts);\n\n const client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await client.connect(transport, this.requestOptions);\n return client;\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (this.stateful && !this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport z from 'zod';\n\nimport { Tool, ToolResponse } from '../tool';\nimport { createToolResponse } from '../tool/response';\nimport { ToolInputSchema } from '../type';\n\n/**\n * Type definition for getting a client instance\n */\ntype GetClient = () => Promise<Client>;\n\n/**\n * Type definition for releasing a client instance\n */\ntype ReleaseClient = (client: Client) => Promise<void>;\n\n/**\n * MCPTool class that wraps an MCP tool and provides a callable interface\n */\nexport class MCPTool implements Tool {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n requireUserConfirm = false;\n call: (input: Record<string, unknown>) => Promise<ToolResponse>;\n\n private getClient: GetClient;\n private releaseClient: ReleaseClient;\n\n /**\n * Initialize an MCPTool instance\n * @param root0\n * @param root0.name\n * @param root0.description\n * @param root0.inputSchema\n * @param root0.getClient\n * @param root0.releaseClient\n */\n constructor({\n name,\n description,\n inputSchema,\n getClient,\n releaseClient,\n }: {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n getClient: GetClient;\n releaseClient: ReleaseClient;\n }) {\n this.name = name;\n this.description = description;\n this.inputSchema = inputSchema;\n this.getClient = getClient;\n this.releaseClient = releaseClient;\n this.call = this._call.bind(this);\n }\n\n /**\n * Call the MCP tool with the specified input arguments. This method sends a request to the MCP server to execute\n * the tool and returns the result as a ToolResponse.\n *\n * @param arguments\n * @param input\n * @returns A ToolResponse object containing the result of the tool execution, or an error message if the call fails.\n */\n async _call(input: Record<string, unknown>) {\n const client = await this.getClient();\n try {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: this.name,\n arguments: input,\n },\n };\n const result = await client.request(request, CallToolResultSchema);\n\n const content: ToolResponse['content'] = [];\n result.content.forEach(item => {\n if (item.type === 'text') {\n content.push({ type: 'text', text: item.text, id: crypto.randomUUID() });\n } else if (item.type === 'image' || item.type === 'audio') {\n content.push({\n id: crypto.randomUUID(),\n type: 'data',\n source: { type: 'base64', mediaType: item.mimeType, data: item.data },\n });\n } else {\n console.warn(\n `Unsupported content type '${item.type}' in tool result, skipping...`\n );\n }\n });\n return createToolResponse({ content, state: 'success' });\n } catch (error) {\n return createToolResponse({\n content: [\n {\n id: crypto.randomUUID(),\n type: 'text',\n text: `Error calling tool '${this.name}': ${error}`,\n },\n ],\n state: 'error',\n });\n } finally {\n await this.releaseClient(client);\n }\n }\n}\n","import { DataBlock, TextBlock } from '../message';\nimport { JSONSerializableObject } from '../type';\n\n/**\n * The tool response structure.\n */\nexport interface ToolResponse {\n content: Array<TextBlock | DataBlock>;\n id: string;\n createdAt: string;\n metadata: Record<string, JSONSerializableObject>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n isLast: boolean;\n isInterrupted: boolean;\n}\n\n/**\n * Create a tool response object with the given parameters.\n *\n * @param root0\n * @param root0.content\n * @param root0.state\n * @param root0.id\n * @param root0.createdAt\n * @param root0.metadata\n * @param root0.stream\n * @param root0.isLast\n * @param root0.isInterrupted\n * @returns A ToolResponse object\n */\nexport function createToolResponse({\n content,\n state,\n id = crypto.randomUUID(),\n createdAt = new Date().toISOString(),\n metadata = {},\n stream = false,\n isLast = true,\n isInterrupted = false,\n}: {\n content: Array<TextBlock | DataBlock>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n id?: string;\n createdAt?: string;\n metadata?: Record<string, JSONSerializableObject>;\n stream?: boolean;\n isLast?: boolean;\n isInterrupted?: boolean;\n}) {\n return {\n content,\n id,\n createdAt,\n metadata,\n state,\n stream,\n isLast,\n isInterrupted,\n } as ToolResponse;\n}\n\n/**\n * If the given object conforms to the ToolResponse structure.\n *\n * @param obj\n * @returns True if the object is a ToolResponse, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolResponse(obj: any): boolean {\n return (\n obj &&\n typeof obj === 'object' &&\n typeof obj.id === 'string' &&\n typeof obj.createdAt === 'string' &&\n Array.isArray(obj.content) &&\n typeof obj.metadata === 'object' &&\n typeof obj.stream === 'boolean' &&\n typeof obj.isLast === 'boolean' &&\n typeof obj.isInterrupted === 'boolean' &&\n ['success', 'error', 'interrupted', 'running'].includes(obj.state)\n );\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n StdioClientTransport,\n StdioServerParameters,\n} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The STDIO MCP client class.\n */\nexport class StdioMCPClient {\n name: string;\n private stdioServerParameters: StdioServerParameters;\n private transport?: StdioClientTransport;\n private client?: Client;\n\n /**\n * Initialize the StdioMCPClient with the given Stdio parameters.\n *\n * @param root0\n * @param root0.name\n */\n constructor({\n name,\n ...rest\n }: {\n name: string;\n } & StdioServerParameters) {\n this.name = name;\n this.stdioServerParameters = rest;\n }\n\n /**\n * Connect to the MCP server using Stdio transport. Note the Stdio client will start an\n * MCP server process under the hood.\n */\n async connect() {\n this.transport = new StdioClientTransport(this.stdioServerParameters);\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport);\n }\n\n /**\n * Close the connection and stop the MCP server process.\n */\n async close() {\n try {\n if (this.client) {\n await this.client.close();\n }\n } finally {\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await this.client.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n });\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n"],"mappings":";AAAA,SAAS,cAAc;AACvB;AAAA,EACI;AAAA,OAEG;AACP,SAAS,qCAAqC;AAG9C,SAA2B,6BAAmC;;;ACP9D,SAA0B,4BAA4B;;;AC6B/C,SAAS,mBAAmB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,KAAK,OAAO,WAAW;AAAA,EACvB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACnC,WAAW,CAAC;AAAA,EACZ,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AACpB,GASG;AACC,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;ADtCO,IAAM,UAAN,MAA8B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EAEQ;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWR,YAAY;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,GAMG;AACC,SAAK,OAAO;AACZ,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,OAAO,KAAK,MAAM,KAAK,IAAI;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,OAAgC;AACxC,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACA,YAAM,UAA2B;AAAA,QAC7B,QAAQ;AAAA,QACR,QAAQ;AAAA,UACJ,MAAM,KAAK;AAAA,UACX,WAAW;AAAA,QACf;AAAA,MACJ;AACA,YAAM,SAAS,MAAM,OAAO,QAAQ,SAAS,oBAAoB;AAEjE,YAAM,UAAmC,CAAC;AAC1C,aAAO,QAAQ,QAAQ,UAAQ;AAC3B,YAAI,KAAK,SAAS,QAAQ;AACtB,kBAAQ,KAAK,EAAE,MAAM,QAAQ,MAAM,KAAK,MAAM,IAAI,OAAO,WAAW,EAAE,CAAC;AAAA,QAC3E,WAAW,KAAK,SAAS,WAAW,KAAK,SAAS,SAAS;AACvD,kBAAQ,KAAK;AAAA,YACT,IAAI,OAAO,WAAW;AAAA,YACtB,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,UAAU,WAAW,KAAK,UAAU,MAAM,KAAK,KAAK;AAAA,UACxE,CAAC;AAAA,QACL,OAAO;AACH,kBAAQ;AAAA,YACJ,6BAA6B,KAAK,IAAI;AAAA,UAC1C;AAAA,QACJ;AAAA,MACJ,CAAC;AACD,aAAO,mBAAmB,EAAE,SAAS,OAAO,UAAU,CAAC;AAAA,IAC3D,SAAS,OAAO;AACZ,aAAO,mBAAmB;AAAA,QACtB,SAAS;AAAA,UACL;AAAA,YACI,IAAI,OAAO,WAAW;AAAA,YACtB,MAAM;AAAA,YACN,MAAM,uBAAuB,KAAK,IAAI,MAAM,KAAK;AAAA,UACrD;AAAA,QACJ;AAAA,QACA,OAAO;AAAA,MACX,CAAC;AAAA,IACL,UAAE;AACE,YAAM,KAAK,cAAc,MAAM;AAAA,IACnC;AAAA,EACJ;AACJ;;;AD/FO,IAAM,gBAAN,MAAoB;AAAA,EACvB;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaR,YAAY;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACJ,GAOG;AACC,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,MAAM;AACX,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU;AACZ,QAAI,CAAC,KAAK,UAAU;AAChB,cAAQ;AAAA,QACJ,eAAe,KAAK,IAAI;AAAA,MAC5B;AAAA,IACJ,OAAO;AACH,YAAM,KAAK,SAAS;AAAA,IACxB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,WAAW;AACvB,UAAM,UAAU,IAAI,IAAI,KAAK,GAAG;AAChC,QAAI,KAAK,kBAAkB,mBAAmB;AAC1C,WAAK,YAAY,IAAI,8BAA8B,SAAS,KAAK,aAAa;AAAA,IAClF,OAAO;AACH,WAAK,YAAY,IAAI,mBAAmB,SAAS,KAAK,aAAa;AAAA,IACvE;AACA,SAAK,SAAS,IAAI,OAAO;AAAA,MACrB,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,IACb,CAAC;AACD,UAAM,KAAK,OAAO,QAAQ,KAAK,WAAW,KAAK,cAAc;AAC7D,YAAQ,IAAI,eAAe,KAAK,IAAI,gBAAgB;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAgC;AAClC,QAAI;AAEJ,QAAI,KAAK,UAAU;AACf,UAAI,CAAC,KAAK,QAAQ;AACd,cAAM,IAAI;AAAA,UACN,mFAAmF,KAAK,IAAI;AAAA,QAChG;AAAA,MACJ;AACA,mBAAa,KAAK;AAAA,IACtB,OAAO;AACH,mBAAa,MAAM,KAAK,cAAc;AAAA,IAC1C;AAEA,QAAI;AACA,YAAM,eAAiC;AAAA,QACnC,QAAQ;AAAA,QACR,QAAQ,CAAC;AAAA,MACb;AAEA,YAAM,cAAc,MAAM,WAAW,QAAQ,cAAc,qBAAqB;AAChF,UAAI,YAAY,UAAU,QAAW;AACjC,eAAO,CAAC;AAAA,MACZ;AAEA,aAAO,YAAY,MAAM,IAAI,CAAC,SAAe;AACzC,YAAI,KAAK,UAAU;AACf,iBAAO,IAAI,QAAQ;AAAA,YACf,MAAM,KAAK;AAAA,YACX,aAAa,KAAK,eAAe;AAAA,YACjC,aAAa,KAAK;AAAA,YAClB,WAAW,YAAY,KAAK;AAAA,YAC5B,eAAe,YAAY;AAAA,YAAC;AAAA,UAChC,CAAC;AAAA,QACL,OAAO;AACH,iBAAO,IAAI,QAAQ;AAAA,YACf,MAAM,KAAK;AAAA,YACX,aAAa,KAAK,eAAe;AAAA,YACjC,aAAa,KAAK;AAAA,YAClB,WAAW,MAAM,KAAK,cAAc;AAAA,YACpC,eAAe,OAAO,MAAc;AAChC,oBAAM,EAAE,MAAM;AAAA,YAClB;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAAA,IACL,UAAE;AACE,UAAI,CAAC,KAAK,UAAU;AAChB,cAAM,WAAW,MAAM;AAAA,MAC3B;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ;AACV,QAAI,CAAC,KAAK,UAAU;AAChB,cAAQ;AAAA,QACJ,eAAe,KAAK,IAAI;AAAA,MAC5B;AAAA,IACJ,OAAO;AACH,YAAM,KAAK,OAAO;AAAA,IACtB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,SAAS;AACrB,QAAI;AACA,YAAM,KAAK,QAAQ,MAAM;AAAA,IAC7B,UAAE;AACE,cAAQ,IAAI,eAAe,KAAK,IAAI,cAAc;AAClD,WAAK,SAAS;AACd,WAAK,YAAY;AAAA,IACrB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,gBAAiC;AAC7C,UAAM,UAAU,IAAI,IAAI,KAAK,GAAG;AAChC,UAAM,YACF,KAAK,kBAAkB,oBACjB,IAAI,8BAA8B,SAAS,KAAK,aAAa,IAC7D,IAAI,mBAAmB,SAAS,KAAK,aAAa;AAE5D,UAAM,SAAS,IAAI,OAAO;AAAA,MACtB,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,IACb,CAAC;AACD,UAAM,OAAO,QAAQ,WAAW,KAAK,cAAc;AACnD,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,EAAE,KAAK,GAAqB;AAClD,QAAI,KAAK,YAAY,CAAC,KAAK,QAAQ;AAC/B,YAAM,IAAI;AAAA,QACN,mFAAmF,KAAK,IAAI;AAAA,MAChG;AAAA,IACJ;AAEA,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,aAAa,MAAM,KAAK,UAAQ,KAAK,SAAS,IAAI;AAExD,QAAI,CAAC,YAAY;AACb,YAAM,IAAI;AAAA,QACN,SAAS,IAAI,8BAA8B,KAAK,IAAI,uBAAuB,MAAM,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MAChH;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;;;AG/NA,SAAS,UAAAA,eAAc;AACvB;AAAA,EACI;AAAA,OAEG;AACP,SAA2B,yBAAAC,8BAAmC;AAOvD,IAAM,iBAAN,MAAqB;AAAA,EACxB;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,YAAY;AAAA,IACR;AAAA,IACA,GAAG;AAAA,EACP,GAE2B;AACvB,SAAK,OAAO;AACZ,SAAK,wBAAwB;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU;AACZ,SAAK,YAAY,IAAI,qBAAqB,KAAK,qBAAqB;AACpE,SAAK,SAAS,IAAIC,QAAO;AAAA,MACrB,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,IACb,CAAC;AACD,UAAM,KAAK,OAAO,QAAQ,KAAK,SAAS;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ;AACV,QAAI;AACA,UAAI,KAAK,QAAQ;AACb,cAAM,KAAK,OAAO,MAAM;AAAA,MAC5B;AAAA,IACJ,UAAE;AACE,WAAK,SAAS;AACd,WAAK,YAAY;AAAA,IACrB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAgC;AAClC,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,IAAI;AAAA,QACN,mFAAmF,KAAK,IAAI;AAAA,MAChG;AAAA,IACJ;AAEA,UAAM,eAAiC;AAAA,MACnC,QAAQ;AAAA,MACR,QAAQ,CAAC;AAAA,IACb;AAEA,UAAM,cAAc,MAAM,KAAK,OAAO,QAAQ,cAAcC,sBAAqB;AACjF,QAAI,YAAY,UAAU,QAAW;AACjC,aAAO,CAAC;AAAA,IACZ;AAEA,WAAO,YAAY,MAAM,IAAI,CAAC,SAAe;AACzC,aAAO,IAAI,QAAQ;AAAA,QACf,MAAM,KAAK;AAAA,QACX,aAAa,KAAK,eAAe;AAAA,QACjC,aAAa,KAAK;AAAA,QAClB,WAAW,YAAY,KAAK;AAAA,QAC5B,eAAe,YAAY;AAAA,QAAC;AAAA,MAChC,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,EAAE,KAAK,GAAqB;AAClD,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,IAAI;AAAA,QACN,mFAAmF,KAAK,IAAI;AAAA,MAChG;AAAA,IACJ;AAEA,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,aAAa,MAAM,KAAK,UAAQ,KAAK,SAAS,IAAI;AAExD,QAAI,CAAC,YAAY;AACb,YAAM,IAAI;AAAA,QACN,SAAS,IAAI,8BAA8B,KAAK,IAAI,uBAAuB,MAAM,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MAChH;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;","names":["Client","ListToolsResultSchema","Client","ListToolsResultSchema"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/http.ts","../../src/mcp/base.ts","../../src/tool/response.ts","../../src/mcp/stdio.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n SSEClientTransport,\n SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The HTTP MCP client class that connects to an MCP server using either Streamable HTTP or Server-Sent Events (SSE)\n * transport.\n * Note the client is stateful, meaning that developers should manually call the `connect()` and `close()` methods to\n * manage the connection lifecycle.\n */\nexport class HTTPMCPClient {\n name: string;\n private requestOptions?: RequestOptions;\n private client?: Client;\n private transport?: StreamableHTTPClientTransport | SSEClientTransport;\n private transportType: 'streamable-http' | 'sse';\n private url: string;\n private transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n private stateful: boolean;\n\n /**\n * Initialize the HTTPStatefulMCPClient with the specified transport type, URL, and options.\n *\n * @param root0\n * @param root0.name\n * @param root0.transportType\n * @param root0.url\n * @param root0.stateful\n * @param root0.transportOpts\n * @param root0.requestOptions\n */\n constructor({\n name,\n transportType,\n url,\n stateful = true,\n transportOpts,\n requestOptions,\n }: {\n name: string;\n transportType: 'streamable-http' | 'sse';\n url: string;\n stateful?: boolean;\n transportOpts?: StreamableHTTPClientTransportOptions | SSEClientTransportOptions;\n requestOptions?: RequestOptions;\n }) {\n this.name = name;\n this.transportType = transportType;\n this.transportOpts = transportOpts;\n this.requestOptions = requestOptions;\n this.url = url;\n this.stateful = stateful;\n }\n\n /**\n * Connect to the MCP server with the specified transport and URL. This method must be called before making any\n * requests to the server.\n */\n async connect() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'connect()' method explicitly.`\n );\n } else {\n await this._connect();\n }\n }\n\n /**\n * The internal method to establish the connection to the MCP server. It initializes the appropriate transport\n * based on the specified transport type and creates a new Client instance to manage the connection and requests.\n */\n protected async _connect() {\n const baseUrl = new URL(this.url);\n if (this.transportType === 'streamable-http') {\n this.transport = new StreamableHTTPClientTransport(baseUrl, this.transportOpts);\n } else {\n this.transport = new SSEClientTransport(baseUrl, this.transportOpts);\n }\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport, this.requestOptions);\n console.log(`MCP client '${this.name}' is connected`);\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n let listClient: Client;\n\n if (this.stateful) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n listClient = this.client;\n } else {\n listClient = await this._createClient();\n }\n\n try {\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await listClient.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n if (this.stateful) {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n } else {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: () => this._createClient(),\n releaseClient: async (c: Client) => {\n await c.close();\n },\n });\n }\n });\n } finally {\n if (!this.stateful) {\n await listClient.close();\n }\n }\n }\n\n /**\n * Close the connection to the MCP server and clean up any resources used by the client.\n */\n async close() {\n if (!this.stateful) {\n console.log(\n `MCP client '${this.name}' initialized with stateful=false will connect and close the connection automatically for each request, no need to call 'close()' method explicitly.`\n );\n } else {\n await this._close();\n }\n }\n\n /**\n * The internal method to close the connection to the MCP server.\n */\n protected async _close() {\n try {\n await this.client?.close();\n } finally {\n console.log(`MCP client '${this.name} is closed.'`);\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * Create a new client instance without storing it in this.client.\n * Used for stateless operations where each request needs its own client.\n * @returns A new connected Client instance\n */\n protected async _createClient(): Promise<Client> {\n const baseUrl = new URL(this.url);\n const transport =\n this.transportType === 'streamable-http'\n ? new StreamableHTTPClientTransport(baseUrl, this.transportOpts)\n : new SSEClientTransport(baseUrl, this.transportOpts);\n\n const client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await client.connect(transport, this.requestOptions);\n return client;\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (this.stateful && !this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport z from 'zod';\n\nimport { Tool, ToolResponse } from '../tool';\nimport { createToolResponse } from '../tool/response';\nimport { ToolInputSchema } from '../type';\n\n/**\n * Type definition for getting a client instance\n */\ntype GetClient = () => Promise<Client>;\n\n/**\n * Type definition for releasing a client instance\n */\ntype ReleaseClient = (client: Client) => Promise<void>;\n\n/**\n * MCPTool class that wraps an MCP tool and provides a callable interface\n */\nexport class MCPTool implements Tool {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n requireUserConfirm = false;\n call: (input: Record<string, unknown>) => Promise<ToolResponse>;\n\n private getClient: GetClient;\n private releaseClient: ReleaseClient;\n\n /**\n * Initialize an MCPTool instance\n * @param root0\n * @param root0.name\n * @param root0.description\n * @param root0.inputSchema\n * @param root0.getClient\n * @param root0.releaseClient\n */\n constructor({\n name,\n description,\n inputSchema,\n getClient,\n releaseClient,\n }: {\n name: string;\n description: string;\n inputSchema: z.ZodObject | ToolInputSchema;\n getClient: GetClient;\n releaseClient: ReleaseClient;\n }) {\n this.name = name;\n this.description = description;\n this.inputSchema = inputSchema;\n this.getClient = getClient;\n this.releaseClient = releaseClient;\n this.call = this._call.bind(this);\n }\n\n /**\n * Call the MCP tool with the specified input arguments. This method sends a request to the MCP server to execute\n * the tool and returns the result as a ToolResponse.\n *\n * @param arguments\n * @param input\n * @returns A ToolResponse object containing the result of the tool execution, or an error message if the call fails.\n */\n async _call(input: Record<string, unknown>) {\n const client = await this.getClient();\n try {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: this.name,\n arguments: input,\n },\n };\n const result = await client.request(request, CallToolResultSchema);\n\n const content: ToolResponse['content'] = [];\n result.content.forEach(item => {\n if (item.type === 'text') {\n content.push({ type: 'text', text: item.text, id: crypto.randomUUID() });\n } else if (item.type === 'image' || item.type === 'audio') {\n content.push({\n id: crypto.randomUUID(),\n type: 'data',\n source: { type: 'base64', media_type: item.mimeType, data: item.data },\n });\n } else {\n console.warn(\n `Unsupported content type '${item.type}' in tool result, skipping...`\n );\n }\n });\n return createToolResponse({ content, state: 'success' });\n } catch (error) {\n return createToolResponse({\n content: [\n {\n id: crypto.randomUUID(),\n type: 'text',\n text: `Error calling tool '${this.name}': ${error}`,\n },\n ],\n state: 'error',\n });\n } finally {\n await this.releaseClient(client);\n }\n }\n}\n","import { DataBlock, TextBlock } from '../message';\nimport { JSONSerializableObject } from '../type';\n\n/**\n * The tool response structure.\n */\nexport interface ToolResponse {\n content: Array<TextBlock | DataBlock>;\n id: string;\n createdAt: string;\n metadata: Record<string, JSONSerializableObject>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n isLast: boolean;\n isInterrupted: boolean;\n}\n\n/**\n * Create a tool response object with the given parameters.\n *\n * @param root0\n * @param root0.content\n * @param root0.state\n * @param root0.id\n * @param root0.createdAt\n * @param root0.metadata\n * @param root0.stream\n * @param root0.isLast\n * @param root0.isInterrupted\n * @returns A ToolResponse object\n */\nexport function createToolResponse({\n content,\n state,\n id = crypto.randomUUID(),\n createdAt = new Date().toISOString(),\n metadata = {},\n stream = false,\n isLast = true,\n isInterrupted = false,\n}: {\n content: Array<TextBlock | DataBlock>;\n state: 'success' | 'error' | 'interrupted' | 'running';\n id?: string;\n createdAt?: string;\n metadata?: Record<string, JSONSerializableObject>;\n stream?: boolean;\n isLast?: boolean;\n isInterrupted?: boolean;\n}) {\n return {\n content,\n id,\n createdAt,\n metadata,\n state,\n stream,\n isLast,\n isInterrupted,\n } as ToolResponse;\n}\n\n/**\n * If the given object conforms to the ToolResponse structure.\n *\n * @param obj\n * @returns True if the object is a ToolResponse, false otherwise\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolResponse(obj: any): boolean {\n return (\n obj &&\n typeof obj === 'object' &&\n typeof obj.id === 'string' &&\n typeof obj.createdAt === 'string' &&\n Array.isArray(obj.content) &&\n typeof obj.metadata === 'object' &&\n typeof obj.stream === 'boolean' &&\n typeof obj.isLast === 'boolean' &&\n typeof obj.isInterrupted === 'boolean' &&\n ['success', 'error', 'interrupted', 'running'].includes(obj.state)\n );\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n StdioClientTransport,\n StdioServerParameters,\n} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { ListToolsRequest, ListToolsResultSchema, Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { MCPTool } from './base';\n\n/**\n * The STDIO MCP client class.\n */\nexport class StdioMCPClient {\n name: string;\n private stdioServerParameters: StdioServerParameters;\n private transport?: StdioClientTransport;\n private client?: Client;\n\n /**\n * Initialize the StdioMCPClient with the given Stdio parameters.\n *\n * @param root0\n * @param root0.name\n */\n constructor({\n name,\n ...rest\n }: {\n name: string;\n } & StdioServerParameters) {\n this.name = name;\n this.stdioServerParameters = rest;\n }\n\n /**\n * Connect to the MCP server using Stdio transport. Note the Stdio client will start an\n * MCP server process under the hood.\n */\n async connect() {\n this.transport = new StdioClientTransport(this.stdioServerParameters);\n this.client = new Client({\n name: this.name,\n version: '1.0.0',\n });\n await this.client.connect(this.transport);\n }\n\n /**\n * Close the connection and stop the MCP server process.\n */\n async close() {\n try {\n if (this.client) {\n await this.client.close();\n }\n } finally {\n this.client = undefined;\n this.transport = undefined;\n }\n }\n\n /**\n * List all tools available on the MCP server.\n *\n * @returns An array of MCPTool instances representing the tools available on the server.\n */\n async listTools(): Promise<MCPTool[]> {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const toolsRequest: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const toolsResult = await this.client.request(toolsRequest, ListToolsResultSchema);\n if (toolsResult.tools === undefined) {\n return [];\n }\n\n return toolsResult.tools.map((tool: Tool) => {\n return new MCPTool({\n name: tool.name,\n description: tool.description || '',\n inputSchema: tool.inputSchema,\n getClient: async () => this.client!,\n releaseClient: async () => {},\n });\n });\n }\n\n /**\n * Get a callable function for a specific tool by its name.\n * @param root0\n * @param root0.name\n * @returns An instance of MCPTool that can be called to execute the tool's functionality.\n */\n async getCallableFunction({ name }: { name: string }) {\n if (!this.client) {\n throw new Error(\n `Client not initialized, call 'connect()' method first for the MCP client named '${this.name}'`\n );\n }\n\n const tools = await this.listTools();\n const targetTool = tools.find(tool => tool.name === name);\n\n if (!targetTool) {\n throw new Error(\n `Tool '${name}' not found in MCP server '${this.name}'. Available tools: ${tools.map(t => t.name).join(', ')}`\n );\n }\n\n return targetTool;\n }\n}\n"],"mappings":"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","names":["Client","ListToolsResultSchema","Client","ListToolsResultSchema"]}
|
package/dist/message/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { M as Msg, c as createMsg, g as getContentBlocks,
|
|
2
|
-
export { B as Base64Source, C as ContentBlock, D as DataBlock, T as TextBlock, a as ThinkingBlock, b as ToolCallBlock, c as ToolResultBlock, U as URLSource } from '../block-
|
|
1
|
+
export { A as AssistantMsg, M as Msg, S as SystemMsg, U as UserMsg, a as appendEvent, c as createMsg, g as getContentBlocks, b as getTextContent } from '../message-DgpfAaHK.mjs';
|
|
2
|
+
export { B as Base64Source, C as ContentBlock, D as DataBlock, T as TextBlock, a as ThinkingBlock, b as ToolCallBlock, c as ToolCallState, d as ToolResultBlock, e as ToolResultState, U as URLSource } from '../block-B72uPF1H.mjs';
|
|
3
3
|
import '../index-CAxQAkiP.mjs';
|
|
4
|
+
import '../event/index.mjs';
|
|
4
5
|
|
|
5
6
|
declare enum GenerateReason {
|
|
6
7
|
AWAITING_TOOL_RESULT = "AWAITING_TOOL_RESULT",
|
package/dist/message/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { M as Msg, c as createMsg, g as getContentBlocks,
|
|
2
|
-
export { B as Base64Source, C as ContentBlock, D as DataBlock, T as TextBlock, a as ThinkingBlock, b as ToolCallBlock, c as ToolResultBlock, U as URLSource } from '../block-
|
|
1
|
+
export { A as AssistantMsg, M as Msg, S as SystemMsg, U as UserMsg, a as appendEvent, c as createMsg, g as getContentBlocks, b as getTextContent } from '../message-CPZd0NIc.js';
|
|
2
|
+
export { B as Base64Source, C as ContentBlock, D as DataBlock, T as TextBlock, a as ThinkingBlock, b as ToolCallBlock, c as ToolCallState, d as ToolResultBlock, e as ToolResultState, U as URLSource } from '../block-B72uPF1H.js';
|
|
3
3
|
import '../index-CAxQAkiP.js';
|
|
4
|
+
import '../event/index.js';
|
|
4
5
|
|
|
5
6
|
declare enum GenerateReason {
|
|
6
7
|
AWAITING_TOOL_RESULT = "AWAITING_TOOL_RESULT",
|