@agentscope-ai/agentscope 0.0.5 → 0.0.6

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.
Files changed (44) hide show
  1. package/dist/agent/index.d.mts +4 -4
  2. package/dist/agent/index.d.ts +4 -4
  3. package/dist/agent/index.js +34 -7
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/agent/index.mjs +34 -7
  6. package/dist/agent/index.mjs.map +1 -1
  7. package/dist/{base-qmU135_k.d.ts → base-13VLaOvY.d.ts} +2 -2
  8. package/dist/{base-BI5s2ksj.d.mts → base-Bc3GkNS7.d.mts} +1 -1
  9. package/dist/{base-DHtZCg94.d.ts → base-CJkm56kB.d.ts} +1 -1
  10. package/dist/{base-CFDeoJRe.d.ts → base-Dfizi3RB.d.ts} +1 -1
  11. package/dist/{base-BDyDUIhj.d.mts → base-L72wZVx8.d.mts} +2 -2
  12. package/dist/{base-BB9eTlit.d.mts → base-Ps8E0j1_.d.mts} +1 -1
  13. package/dist/event/index.d.mts +2 -2
  14. package/dist/event/index.d.ts +2 -2
  15. package/dist/event/index.js.map +1 -1
  16. package/dist/event/index.mjs.map +1 -1
  17. package/dist/formatter/index.d.mts +2 -2
  18. package/dist/formatter/index.d.ts +2 -2
  19. package/dist/formatter/index.js +16 -0
  20. package/dist/formatter/index.js.map +1 -1
  21. package/dist/formatter/index.mjs +16 -0
  22. package/dist/formatter/index.mjs.map +1 -1
  23. package/dist/message/index.d.mts +1 -1
  24. package/dist/message/index.d.ts +1 -1
  25. package/dist/message/index.js +50 -14
  26. package/dist/message/index.js.map +1 -1
  27. package/dist/message/index.mjs +50 -14
  28. package/dist/message/index.mjs.map +1 -1
  29. package/dist/{message-D-LObC06.d.mts → message-COpNEf0G.d.mts} +10 -7
  30. package/dist/{message-DU0_qm3u.d.ts → message-DbCMy5tM.d.ts} +10 -7
  31. package/dist/model/index.d.mts +4 -4
  32. package/dist/model/index.d.ts +4 -4
  33. package/dist/model/index.js +16 -0
  34. package/dist/model/index.js.map +1 -1
  35. package/dist/model/index.mjs +16 -0
  36. package/dist/model/index.mjs.map +1 -1
  37. package/dist/storage/index.d.mts +2 -2
  38. package/dist/storage/index.d.ts +2 -2
  39. package/package.json +1 -1
  40. package/src/agent/agent.ts +20 -7
  41. package/src/event/index.ts +2 -2
  42. package/src/message/append-event.test.ts +17 -11
  43. package/src/message/message.test.ts +2 -2
  44. package/src/message/message.ts +77 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/model/index.ts","../../src/message/message.ts","../../src/model/base.ts","../../src/_utils/common.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","../../src/model/dashscope-model.ts","../../src/model/deepseek-model.ts","../../src/model/ollama-model.ts","../../src/model/openai-model.ts"],"sourcesContent":["export { ChatModelBase } from './base';\nexport { ChatResponse } from './response';\nexport { ChatUsage } from './usage';\nexport { DashScopeChatModel } from './dashscope-model';\nexport { DeepSeekChatModel } from './deepseek-model';\nexport { OllamaChatModel } from './ollama-model';\nexport { OpenAIChatModel } from './openai-model';\n","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.MODEL_CALL_END:\n // Accumulated the input and output tokens here.\n if (msg.usage) {\n msg.usage.inputTokens += event.input_tokens;\n msg.usage.outputTokens += event.output_tokens;\n } else {\n msg.usage = {\n inputTokens: event.input_tokens,\n outputTokens: event.output_tokens,\n };\n }\n break;\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) {\n (b as ToolCallBlock).state = 'asking';\n if (tc.suggested_rules !== undefined) {\n (b as ToolCallBlock).suggested_rules = tc.suggested_rules;\n }\n }\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 { z } from 'zod';\n\nimport { ChatResponse, StructuredResponse } from './response';\nimport { FormatterBase } from '../formatter';\nimport { getTextContent, Msg } from '../message';\nimport { ToolChoice, ToolInputSchema, ToolSchema } from '../type';\n\nexport interface ChatModelOptions {\n modelName: string;\n stream?: boolean;\n maxRetries?: number;\n fallbackModelName?: string;\n formatter?: FormatterBase;\n}\n\n// The chat model call options interface\nexport interface ChatModelCallOptions {\n messages: Msg[];\n tools?: ToolSchema[];\n toolChoice?: ToolChoice;\n\n // The additional options can be added as needed\n [key: string]: unknown;\n}\n\nexport interface ChatModelCallStructuredOptions {\n messages: Msg[];\n schema: z.ZodObject;\n}\n\n// Internal API request options after formatting\nexport interface ChatModelRequestOptions<T> {\n messages: T[];\n tools?: ToolSchema[];\n toolChoice?: ToolChoice;\n\n // The additional options can be added as needed\n [key: string]: unknown;\n}\n\n/**\n * The base class for chat models.\n */\nexport abstract class ChatModelBase {\n public modelName: string;\n public stream: boolean;\n public maxRetries: number;\n public fallbackModelName?: string;\n public formatter?: FormatterBase;\n /**\n * Initializes a new instance of the ChatModelBase class.\n *\n * @param options - The chat model options, including model name, streaming option, max retries, fallback\n * model name, and formatter.\n *\n * @param options.modelName\n * @param options.stream\n * @param options.maxRetries\n * @param options.fallbackModelName\n * @param options.formatter\n */\n protected constructor({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter,\n }: ChatModelOptions) {\n this.modelName = modelName;\n this.stream = stream ?? true;\n this.maxRetries = maxRetries ?? 0;\n this.fallbackModelName = fallbackModelName;\n this.formatter = formatter;\n }\n\n /**\n * Calls the chat model with the given messages.\n * This is the main method to interact with the model.\n *\n * @param options - The chat model call options.\n * @returns A promise that resolves to the model's response.\n */\n async call(\n options: ChatModelCallOptions\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse>> {\n // Format messages using the formatter if available\n let formattedMessages: unknown[];\n if (this.formatter) {\n formattedMessages = await this.formatter.format({ msgs: options.messages });\n } else {\n // If no formatter is provided, pass messages as-is\n formattedMessages = options.messages as unknown[];\n }\n\n const requestOptions: ChatModelRequestOptions<unknown> = {\n ...options,\n messages: formattedMessages,\n };\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n return await this._callAPI(this.modelName, requestOptions);\n } catch (error) {\n lastError = error;\n if (attempt === this.maxRetries) {\n throw error;\n } else {\n console.log(\n `Attempt ${attempt + 1} failed for model ${this.modelName}. Retrying...`\n );\n }\n }\n }\n\n // Use the fallback model if specified\n if (this.fallbackModelName) {\n console.log(\n `Using fallback model ${this.fallbackModelName} after ${this.maxRetries} failed attempts.`\n );\n return await this._callAPI(this.fallbackModelName, requestOptions);\n }\n\n // This line should never be reached, but it ensures TypeScript knows the function always returns\n throw lastError;\n }\n\n /**\n * Abstract method to call the underlying API with the given parameters.\n */\n protected abstract _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<unknown>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse>>;\n\n /**\n * Format the AgentScope tool choice parameter to the expected API format.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n abstract _formatToolChoice(toolChoice: ToolChoice): unknown;\n\n /**\n * A heuristic method to count the number of the tokens\n * Note the multimodal content is ignored in the token counting\n * @param options\n * @param options.messages\n * @param options.tools\n * @returns The estimated number of tokens in the input messages and tools.\n */\n async countTokens(options: { messages: Msg[]; tools?: ToolSchema[] }): Promise<number> {\n let accText: string = '';\n for (const msg of options.messages) {\n accText += getTextContent(msg) || '';\n }\n if (options.tools) {\n accText += JSON.stringify(options.tools);\n }\n const chineseMatches =\n accText.match(/[\\u4e00-\\u9fff\\u3400-\\u4dbf\\u{20000}-\\u{2a6df}]/gu)?.length ?? 0;\n const englishMatches = accText.match(/[a-zA-Z]+/g)?.length ?? 0;\n\n return chineseMatches * 2 + englishMatches * 1.5;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n abstract _formatToolSchemas(tools: ToolSchema[]): unknown[];\n\n /**\n * A default implementation of the structured call method. For those supporting structured output, the model should\n * override this method.\n * @param options\n * @returns The structured response from the model, which should conform to the provided Zod schema.\n */\n async callStructured(options: ChatModelCallStructuredOptions): Promise<StructuredResponse> {\n // Prepare a tool schema that wraps the provided Zod schema\n const toolSchema: ToolSchema = {\n type: 'function',\n function: {\n name: 'GenerateStructuredResponse',\n description: 'Generate required structured response by this toll.',\n parameters: options.schema.toJSONSchema({\n target: 'openapi-3.0',\n }) as ToolInputSchema,\n },\n };\n\n const res = await this.call({\n messages: options.messages,\n tools: [toolSchema],\n toolChoice: 'GenerateStructuredResponse',\n });\n\n let completedResponse: ChatResponse;\n if (this.stream) {\n while (true) {\n const { value, done } = await (res as AsyncGenerator<ChatResponse>).next();\n if (done) {\n completedResponse = value;\n break;\n }\n }\n } else {\n completedResponse = res as ChatResponse;\n }\n\n // Find the tool call\n for (const block of completedResponse.content) {\n if (block.type === 'tool_call' && block.name === 'GenerateStructuredResponse') {\n const structuredContent = JSON.parse(block.input);\n return {\n ...completedResponse,\n content: structuredContent,\n type: 'structured',\n } as StructuredResponse;\n }\n }\n\n throw new Error(`Failed to generate the structured response`);\n }\n}\n","import { jsonrepair } from 'jsonrepair';\n\nimport { JSONSerializableObject } from '../type';\n\n/**\n * Creates a timestamp string in the format \"YYYY-MM-DD HH:mm:ss.sss\"\n * representing the current date and time.\n *\n * @returns {string} The formatted timestamp string.\n */\nexport function _createTimestamp(): string {\n return new Date().toISOString().replace('T', ' ').replace('Z', '').substring(0, 23);\n}\n\n/**\n * Attempts to parse a JSON string into a dictionary/Record.\n * This function is used to handle the streaming tool use block from the LLM API.\n *\n * @param input - The JSON string to parse.\n * @returns A dictionary/Record parsed from the JSON string. If parsing fails, returns an empty dictionary.\n */\nexport function _jsonLoadsWithRepair(input: string): Record<string, JSONSerializableObject> {\n try {\n const jsonObj = JSON.parse(input);\n // Check if the jsonObj is a dictionary/Record\n if (typeof jsonObj === 'object' && jsonObj !== null && !Array.isArray(jsonObj)) {\n return jsonObj as Record<string, JSONSerializableObject>;\n } else {\n // Return an empty dictionary\n return {};\n }\n } catch {\n try {\n const repairedString = jsonrepair(input);\n const jsonObj = JSON.parse(repairedString);\n // Check if the jsonObj is a dictionary/Record\n if (typeof jsonObj === 'object' && jsonObj !== null && !Array.isArray(jsonObj)) {\n return jsonObj as Record<string, JSONSerializableObject>;\n } else {\n // Return an empty dictionary\n return {};\n }\n } catch (e) {\n console.error(`Failed to parse JSON \"${input}\" with error:`, e);\n return {};\n }\n }\n}\n\n/**\n * Parses a streamed response from the post request.\n * An async generator that yields parsed JSON objects from the SSE stream.\n *\n * @param response - The fetch response object.\n * @returns An async generator yielding parsed JSON objects.\n */\nexport async function* _parseStreamedResponse<T>(response: Response): AsyncGenerator<T> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response body for streaming.');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Handle the completed line\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep the last uncompleted line\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine || trimmedLine.startsWith(':')) {\n continue; // Skip the empty line and comments\n }\n\n if (trimmedLine.startsWith('data:')) {\n const jsonStr = trimmedLine.slice(5).trim(); // Remove \"data:\" prefix\n\n if (jsonStr === '[DONE]') {\n break;\n }\n\n try {\n const json = JSON.parse(jsonStr);\n yield json;\n } catch (e) {\n console.error('Failed to parse JSON:', e);\n throw new Error(`Failed to parse JSON from stream: ${jsonStr}`);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\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","import { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { _parseStreamedResponse } from '../_utils';\nimport { DashScopeChatFormatter } from '../formatter';\n\ninterface _DashScopeStreamChunk {\n output?: {\n choices: {\n message?: {\n content?: string | { text: string }[];\n reasoning_content?: string;\n tool_calls?: {\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }[];\n };\n }[];\n };\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n}\n\ninterface DashScopeThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n\n /**\n * Maximum tokens for reasoning (optional).\n */\n thinkingBudget?: number;\n}\n\ninterface DashScopeChatModelOptions extends ChatModelOptions {\n /**\n * The API key for authenticating with DashScope API.\n */\n apiKey: string;\n\n /**\n * Thinking configuration for DashScope models.\n */\n thinkingConfig?: DashScopeThinkingConfig;\n\n /**\n * (Deprecated) Use thinkingConfig instead.\n * Whether to enable the \"thinking\" feature in the model.\n */\n enableThinking?: boolean;\n\n /**\n * Whether the model is multimodal or not, this will decide the default API endpoint.\n */\n multimodal?: boolean;\n\n /**\n * Preset generation parameters to include in each request.\n * These parameters will be merged with the request-specific parameters.\n */\n presetGenParams?: Record<string, unknown>;\n\n /**\n * Preset headers that will be included in each request.\n */\n presetHeaders?: Record<string, unknown>;\n}\n\n/**\n * The DashScope API chat model.\n */\nexport class DashScopeChatModel extends ChatModelBase {\n apiURL: string;\n protected apiKey: string;\n protected presetGenParams: Record<string, unknown> | undefined;\n protected presetHeaders: Record<string, unknown> | undefined;\n protected thinkingConfig?: DashScopeThinkingConfig;\n\n /**\n * Initializes a new instance of the DashScopeChatModel class.\n *\n * @param options - The DashScope chat model options.\n * @param options.modelName - The name of the model to use.\n * @param options.apiKey - The API key for authentication.\n * @param options.stream - Whether to use streaming responses. Default is true.\n * @param options.thinkingConfig - The thinking configuration for DashScope models, including whether to enable thinking and the thinking budget.\n * @param options.maxRetries - The maximum number of retries for failed requests. Default is 3.\n * @param options.fallbackModelName - The fallback model name to use if the primary model fails.\n * @param options.presetGenParams - Preset generation parameters to include in each request.\n * @param options.presetHeaders - Preset headers that will be included in each request.\n * @param options.multimodal - Whether the model is multimodal or not, this will decide the default API endpoint. If not provided, it will be inferred from the model name.\n * @param options.formatter - An optional custom formatter. If not provided, a default DashScopeChatFormatter will be used.\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n thinkingConfig,\n maxRetries = 0,\n fallbackModelName,\n presetGenParams,\n presetHeaders,\n multimodal,\n formatter,\n }: DashScopeChatModelOptions) {\n // If no formatter is provided, create a default DashScopeChatFormatter\n const defaultFormatter = formatter || new DashScopeChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.apiKey = apiKey;\n this.thinkingConfig = thinkingConfig;\n this.presetGenParams = presetGenParams;\n this.presetHeaders = presetHeaders;\n\n // Infer the apiURL based on the multimodal option or the model name\n if (multimodal === undefined) {\n // Router according to the model name\n multimodal =\n modelName.includes('vl') ||\n modelName.includes('qwen3.5-plus') ||\n modelName.includes('qvq');\n }\n this.apiURL = multimodal\n ? 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation'\n : 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';\n }\n\n /**\n * Calls the DashScope API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n // Set up request data\n const data = {\n model: modelName,\n input: {\n messages: options.messages,\n },\n parameters: {\n result_format: 'message',\n tools: this._formatToolSchemas(options.tools),\n toolChoice: this._formatToolChoice(options.toolChoice),\n enable_thinking: this.thinkingConfig?.enableThinking ?? false,\n ...(this.thinkingConfig?.thinkingBudget !== undefined && {\n thinking_budget: this.thinkingConfig.thinkingBudget,\n }),\n ...(this.presetGenParams ?? {}),\n incremental_output: true,\n } as Record<string, unknown>,\n };\n\n // Set up headers\n const headers: Record<string, unknown> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.presetHeaders,\n };\n\n // Set up streaming header if needed\n if (this.stream) {\n headers['X-DashScope-SSE'] = 'enable';\n }\n\n // Counting the time cost\n const startTime = Date.now();\n const response = await fetch(this.apiURL, {\n method: 'POST',\n headers: headers as HeadersInit,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n throw new Error(\n `DashScope API request failed with status ${response.status}: ${await response.text()}`\n );\n }\n\n if (this.stream) {\n // Handle the streaming response\n return this._parseDashScopeStreamedResponse(response, startTime);\n }\n\n // Handle the non-streaming response\n const blocks: Array<TextBlock | ToolCallBlock | ThinkingBlock | DataBlock> = [];\n const res = await response.json();\n const choice = res.output.choices[0];\n if (choice.message.reasoning_content) {\n blocks.push({\n type: 'thinking',\n thinking: choice.message.reasoning_content,\n id: crypto.randomUUID(),\n });\n }\n if (choice.message.content) {\n blocks.push({ type: 'text', text: choice.message.content, id: crypto.randomUUID() });\n }\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach((toolCall: object) => {\n if (\n 'id' in toolCall &&\n 'function' in toolCall &&\n typeof toolCall.function === 'object' &&\n toolCall.function &&\n 'name' in toolCall.function &&\n 'arguments' in toolCall.function\n ) {\n const inputString = String(toolCall.function.arguments);\n blocks.push({\n type: 'tool_call',\n id: String(toolCall.id),\n name: String(toolCall.function.name),\n input: inputString,\n state: 'pending',\n });\n }\n });\n }\n\n const usage = res.usage\n ? {\n type: 'chat_usage',\n inputTokens: res.usage.input_tokens || 0,\n outputTokens: res.usage.output_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * The method to format the tool choice parameter.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(toolChoice?: ToolChoice): 'auto' | 'none' | Record<string, unknown> {\n if (toolChoice) {\n if (toolChoice === 'auto') return 'auto';\n if (toolChoice === 'none') return 'none';\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from DashScope API specifically for chat responses.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param response - The fetch response object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseDashScopeStreamedResponse(\n response: Response,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n const asyncGenerator = _parseStreamedResponse<_DashScopeStreamChunk>(response);\n\n let accText: string = '';\n let accThinking: string = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | undefined = undefined;\n\n for await (const jsonObj of asyncGenerator) {\n if (jsonObj.output && jsonObj.output.choices) {\n const choice = jsonObj.output.choices[0];\n\n // Delta data for this chunk\n let deltaText: string = '';\n let deltaThinking: string = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n const content = choice.message?.content;\n if (content) {\n if (typeof content === 'string') {\n deltaText = content;\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (block.text) {\n deltaText += block.text;\n }\n }\n }\n accText += deltaText;\n }\n if (choice.message?.reasoning_content) {\n deltaThinking = choice.message.reasoning_content;\n accThinking += deltaThinking;\n }\n if (choice.message?.tool_calls) {\n choice.message.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool use id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool use name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool use input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._dataToBlocks(deltaText, deltaThinking, deltaToolCalls);\n lastUsage = jsonObj.usage\n ? {\n type: 'chat_usage',\n inputTokens: jsonObj.usage.input_tokens || 0,\n outputTokens: jsonObj.usage.output_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n }\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._dataToBlocks(accText, accThinking, finalToolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param thinking - The thinking response\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _dataToBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ThinkingBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ThinkingBlock | ToolCallBlock)[] = [];\n if (thinking) {\n blocks.push({ type: 'thinking', thinking: thinking, id: crypto.randomUUID() });\n }\n if (text) {\n blocks.push({ type: 'text', text: text, id: crypto.randomUUID() });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { _parseStreamedResponse } from '../_utils';\nimport { DeepSeekChatFormatter } from '../formatter';\n\ninterface _DeepSeekStreamChunk {\n choices?: {\n delta?: {\n content?: string;\n reasoning_content?: string;\n tool_calls?: {\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\ninterface DeepSeekThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n}\n\ninterface DeepSeekChatModelOptions extends ChatModelOptions {\n /**\n * The API key for authenticating with DeepSeek API.\n */\n apiKey: string;\n\n /**\n * Thinking configuration for DeepSeek models.\n */\n thinkingConfig?: DeepSeekThinkingConfig;\n\n /**\n * Preset generation parameters to include in each request.\n * These parameters will be merged with the request-specific parameters.\n */\n presetGenParams?: Record<string, unknown>;\n\n /**\n * Preset headers that will be included in each request.\n */\n presetHeaders?: Record<string, unknown>;\n}\n\n/**\n * The DeepSeek API chat model.\n */\nexport class DeepSeekChatModel extends ChatModelBase {\n apiURL: string;\n protected apiKey: string;\n protected presetGenParams: Record<string, unknown> | undefined;\n protected presetHeaders: Record<string, unknown> | undefined;\n protected thinkingConfig: DeepSeekThinkingConfig;\n\n /**\n * Initializes a new instance of the DeepSeekChatModel class.\n *\n * @param options - The DeepSeek chat model options.\n * @param options.modelName - The name of the model to use.\n * @param options.apiKey - The API key for authentication.\n * @param options.stream - Whether to use streaming responses. Default is true.\n * @param options.thinkingConfig - Thinking configuration.\n * @param options.maxRetries - The maximum number of retries for failed requests. Default is 0.\n * @param options.fallbackModelName - The fallback model name to use if the primary model fails.\n * @param options.presetGenParams - Preset generation parameters to include in each request.\n * @param options.presetHeaders - Preset headers that will be included in each request.\n * @param options.formatter\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n thinkingConfig,\n maxRetries = 0,\n fallbackModelName,\n presetGenParams,\n presetHeaders,\n formatter,\n }: DeepSeekChatModelOptions) {\n // If no formatter is provided, create a default DeepSeekChatFormatter\n const defaultFormatter = formatter || new DeepSeekChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.apiKey = apiKey;\n this.thinkingConfig = thinkingConfig || { enableThinking: false };\n this.presetGenParams = presetGenParams;\n this.presetHeaders = presetHeaders;\n this.apiURL = 'https://api.deepseek.com/chat/completions';\n }\n\n /**\n * Calls the DeepSeek API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n // Set up request data\n const data = {\n model: modelName,\n messages: options.messages,\n tools: this._formatToolSchemas(options.tools),\n tool_choice: this._formatToolChoice(options.toolChoice),\n thinking: this.thinkingConfig.enableThinking\n ? { type: 'enabled' }\n : { type: 'disabled' },\n stream: this.stream,\n ...(this.presetGenParams ?? {}),\n } as Record<string, unknown>;\n\n // Set up headers\n const headers: Record<string, unknown> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.presetHeaders,\n };\n\n // Counting the time cost\n const startTime = Date.now();\n const response = await fetch(this.apiURL, {\n method: 'POST',\n headers: headers as HeadersInit,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n throw new Error(\n `DeepSeek API request failed with status ${response.status}: ${await response.text()}`\n );\n }\n\n if (this.stream) {\n // Handle the streaming response\n return this._parseDeepSeekStreamedResponse(response, startTime);\n }\n\n // Handle the non-streaming response\n const blocks: Array<TextBlock | ToolCallBlock | ThinkingBlock | DataBlock> = [];\n const res = await response.json();\n const choice = res.choices[0];\n\n if (choice.message.reasoning_content) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'thinking',\n thinking: choice.message.reasoning_content,\n });\n }\n if (choice.message.content) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: choice.message.content });\n }\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach((toolCall: object) => {\n if (\n 'id' in toolCall &&\n 'function' in toolCall &&\n typeof toolCall.function === 'object' &&\n toolCall.function &&\n 'name' in toolCall.function &&\n 'arguments' in toolCall.function\n ) {\n const inputString = String(toolCall.function.arguments);\n blocks.push({\n type: 'tool_call',\n id: String(toolCall.id),\n name: String(toolCall.function.name),\n input: inputString,\n state: 'pending',\n });\n }\n });\n }\n\n const usage = res.usage\n ? {\n type: 'chat_usage',\n inputTokens: res.usage.prompt_tokens || 0,\n outputTokens: res.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * The method to format the tool choice parameter.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(\n toolChoice?: ToolChoice\n ): 'auto' | 'none' | 'required' | Record<string, unknown> {\n if (toolChoice) {\n if (toolChoice === 'auto') return 'auto';\n if (toolChoice === 'none') return 'none';\n if (this.thinkingConfig?.enableThinking) {\n console.log(\n `The deepseek reasoning model does not support tool choice options '${toolChoice}'. 'auto' will be used instead.`\n );\n return 'auto';\n }\n if (toolChoice === 'required') return 'required';\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from DeepSeek API specifically for chat responses.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param response - The fetch response object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseDeepSeekStreamedResponse(\n response: Response,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n const asyncGenerator = _parseStreamedResponse<_DeepSeekStreamChunk>(response);\n\n let accText: string = '';\n let accThinking: string = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | undefined = undefined;\n\n for await (const jsonObj of asyncGenerator) {\n if (jsonObj.choices && jsonObj.choices.length > 0) {\n const choice = jsonObj.choices[0];\n\n // Delta data for this chunk\n let deltaText: string = '';\n let deltaThinking: string = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n if (choice.delta?.content) {\n deltaText = choice.delta.content;\n accText += deltaText;\n }\n if (choice.delta?.reasoning_content) {\n deltaThinking = choice.delta.reasoning_content;\n accThinking += deltaThinking;\n }\n if (choice.delta?.tool_calls) {\n choice.delta.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool use id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool use name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool use input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._accDataToBlocks(deltaText, deltaThinking, deltaToolCalls);\n lastUsage = jsonObj.usage\n ? {\n type: 'chat_usage',\n inputTokens: jsonObj.usage.prompt_tokens || 0,\n outputTokens: jsonObj.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n }\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._accDataToBlocks(accText, accThinking, finalToolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param thinking - The thinking response\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _accDataToBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ThinkingBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ThinkingBlock | ToolCallBlock)[] = [];\n if (thinking) {\n blocks.push({ id: crypto.randomUUID(), type: 'thinking', thinking: thinking });\n }\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: text });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format for DeepSeek API.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { Ollama, ChatResponse as OllamaChatResponse, AbortableAsyncIterator } from 'ollama';\n\nimport { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { OllamaChatFormatter } from '../formatter';\n\ninterface OllamaThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n\n /**\n * Thinking level for Ollama models (high, medium, low).\n * Only applicable when enableThinking is true.\n */\n thinkingLevel?: 'high' | 'medium' | 'low';\n}\n\ninterface OllamaChatModelOptions extends ChatModelOptions {\n /**\n * Additional parameters to pass to the Ollama API (e.g., temperature).\n */\n options?: Record<string, unknown>;\n\n /**\n * Duration to keep the model loaded in memory (e.g., \"5m\", \"1h\").\n */\n keepAlive?: string;\n\n /**\n * Thinking configuration for Ollama models.\n */\n thinkingConfig?: OllamaThinkingConfig;\n\n /**\n * The host address of the Ollama server.\n */\n host?: string;\n\n /**\n * Extra keyword arguments to initialize the Ollama client.\n */\n clientKwargs?: Record<string, unknown>;\n\n /**\n * Extra keyword arguments used in Ollama API generation.\n */\n generateKwargs?: Record<string, unknown>;\n}\n\n/**\n * The Ollama chat model class in AgentScope.\n */\nexport class OllamaChatModel extends ChatModelBase {\n protected client: Ollama;\n protected options?: Record<string, unknown>;\n protected keepAlive: string;\n protected thinkingConfig: OllamaThinkingConfig;\n protected generateKwargs: Record<string, unknown>;\n\n /**\n * Initializes a new instance of the OllamaChatModel class.\n * @param root0\n * @param root0.modelName\n * @param root0.stream\n * @param root0.options\n * @param root0.keepAlive\n * @param root0.thinkingConfig\n * @param root0.host\n * @param root0.maxRetries\n * @param root0.fallbackModelName\n * @param root0.clientKwargs\n * @param root0.generateKwargs\n * @param root0.formatter\n */\n constructor({\n modelName,\n stream = true,\n options,\n keepAlive = '5m',\n thinkingConfig,\n host,\n maxRetries = 0,\n fallbackModelName,\n clientKwargs,\n generateKwargs,\n formatter,\n }: OllamaChatModelOptions) {\n // If no formatter is provided, create a default OllamaChatFormatter\n const defaultFormatter = formatter || new OllamaChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.options = options;\n this.keepAlive = keepAlive;\n this.thinkingConfig = thinkingConfig || {\n enableThinking: false,\n };\n this.generateKwargs = generateKwargs || {};\n\n // Initialize Ollama client\n this.client = new Ollama({\n host: host,\n ...clientKwargs,\n });\n }\n\n /**\n * Calls the Ollama API with the given parameters.\n * @param modelName\n * @param options\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n const kwargs: Record<string, unknown> = {\n model: modelName,\n messages: options.messages,\n stream: this.stream,\n options: this.options,\n keep_alive: this.keepAlive,\n ...this.generateKwargs,\n };\n\n if (this.thinkingConfig.enableThinking) {\n // If thinkingLevel is specified, use it; otherwise use true\n kwargs.think = this.thinkingConfig.thinkingLevel || true;\n } else {\n kwargs.think = false;\n }\n\n if (options.tools) {\n kwargs.tools = this._formatToolSchemas(options.tools);\n }\n\n if (options.toolChoice) {\n console.warn('Ollama does not support tool_choice yet, ignored.');\n }\n\n const startTime = Date.now();\n\n if (this.stream) {\n const response = (await this.client.chat({\n ...kwargs,\n stream: true,\n } as Parameters<\n typeof this.client.chat\n >[0])) as unknown as AbortableAsyncIterator<OllamaChatResponse>;\n return this._parseOllamaStreamResponse(response, startTime);\n }\n\n const response = (await this.client.chat({\n ...kwargs,\n stream: false,\n } as Parameters<typeof this.client.chat>[0])) as unknown as OllamaChatResponse;\n return this._parseOllamaResponse(response, startTime);\n }\n\n /**\n * Parse Ollama streaming response.\n * @param stream\n * @param startTime\n * @returns An async generator that yields delta ChatResponse objects and returns the complete ChatResponse.\n */\n async *_parseOllamaStreamResponse(\n stream: AbortableAsyncIterator<OllamaChatResponse>,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n let accText = '';\n let accThinking = '';\n const toolCalls: Map<string, ToolCallBlock> = new Map();\n let lastUsage: ChatUsage | null = null;\n\n for await (const chunk of stream) {\n const msg = chunk.message;\n\n // Delta data for this chunk\n let deltaText = '';\n let deltaThinking = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n // Accumulate text and thinking\n if (msg.thinking) {\n deltaThinking = msg.thinking;\n accThinking += msg.thinking;\n }\n if (msg.content) {\n deltaText = msg.content;\n accText += msg.content;\n }\n\n // Handle tool calls\n if (msg.tool_calls && Array.isArray(msg.tool_calls)) {\n for (let idx = 0; idx < msg.tool_calls.length; idx++) {\n const toolCall = msg.tool_calls[idx];\n const func = toolCall.function;\n const toolId = `${idx}_${func.name}`;\n\n const toolCallBlock = {\n type: 'tool_call' as const,\n id: toolId,\n name: func.name,\n input: JSON.stringify(func.arguments),\n state: 'pending' as const,\n };\n\n toolCalls.set(toolId, toolCallBlock);\n deltaToolCalls.set(toolId, toolCallBlock);\n }\n }\n\n // Calculate usage\n const currentTime = (Date.now() - startTime) / 1000;\n lastUsage = {\n type: 'chat_usage',\n inputTokens: chunk.prompt_eval_count || 0,\n outputTokens: chunk.eval_count || 0,\n time: currentTime,\n };\n\n // Yield delta response\n const deltaBlocks = this._buildContentBlocks(deltaText, deltaThinking, deltaToolCalls);\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n // Return complete response\n const blocks = this._buildContentBlocks(accText, accThinking, toolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Parse Ollama non-streaming response.\n * @param response\n * @param startTime\n * @returns A ChatResponse object containing the content blocks and usage.\n */\n _parseOllamaResponse(response: OllamaChatResponse, startTime: number): ChatResponse {\n const blocks: Array<TextBlock | ThinkingBlock | ToolCallBlock> = [];\n\n if (response.message.thinking) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'thinking',\n thinking: response.message.thinking,\n });\n }\n\n if (response.message.content) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: response.message.content,\n });\n }\n\n // Handle tool calls\n if (response.message.tool_calls && Array.isArray(response.message.tool_calls)) {\n for (let idx = 0; idx < response.message.tool_calls.length; idx++) {\n const toolCall = response.message.tool_calls[idx];\n blocks.push({\n type: 'tool_call',\n id: `${idx}_${toolCall.function.name}`,\n name: toolCall.function.name,\n input: JSON.stringify(toolCall.function.arguments),\n state: 'pending',\n });\n }\n }\n\n const usage =\n response.prompt_eval_count !== undefined && response.eval_count !== undefined\n ? {\n type: 'chat_usage',\n inputTokens: response.prompt_eval_count || 0,\n outputTokens: response.eval_count || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * Build content blocks from accumulated data.\n * @param text\n * @param thinking\n * @param toolCalls\n * @returns An array of content blocks.\n */\n _buildContentBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): Array<TextBlock | ThinkingBlock | ToolCallBlock> {\n const blocks: Array<TextBlock | ThinkingBlock | ToolCallBlock> = [];\n\n if (thinking) {\n blocks.push({ id: crypto.randomUUID(), type: 'thinking', thinking });\n }\n\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text });\n }\n\n toolCalls.forEach(toolCall => {\n blocks.push(toolCall);\n });\n\n return blocks;\n }\n\n /**\n * Format tool choice parameter (not supported by Ollama).\n * @param _toolChoice\n * @returns undefined as Ollama does not support tool choice.\n */\n _formatToolChoice(_toolChoice?: ToolChoice): unknown {\n return undefined;\n }\n\n /**\n * Format tool schemas for Ollama API (no special formatting needed).\n * @param tools\n * @returns The same array of tool schemas, or an empty array if undefined.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { OpenAI } from 'openai';\nimport {\n ChatCompletionMessageParam,\n ChatCompletionToolChoiceOption,\n} from 'openai/resources/chat/completions';\n\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { ChatUsage } from './usage';\nimport { OpenAIChatFormatter } from '../formatter';\n\ninterface OpenAIChatModelOptions extends ChatModelOptions {\n apiKey: string;\n presetGenParams?: Record<string, unknown>;\n baseURL?: string;\n}\n\n/**\n * The OpenAI API chat model.\n */\nexport class OpenAIChatModel extends ChatModelBase {\n protected client: OpenAI;\n protected presetGenParams: Record<string, unknown> | undefined;\n\n /**\n * Initializes a new instance of the OpenAIChatModel class.\n * @param options\n * @param options.modelName\n * @param options.apiKey\n * @param options.stream\n * @param options.maxRetries\n * @param options.fallbackModelName\n * @param options.presetGenParams\n * @param options.baseURL\n * @param options.formatter\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n maxRetries = 3,\n fallbackModelName,\n presetGenParams,\n baseURL,\n formatter,\n }: OpenAIChatModelOptions) {\n // If no formatter is provided, create a default OpenAIChatFormatter\n const defaultFormatter = formatter || new OpenAIChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.client = new OpenAI({\n apiKey: apiKey,\n baseURL,\n });\n this.presetGenParams = presetGenParams;\n }\n\n /**\n * Calls the OpenAI API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<ChatCompletionMessageParam>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n const startTime = Date.now();\n\n if (this.stream) {\n // Handle streaming response\n const stream = await this.client.chat.completions.create({\n model: modelName,\n messages: options.messages,\n tools: this._formatToolSchemas(options.tools),\n tool_choice: this._formatToolChoice(options.toolChoice),\n stream: true,\n ...(this.presetGenParams ?? {}),\n });\n\n return this._parseOpenAIStreamedResponse(stream, startTime);\n }\n\n // Handle non-streaming response\n const response = await this.client.chat.completions.create({\n model: modelName,\n messages: options.messages,\n tools: options.tools,\n tool_choice: this._formatToolChoice(options.toolChoice),\n stream: false,\n ...(this.presetGenParams ?? {}),\n });\n\n const choice = response.choices[0];\n const blocks: (TextBlock | ToolCallBlock | ThinkingBlock | DataBlock)[] = [];\n\n // handling text block\n if (choice.message.content) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: choice.message.content });\n }\n\n // handling tool calls\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach(toolCall => {\n if (toolCall.type === 'function') {\n blocks.push({\n type: 'tool_call',\n id: toolCall.id,\n name: toolCall.function.name,\n input: toolCall.function.arguments,\n state: 'pending',\n });\n }\n });\n }\n\n // handling usage\n const usage = response.usage\n ? {\n type: 'chat_usage',\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: response.id,\n createdAt: new Date(response.created * 1000).toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * Formats the tool choice for the API request.\n *\n * TODO: supports grouped tool choices.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(toolChoice?: ToolChoice): ChatCompletionToolChoiceOption {\n if (toolChoice) {\n // Directly return predefined options\n if (toolChoice === 'none' || toolChoice === 'auto' || toolChoice === 'required') {\n return toolChoice;\n }\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from OpenAI API.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param stream - The OpenAI stream object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseOpenAIStreamedResponse(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n let accText = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | null = null;\n let responseId = '';\n let createdTimestamp = 0;\n\n for await (const chunk of stream) {\n if (!responseId && chunk.id) {\n responseId = chunk.id;\n }\n if (!createdTimestamp && chunk.created) {\n createdTimestamp = chunk.created;\n }\n\n if (chunk.choices && chunk.choices.length > 0) {\n const choice = chunk.choices[0];\n\n // Delta data for this chunk\n let deltaText = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n if (choice.delta?.content) {\n deltaText = choice.delta.content;\n accText += deltaText;\n }\n\n if (choice.delta?.tool_calls) {\n choice.delta.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool call id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool call name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool call input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._accDataToBlocks(deltaText, deltaToolCalls);\n\n yield {\n type: 'chat',\n id: responseId || crypto.randomUUID(),\n createdAt: createdTimestamp\n ? new Date(createdTimestamp * 1000).toISOString()\n : new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n // Handle usage information (typically in the last chunk)\n if (chunk.usage) {\n lastUsage = {\n type: 'chat_usage',\n inputTokens: chunk.usage.prompt_tokens || 0,\n outputTokens: chunk.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n };\n }\n }\n\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._accDataToBlocks(accText, finalToolCalls);\n return {\n type: 'chat',\n id: responseId || crypto.randomUUID(),\n createdAt: createdTimestamp\n ? new Date(createdTimestamp * 1000).toISOString()\n : new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _accDataToBlocks(\n text: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ToolCallBlock)[] = [];\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: text });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n"],"mappings":"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","names":["format","response"]}
1
+ {"version":3,"sources":["../../src/model/index.ts","../../src/message/message.ts","../../src/model/base.ts","../../src/_utils/common.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","../../src/model/dashscope-model.ts","../../src/model/deepseek-model.ts","../../src/model/ollama-model.ts","../../src/model/openai-model.ts"],"sourcesContent":["export { ChatModelBase } from './base';\nexport { ChatResponse } from './response';\nexport { ChatUsage } from './usage';\nexport { DashScopeChatModel } from './dashscope-model';\nexport { DeepSeekChatModel } from './deepseek-model';\nexport { OllamaChatModel } from './ollama-model';\nexport { OpenAIChatModel } from './openai-model';\n","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 input_tokens: number;\n output_tokens: 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 */\n/**\n * Validate that content blocks are allowed for the given role.\n *\n * Mirrors the Python `_assert_user_content_blocks` / `_assert_system_content_blocks`\n * guards: user messages may only contain text or data blocks; system messages\n * may only contain text blocks; assistant messages accept any block type.\n * @param role\n * @param content\n */\nfunction assertContentBlocksForRole(role: Msg['role'], content: ContentBlock[]): void {\n if (role === 'user') {\n for (const block of content) {\n if (block.type !== 'text' && block.type !== 'data') {\n throw new Error('User message can only contain text blocks or data blocks.');\n }\n }\n } else if (role === 'system') {\n for (const block of content) {\n if (block.type !== 'text') {\n throw new Error('System message can only contain text blocks.');\n }\n }\n }\n}\n\n/**\n * createMsg is a low-level utility for constructing Msg objects with proper defaults and validation.\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 with the specified properties, and defaults for any omitted fields.\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 assertContentBlocksForRole(role, contentBlocks);\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 * @param root0.finished_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 finished_at,\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n finished_at?: string | null;\n}): Msg {\n return createMsg({\n name,\n content,\n role: 'user',\n metadata,\n id,\n created_at,\n finished_at: finished_at ?? created_at,\n });\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 * @param root0.finished_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 finished_at,\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n finished_at?: string | null;\n}): Msg {\n return createMsg({\n name,\n content,\n role: 'system',\n metadata,\n id,\n created_at,\n finished_at: finished_at ?? created_at,\n });\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 if (event.data) {\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: 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({\n type: 'data',\n id: event.block_id ?? crypto.randomUUID(),\n source,\n });\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.MODEL_CALL_END:\n // Accumulated the input and output tokens here.\n if (msg.usage) {\n msg.usage.input_tokens += event.input_tokens;\n msg.usage.output_tokens += event.output_tokens;\n } else {\n msg.usage = {\n input_tokens: event.input_tokens,\n output_tokens: event.output_tokens,\n };\n }\n break;\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) {\n (b as ToolCallBlock).state = 'asking';\n (b as ToolCallBlock).suggested_rules = tc.suggested_rules || [];\n }\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 { z } from 'zod';\n\nimport { ChatResponse, StructuredResponse } from './response';\nimport { FormatterBase } from '../formatter';\nimport { getTextContent, Msg } from '../message';\nimport { ToolChoice, ToolInputSchema, ToolSchema } from '../type';\n\nexport interface ChatModelOptions {\n modelName: string;\n stream?: boolean;\n maxRetries?: number;\n fallbackModelName?: string;\n formatter?: FormatterBase;\n}\n\n// The chat model call options interface\nexport interface ChatModelCallOptions {\n messages: Msg[];\n tools?: ToolSchema[];\n toolChoice?: ToolChoice;\n\n // The additional options can be added as needed\n [key: string]: unknown;\n}\n\nexport interface ChatModelCallStructuredOptions {\n messages: Msg[];\n schema: z.ZodObject;\n}\n\n// Internal API request options after formatting\nexport interface ChatModelRequestOptions<T> {\n messages: T[];\n tools?: ToolSchema[];\n toolChoice?: ToolChoice;\n\n // The additional options can be added as needed\n [key: string]: unknown;\n}\n\n/**\n * The base class for chat models.\n */\nexport abstract class ChatModelBase {\n public modelName: string;\n public stream: boolean;\n public maxRetries: number;\n public fallbackModelName?: string;\n public formatter?: FormatterBase;\n /**\n * Initializes a new instance of the ChatModelBase class.\n *\n * @param options - The chat model options, including model name, streaming option, max retries, fallback\n * model name, and formatter.\n *\n * @param options.modelName\n * @param options.stream\n * @param options.maxRetries\n * @param options.fallbackModelName\n * @param options.formatter\n */\n protected constructor({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter,\n }: ChatModelOptions) {\n this.modelName = modelName;\n this.stream = stream ?? true;\n this.maxRetries = maxRetries ?? 0;\n this.fallbackModelName = fallbackModelName;\n this.formatter = formatter;\n }\n\n /**\n * Calls the chat model with the given messages.\n * This is the main method to interact with the model.\n *\n * @param options - The chat model call options.\n * @returns A promise that resolves to the model's response.\n */\n async call(\n options: ChatModelCallOptions\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse>> {\n // Format messages using the formatter if available\n let formattedMessages: unknown[];\n if (this.formatter) {\n formattedMessages = await this.formatter.format({ msgs: options.messages });\n } else {\n // If no formatter is provided, pass messages as-is\n formattedMessages = options.messages as unknown[];\n }\n\n const requestOptions: ChatModelRequestOptions<unknown> = {\n ...options,\n messages: formattedMessages,\n };\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n return await this._callAPI(this.modelName, requestOptions);\n } catch (error) {\n lastError = error;\n if (attempt === this.maxRetries) {\n throw error;\n } else {\n console.log(\n `Attempt ${attempt + 1} failed for model ${this.modelName}. Retrying...`\n );\n }\n }\n }\n\n // Use the fallback model if specified\n if (this.fallbackModelName) {\n console.log(\n `Using fallback model ${this.fallbackModelName} after ${this.maxRetries} failed attempts.`\n );\n return await this._callAPI(this.fallbackModelName, requestOptions);\n }\n\n // This line should never be reached, but it ensures TypeScript knows the function always returns\n throw lastError;\n }\n\n /**\n * Abstract method to call the underlying API with the given parameters.\n */\n protected abstract _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<unknown>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse>>;\n\n /**\n * Format the AgentScope tool choice parameter to the expected API format.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n abstract _formatToolChoice(toolChoice: ToolChoice): unknown;\n\n /**\n * A heuristic method to count the number of the tokens\n * Note the multimodal content is ignored in the token counting\n * @param options\n * @param options.messages\n * @param options.tools\n * @returns The estimated number of tokens in the input messages and tools.\n */\n async countTokens(options: { messages: Msg[]; tools?: ToolSchema[] }): Promise<number> {\n let accText: string = '';\n for (const msg of options.messages) {\n accText += getTextContent(msg) || '';\n }\n if (options.tools) {\n accText += JSON.stringify(options.tools);\n }\n const chineseMatches =\n accText.match(/[\\u4e00-\\u9fff\\u3400-\\u4dbf\\u{20000}-\\u{2a6df}]/gu)?.length ?? 0;\n const englishMatches = accText.match(/[a-zA-Z]+/g)?.length ?? 0;\n\n return chineseMatches * 2 + englishMatches * 1.5;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n abstract _formatToolSchemas(tools: ToolSchema[]): unknown[];\n\n /**\n * A default implementation of the structured call method. For those supporting structured output, the model should\n * override this method.\n * @param options\n * @returns The structured response from the model, which should conform to the provided Zod schema.\n */\n async callStructured(options: ChatModelCallStructuredOptions): Promise<StructuredResponse> {\n // Prepare a tool schema that wraps the provided Zod schema\n const toolSchema: ToolSchema = {\n type: 'function',\n function: {\n name: 'GenerateStructuredResponse',\n description: 'Generate required structured response by this toll.',\n parameters: options.schema.toJSONSchema({\n target: 'openapi-3.0',\n }) as ToolInputSchema,\n },\n };\n\n const res = await this.call({\n messages: options.messages,\n tools: [toolSchema],\n toolChoice: 'GenerateStructuredResponse',\n });\n\n let completedResponse: ChatResponse;\n if (this.stream) {\n while (true) {\n const { value, done } = await (res as AsyncGenerator<ChatResponse>).next();\n if (done) {\n completedResponse = value;\n break;\n }\n }\n } else {\n completedResponse = res as ChatResponse;\n }\n\n // Find the tool call\n for (const block of completedResponse.content) {\n if (block.type === 'tool_call' && block.name === 'GenerateStructuredResponse') {\n const structuredContent = JSON.parse(block.input);\n return {\n ...completedResponse,\n content: structuredContent,\n type: 'structured',\n } as StructuredResponse;\n }\n }\n\n throw new Error(`Failed to generate the structured response`);\n }\n}\n","import { jsonrepair } from 'jsonrepair';\n\nimport { JSONSerializableObject } from '../type';\n\n/**\n * Creates a timestamp string in the format \"YYYY-MM-DD HH:mm:ss.sss\"\n * representing the current date and time.\n *\n * @returns {string} The formatted timestamp string.\n */\nexport function _createTimestamp(): string {\n return new Date().toISOString().replace('T', ' ').replace('Z', '').substring(0, 23);\n}\n\n/**\n * Attempts to parse a JSON string into a dictionary/Record.\n * This function is used to handle the streaming tool use block from the LLM API.\n *\n * @param input - The JSON string to parse.\n * @returns A dictionary/Record parsed from the JSON string. If parsing fails, returns an empty dictionary.\n */\nexport function _jsonLoadsWithRepair(input: string): Record<string, JSONSerializableObject> {\n try {\n const jsonObj = JSON.parse(input);\n // Check if the jsonObj is a dictionary/Record\n if (typeof jsonObj === 'object' && jsonObj !== null && !Array.isArray(jsonObj)) {\n return jsonObj as Record<string, JSONSerializableObject>;\n } else {\n // Return an empty dictionary\n return {};\n }\n } catch {\n try {\n const repairedString = jsonrepair(input);\n const jsonObj = JSON.parse(repairedString);\n // Check if the jsonObj is a dictionary/Record\n if (typeof jsonObj === 'object' && jsonObj !== null && !Array.isArray(jsonObj)) {\n return jsonObj as Record<string, JSONSerializableObject>;\n } else {\n // Return an empty dictionary\n return {};\n }\n } catch (e) {\n console.error(`Failed to parse JSON \"${input}\" with error:`, e);\n return {};\n }\n }\n}\n\n/**\n * Parses a streamed response from the post request.\n * An async generator that yields parsed JSON objects from the SSE stream.\n *\n * @param response - The fetch response object.\n * @returns An async generator yielding parsed JSON objects.\n */\nexport async function* _parseStreamedResponse<T>(response: Response): AsyncGenerator<T> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response body for streaming.');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Handle the completed line\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep the last uncompleted line\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine || trimmedLine.startsWith(':')) {\n continue; // Skip the empty line and comments\n }\n\n if (trimmedLine.startsWith('data:')) {\n const jsonStr = trimmedLine.slice(5).trim(); // Remove \"data:\" prefix\n\n if (jsonStr === '[DONE]') {\n break;\n }\n\n try {\n const json = JSON.parse(jsonStr);\n yield json;\n } catch (e) {\n console.error('Failed to parse JSON:', e);\n throw new Error(`Failed to parse JSON from stream: ${jsonStr}`);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\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","import { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { _parseStreamedResponse } from '../_utils';\nimport { DashScopeChatFormatter } from '../formatter';\n\ninterface _DashScopeStreamChunk {\n output?: {\n choices: {\n message?: {\n content?: string | { text: string }[];\n reasoning_content?: string;\n tool_calls?: {\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }[];\n };\n }[];\n };\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n}\n\ninterface DashScopeThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n\n /**\n * Maximum tokens for reasoning (optional).\n */\n thinkingBudget?: number;\n}\n\ninterface DashScopeChatModelOptions extends ChatModelOptions {\n /**\n * The API key for authenticating with DashScope API.\n */\n apiKey: string;\n\n /**\n * Thinking configuration for DashScope models.\n */\n thinkingConfig?: DashScopeThinkingConfig;\n\n /**\n * (Deprecated) Use thinkingConfig instead.\n * Whether to enable the \"thinking\" feature in the model.\n */\n enableThinking?: boolean;\n\n /**\n * Whether the model is multimodal or not, this will decide the default API endpoint.\n */\n multimodal?: boolean;\n\n /**\n * Preset generation parameters to include in each request.\n * These parameters will be merged with the request-specific parameters.\n */\n presetGenParams?: Record<string, unknown>;\n\n /**\n * Preset headers that will be included in each request.\n */\n presetHeaders?: Record<string, unknown>;\n}\n\n/**\n * The DashScope API chat model.\n */\nexport class DashScopeChatModel extends ChatModelBase {\n apiURL: string;\n protected apiKey: string;\n protected presetGenParams: Record<string, unknown> | undefined;\n protected presetHeaders: Record<string, unknown> | undefined;\n protected thinkingConfig?: DashScopeThinkingConfig;\n\n /**\n * Initializes a new instance of the DashScopeChatModel class.\n *\n * @param options - The DashScope chat model options.\n * @param options.modelName - The name of the model to use.\n * @param options.apiKey - The API key for authentication.\n * @param options.stream - Whether to use streaming responses. Default is true.\n * @param options.thinkingConfig - The thinking configuration for DashScope models, including whether to enable thinking and the thinking budget.\n * @param options.maxRetries - The maximum number of retries for failed requests. Default is 3.\n * @param options.fallbackModelName - The fallback model name to use if the primary model fails.\n * @param options.presetGenParams - Preset generation parameters to include in each request.\n * @param options.presetHeaders - Preset headers that will be included in each request.\n * @param options.multimodal - Whether the model is multimodal or not, this will decide the default API endpoint. If not provided, it will be inferred from the model name.\n * @param options.formatter - An optional custom formatter. If not provided, a default DashScopeChatFormatter will be used.\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n thinkingConfig,\n maxRetries = 0,\n fallbackModelName,\n presetGenParams,\n presetHeaders,\n multimodal,\n formatter,\n }: DashScopeChatModelOptions) {\n // If no formatter is provided, create a default DashScopeChatFormatter\n const defaultFormatter = formatter || new DashScopeChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.apiKey = apiKey;\n this.thinkingConfig = thinkingConfig;\n this.presetGenParams = presetGenParams;\n this.presetHeaders = presetHeaders;\n\n // Infer the apiURL based on the multimodal option or the model name\n if (multimodal === undefined) {\n // Router according to the model name\n multimodal =\n modelName.includes('vl') ||\n modelName.includes('qwen3.5-plus') ||\n modelName.includes('qvq');\n }\n this.apiURL = multimodal\n ? 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation'\n : 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';\n }\n\n /**\n * Calls the DashScope API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n // Set up request data\n const data = {\n model: modelName,\n input: {\n messages: options.messages,\n },\n parameters: {\n result_format: 'message',\n tools: this._formatToolSchemas(options.tools),\n toolChoice: this._formatToolChoice(options.toolChoice),\n enable_thinking: this.thinkingConfig?.enableThinking ?? false,\n ...(this.thinkingConfig?.thinkingBudget !== undefined && {\n thinking_budget: this.thinkingConfig.thinkingBudget,\n }),\n ...(this.presetGenParams ?? {}),\n incremental_output: true,\n } as Record<string, unknown>,\n };\n\n // Set up headers\n const headers: Record<string, unknown> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.presetHeaders,\n };\n\n // Set up streaming header if needed\n if (this.stream) {\n headers['X-DashScope-SSE'] = 'enable';\n }\n\n // Counting the time cost\n const startTime = Date.now();\n const response = await fetch(this.apiURL, {\n method: 'POST',\n headers: headers as HeadersInit,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n throw new Error(\n `DashScope API request failed with status ${response.status}: ${await response.text()}`\n );\n }\n\n if (this.stream) {\n // Handle the streaming response\n return this._parseDashScopeStreamedResponse(response, startTime);\n }\n\n // Handle the non-streaming response\n const blocks: Array<TextBlock | ToolCallBlock | ThinkingBlock | DataBlock> = [];\n const res = await response.json();\n const choice = res.output.choices[0];\n if (choice.message.reasoning_content) {\n blocks.push({\n type: 'thinking',\n thinking: choice.message.reasoning_content,\n id: crypto.randomUUID(),\n });\n }\n if (choice.message.content) {\n blocks.push({ type: 'text', text: choice.message.content, id: crypto.randomUUID() });\n }\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach((toolCall: object) => {\n if (\n 'id' in toolCall &&\n 'function' in toolCall &&\n typeof toolCall.function === 'object' &&\n toolCall.function &&\n 'name' in toolCall.function &&\n 'arguments' in toolCall.function\n ) {\n const inputString = String(toolCall.function.arguments);\n blocks.push({\n type: 'tool_call',\n id: String(toolCall.id),\n name: String(toolCall.function.name),\n input: inputString,\n state: 'pending',\n });\n }\n });\n }\n\n const usage = res.usage\n ? {\n type: 'chat_usage',\n inputTokens: res.usage.input_tokens || 0,\n outputTokens: res.usage.output_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * The method to format the tool choice parameter.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(toolChoice?: ToolChoice): 'auto' | 'none' | Record<string, unknown> {\n if (toolChoice) {\n if (toolChoice === 'auto') return 'auto';\n if (toolChoice === 'none') return 'none';\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from DashScope API specifically for chat responses.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param response - The fetch response object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseDashScopeStreamedResponse(\n response: Response,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n const asyncGenerator = _parseStreamedResponse<_DashScopeStreamChunk>(response);\n\n let accText: string = '';\n let accThinking: string = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | undefined = undefined;\n\n for await (const jsonObj of asyncGenerator) {\n if (jsonObj.output && jsonObj.output.choices) {\n const choice = jsonObj.output.choices[0];\n\n // Delta data for this chunk\n let deltaText: string = '';\n let deltaThinking: string = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n const content = choice.message?.content;\n if (content) {\n if (typeof content === 'string') {\n deltaText = content;\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (block.text) {\n deltaText += block.text;\n }\n }\n }\n accText += deltaText;\n }\n if (choice.message?.reasoning_content) {\n deltaThinking = choice.message.reasoning_content;\n accThinking += deltaThinking;\n }\n if (choice.message?.tool_calls) {\n choice.message.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool use id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool use name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool use input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._dataToBlocks(deltaText, deltaThinking, deltaToolCalls);\n lastUsage = jsonObj.usage\n ? {\n type: 'chat_usage',\n inputTokens: jsonObj.usage.input_tokens || 0,\n outputTokens: jsonObj.usage.output_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n }\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._dataToBlocks(accText, accThinking, finalToolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param thinking - The thinking response\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _dataToBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ThinkingBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ThinkingBlock | ToolCallBlock)[] = [];\n if (thinking) {\n blocks.push({ type: 'thinking', thinking: thinking, id: crypto.randomUUID() });\n }\n if (text) {\n blocks.push({ type: 'text', text: text, id: crypto.randomUUID() });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { _parseStreamedResponse } from '../_utils';\nimport { DeepSeekChatFormatter } from '../formatter';\n\ninterface _DeepSeekStreamChunk {\n choices?: {\n delta?: {\n content?: string;\n reasoning_content?: string;\n tool_calls?: {\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\ninterface DeepSeekThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n}\n\ninterface DeepSeekChatModelOptions extends ChatModelOptions {\n /**\n * The API key for authenticating with DeepSeek API.\n */\n apiKey: string;\n\n /**\n * Thinking configuration for DeepSeek models.\n */\n thinkingConfig?: DeepSeekThinkingConfig;\n\n /**\n * Preset generation parameters to include in each request.\n * These parameters will be merged with the request-specific parameters.\n */\n presetGenParams?: Record<string, unknown>;\n\n /**\n * Preset headers that will be included in each request.\n */\n presetHeaders?: Record<string, unknown>;\n}\n\n/**\n * The DeepSeek API chat model.\n */\nexport class DeepSeekChatModel extends ChatModelBase {\n apiURL: string;\n protected apiKey: string;\n protected presetGenParams: Record<string, unknown> | undefined;\n protected presetHeaders: Record<string, unknown> | undefined;\n protected thinkingConfig: DeepSeekThinkingConfig;\n\n /**\n * Initializes a new instance of the DeepSeekChatModel class.\n *\n * @param options - The DeepSeek chat model options.\n * @param options.modelName - The name of the model to use.\n * @param options.apiKey - The API key for authentication.\n * @param options.stream - Whether to use streaming responses. Default is true.\n * @param options.thinkingConfig - Thinking configuration.\n * @param options.maxRetries - The maximum number of retries for failed requests. Default is 0.\n * @param options.fallbackModelName - The fallback model name to use if the primary model fails.\n * @param options.presetGenParams - Preset generation parameters to include in each request.\n * @param options.presetHeaders - Preset headers that will be included in each request.\n * @param options.formatter\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n thinkingConfig,\n maxRetries = 0,\n fallbackModelName,\n presetGenParams,\n presetHeaders,\n formatter,\n }: DeepSeekChatModelOptions) {\n // If no formatter is provided, create a default DeepSeekChatFormatter\n const defaultFormatter = formatter || new DeepSeekChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.apiKey = apiKey;\n this.thinkingConfig = thinkingConfig || { enableThinking: false };\n this.presetGenParams = presetGenParams;\n this.presetHeaders = presetHeaders;\n this.apiURL = 'https://api.deepseek.com/chat/completions';\n }\n\n /**\n * Calls the DeepSeek API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n // Set up request data\n const data = {\n model: modelName,\n messages: options.messages,\n tools: this._formatToolSchemas(options.tools),\n tool_choice: this._formatToolChoice(options.toolChoice),\n thinking: this.thinkingConfig.enableThinking\n ? { type: 'enabled' }\n : { type: 'disabled' },\n stream: this.stream,\n ...(this.presetGenParams ?? {}),\n } as Record<string, unknown>;\n\n // Set up headers\n const headers: Record<string, unknown> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.presetHeaders,\n };\n\n // Counting the time cost\n const startTime = Date.now();\n const response = await fetch(this.apiURL, {\n method: 'POST',\n headers: headers as HeadersInit,\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n throw new Error(\n `DeepSeek API request failed with status ${response.status}: ${await response.text()}`\n );\n }\n\n if (this.stream) {\n // Handle the streaming response\n return this._parseDeepSeekStreamedResponse(response, startTime);\n }\n\n // Handle the non-streaming response\n const blocks: Array<TextBlock | ToolCallBlock | ThinkingBlock | DataBlock> = [];\n const res = await response.json();\n const choice = res.choices[0];\n\n if (choice.message.reasoning_content) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'thinking',\n thinking: choice.message.reasoning_content,\n });\n }\n if (choice.message.content) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: choice.message.content });\n }\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach((toolCall: object) => {\n if (\n 'id' in toolCall &&\n 'function' in toolCall &&\n typeof toolCall.function === 'object' &&\n toolCall.function &&\n 'name' in toolCall.function &&\n 'arguments' in toolCall.function\n ) {\n const inputString = String(toolCall.function.arguments);\n blocks.push({\n type: 'tool_call',\n id: String(toolCall.id),\n name: String(toolCall.function.name),\n input: inputString,\n state: 'pending',\n });\n }\n });\n }\n\n const usage = res.usage\n ? {\n type: 'chat_usage',\n inputTokens: res.usage.prompt_tokens || 0,\n outputTokens: res.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * The method to format the tool choice parameter.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(\n toolChoice?: ToolChoice\n ): 'auto' | 'none' | 'required' | Record<string, unknown> {\n if (toolChoice) {\n if (toolChoice === 'auto') return 'auto';\n if (toolChoice === 'none') return 'none';\n if (this.thinkingConfig?.enableThinking) {\n console.log(\n `The deepseek reasoning model does not support tool choice options '${toolChoice}'. 'auto' will be used instead.`\n );\n return 'auto';\n }\n if (toolChoice === 'required') return 'required';\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from DeepSeek API specifically for chat responses.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param response - The fetch response object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseDeepSeekStreamedResponse(\n response: Response,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n const asyncGenerator = _parseStreamedResponse<_DeepSeekStreamChunk>(response);\n\n let accText: string = '';\n let accThinking: string = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | undefined = undefined;\n\n for await (const jsonObj of asyncGenerator) {\n if (jsonObj.choices && jsonObj.choices.length > 0) {\n const choice = jsonObj.choices[0];\n\n // Delta data for this chunk\n let deltaText: string = '';\n let deltaThinking: string = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n if (choice.delta?.content) {\n deltaText = choice.delta.content;\n accText += deltaText;\n }\n if (choice.delta?.reasoning_content) {\n deltaThinking = choice.delta.reasoning_content;\n accThinking += deltaThinking;\n }\n if (choice.delta?.tool_calls) {\n choice.delta.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool use id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool use name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool use input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._accDataToBlocks(deltaText, deltaThinking, deltaToolCalls);\n lastUsage = jsonObj.usage\n ? {\n type: 'chat_usage',\n inputTokens: jsonObj.usage.prompt_tokens || 0,\n outputTokens: jsonObj.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n }\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._accDataToBlocks(accText, accThinking, finalToolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param thinking - The thinking response\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _accDataToBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ThinkingBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ThinkingBlock | ToolCallBlock)[] = [];\n if (thinking) {\n blocks.push({ id: crypto.randomUUID(), type: 'thinking', thinking: thinking });\n }\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: text });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format for DeepSeek API.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { Ollama, ChatResponse as OllamaChatResponse, AbortableAsyncIterator } from 'ollama';\n\nimport { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatUsage } from './usage';\nimport { OllamaChatFormatter } from '../formatter';\n\ninterface OllamaThinkingConfig {\n /**\n * Whether to enable thinking or not.\n */\n enableThinking: boolean;\n\n /**\n * Thinking level for Ollama models (high, medium, low).\n * Only applicable when enableThinking is true.\n */\n thinkingLevel?: 'high' | 'medium' | 'low';\n}\n\ninterface OllamaChatModelOptions extends ChatModelOptions {\n /**\n * Additional parameters to pass to the Ollama API (e.g., temperature).\n */\n options?: Record<string, unknown>;\n\n /**\n * Duration to keep the model loaded in memory (e.g., \"5m\", \"1h\").\n */\n keepAlive?: string;\n\n /**\n * Thinking configuration for Ollama models.\n */\n thinkingConfig?: OllamaThinkingConfig;\n\n /**\n * The host address of the Ollama server.\n */\n host?: string;\n\n /**\n * Extra keyword arguments to initialize the Ollama client.\n */\n clientKwargs?: Record<string, unknown>;\n\n /**\n * Extra keyword arguments used in Ollama API generation.\n */\n generateKwargs?: Record<string, unknown>;\n}\n\n/**\n * The Ollama chat model class in AgentScope.\n */\nexport class OllamaChatModel extends ChatModelBase {\n protected client: Ollama;\n protected options?: Record<string, unknown>;\n protected keepAlive: string;\n protected thinkingConfig: OllamaThinkingConfig;\n protected generateKwargs: Record<string, unknown>;\n\n /**\n * Initializes a new instance of the OllamaChatModel class.\n * @param root0\n * @param root0.modelName\n * @param root0.stream\n * @param root0.options\n * @param root0.keepAlive\n * @param root0.thinkingConfig\n * @param root0.host\n * @param root0.maxRetries\n * @param root0.fallbackModelName\n * @param root0.clientKwargs\n * @param root0.generateKwargs\n * @param root0.formatter\n */\n constructor({\n modelName,\n stream = true,\n options,\n keepAlive = '5m',\n thinkingConfig,\n host,\n maxRetries = 0,\n fallbackModelName,\n clientKwargs,\n generateKwargs,\n formatter,\n }: OllamaChatModelOptions) {\n // If no formatter is provided, create a default OllamaChatFormatter\n const defaultFormatter = formatter || new OllamaChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.options = options;\n this.keepAlive = keepAlive;\n this.thinkingConfig = thinkingConfig || {\n enableThinking: false,\n };\n this.generateKwargs = generateKwargs || {};\n\n // Initialize Ollama client\n this.client = new Ollama({\n host: host,\n ...clientKwargs,\n });\n }\n\n /**\n * Calls the Ollama API with the given parameters.\n * @param modelName\n * @param options\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<Record<string, unknown>>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n const kwargs: Record<string, unknown> = {\n model: modelName,\n messages: options.messages,\n stream: this.stream,\n options: this.options,\n keep_alive: this.keepAlive,\n ...this.generateKwargs,\n };\n\n if (this.thinkingConfig.enableThinking) {\n // If thinkingLevel is specified, use it; otherwise use true\n kwargs.think = this.thinkingConfig.thinkingLevel || true;\n } else {\n kwargs.think = false;\n }\n\n if (options.tools) {\n kwargs.tools = this._formatToolSchemas(options.tools);\n }\n\n if (options.toolChoice) {\n console.warn('Ollama does not support tool_choice yet, ignored.');\n }\n\n const startTime = Date.now();\n\n if (this.stream) {\n const response = (await this.client.chat({\n ...kwargs,\n stream: true,\n } as Parameters<\n typeof this.client.chat\n >[0])) as unknown as AbortableAsyncIterator<OllamaChatResponse>;\n return this._parseOllamaStreamResponse(response, startTime);\n }\n\n const response = (await this.client.chat({\n ...kwargs,\n stream: false,\n } as Parameters<typeof this.client.chat>[0])) as unknown as OllamaChatResponse;\n return this._parseOllamaResponse(response, startTime);\n }\n\n /**\n * Parse Ollama streaming response.\n * @param stream\n * @param startTime\n * @returns An async generator that yields delta ChatResponse objects and returns the complete ChatResponse.\n */\n async *_parseOllamaStreamResponse(\n stream: AbortableAsyncIterator<OllamaChatResponse>,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n let accText = '';\n let accThinking = '';\n const toolCalls: Map<string, ToolCallBlock> = new Map();\n let lastUsage: ChatUsage | null = null;\n\n for await (const chunk of stream) {\n const msg = chunk.message;\n\n // Delta data for this chunk\n let deltaText = '';\n let deltaThinking = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n // Accumulate text and thinking\n if (msg.thinking) {\n deltaThinking = msg.thinking;\n accThinking += msg.thinking;\n }\n if (msg.content) {\n deltaText = msg.content;\n accText += msg.content;\n }\n\n // Handle tool calls\n if (msg.tool_calls && Array.isArray(msg.tool_calls)) {\n for (let idx = 0; idx < msg.tool_calls.length; idx++) {\n const toolCall = msg.tool_calls[idx];\n const func = toolCall.function;\n const toolId = `${idx}_${func.name}`;\n\n const toolCallBlock = {\n type: 'tool_call' as const,\n id: toolId,\n name: func.name,\n input: JSON.stringify(func.arguments),\n state: 'pending' as const,\n };\n\n toolCalls.set(toolId, toolCallBlock);\n deltaToolCalls.set(toolId, toolCallBlock);\n }\n }\n\n // Calculate usage\n const currentTime = (Date.now() - startTime) / 1000;\n lastUsage = {\n type: 'chat_usage',\n inputTokens: chunk.prompt_eval_count || 0,\n outputTokens: chunk.eval_count || 0,\n time: currentTime,\n };\n\n // Yield delta response\n const deltaBlocks = this._buildContentBlocks(deltaText, deltaThinking, deltaToolCalls);\n yield {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n // Return complete response\n const blocks = this._buildContentBlocks(accText, accThinking, toolCalls);\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Parse Ollama non-streaming response.\n * @param response\n * @param startTime\n * @returns A ChatResponse object containing the content blocks and usage.\n */\n _parseOllamaResponse(response: OllamaChatResponse, startTime: number): ChatResponse {\n const blocks: Array<TextBlock | ThinkingBlock | ToolCallBlock> = [];\n\n if (response.message.thinking) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'thinking',\n thinking: response.message.thinking,\n });\n }\n\n if (response.message.content) {\n blocks.push({\n id: crypto.randomUUID(),\n type: 'text',\n text: response.message.content,\n });\n }\n\n // Handle tool calls\n if (response.message.tool_calls && Array.isArray(response.message.tool_calls)) {\n for (let idx = 0; idx < response.message.tool_calls.length; idx++) {\n const toolCall = response.message.tool_calls[idx];\n blocks.push({\n type: 'tool_call',\n id: `${idx}_${toolCall.function.name}`,\n name: toolCall.function.name,\n input: JSON.stringify(toolCall.function.arguments),\n state: 'pending',\n });\n }\n }\n\n const usage =\n response.prompt_eval_count !== undefined && response.eval_count !== undefined\n ? {\n type: 'chat_usage',\n inputTokens: response.prompt_eval_count || 0,\n outputTokens: response.eval_count || 0,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * Build content blocks from accumulated data.\n * @param text\n * @param thinking\n * @param toolCalls\n * @returns An array of content blocks.\n */\n _buildContentBlocks(\n text: string,\n thinking: string,\n toolCalls: Map<string, ToolCallBlock>\n ): Array<TextBlock | ThinkingBlock | ToolCallBlock> {\n const blocks: Array<TextBlock | ThinkingBlock | ToolCallBlock> = [];\n\n if (thinking) {\n blocks.push({ id: crypto.randomUUID(), type: 'thinking', thinking });\n }\n\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text });\n }\n\n toolCalls.forEach(toolCall => {\n blocks.push(toolCall);\n });\n\n return blocks;\n }\n\n /**\n * Format tool choice parameter (not supported by Ollama).\n * @param _toolChoice\n * @returns undefined as Ollama does not support tool choice.\n */\n _formatToolChoice(_toolChoice?: ToolChoice): unknown {\n return undefined;\n }\n\n /**\n * Format tool schemas for Ollama API (no special formatting needed).\n * @param tools\n * @returns The same array of tool schemas, or an empty array if undefined.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n","import { OpenAI } from 'openai';\nimport {\n ChatCompletionMessageParam,\n ChatCompletionToolChoiceOption,\n} from 'openai/resources/chat/completions';\n\nimport { DataBlock, TextBlock, ThinkingBlock, ToolCallBlock } from '../message';\nimport { ToolChoice, ToolSchema } from '../type';\nimport { ChatModelBase, ChatModelOptions, ChatModelRequestOptions } from './base';\nimport { ChatResponse } from './response';\nimport { ChatUsage } from './usage';\nimport { OpenAIChatFormatter } from '../formatter';\n\ninterface OpenAIChatModelOptions extends ChatModelOptions {\n apiKey: string;\n presetGenParams?: Record<string, unknown>;\n baseURL?: string;\n}\n\n/**\n * The OpenAI API chat model.\n */\nexport class OpenAIChatModel extends ChatModelBase {\n protected client: OpenAI;\n protected presetGenParams: Record<string, unknown> | undefined;\n\n /**\n * Initializes a new instance of the OpenAIChatModel class.\n * @param options\n * @param options.modelName\n * @param options.apiKey\n * @param options.stream\n * @param options.maxRetries\n * @param options.fallbackModelName\n * @param options.presetGenParams\n * @param options.baseURL\n * @param options.formatter\n */\n constructor({\n modelName,\n apiKey,\n stream = true,\n maxRetries = 3,\n fallbackModelName,\n presetGenParams,\n baseURL,\n formatter,\n }: OpenAIChatModelOptions) {\n // If no formatter is provided, create a default OpenAIChatFormatter\n const defaultFormatter = formatter || new OpenAIChatFormatter();\n super({\n modelName,\n stream,\n maxRetries,\n fallbackModelName,\n formatter: defaultFormatter,\n } as ChatModelOptions);\n\n this.client = new OpenAI({\n apiKey: apiKey,\n baseURL,\n });\n this.presetGenParams = presetGenParams;\n }\n\n /**\n * Calls the OpenAI API with the given parameters.\n *\n * @param modelName - The name of the model to use.\n * @param options - The chat model options.\n * @returns A promise that resolves to either a ChatResponse or an AsyncGenerator of ChatResponses.\n */\n async _callAPI(\n modelName: string,\n options: ChatModelRequestOptions<ChatCompletionMessageParam>\n ): Promise<ChatResponse | AsyncGenerator<ChatResponse, ChatResponse>> {\n const startTime = Date.now();\n\n if (this.stream) {\n // Handle streaming response\n const stream = await this.client.chat.completions.create({\n model: modelName,\n messages: options.messages,\n tools: this._formatToolSchemas(options.tools),\n tool_choice: this._formatToolChoice(options.toolChoice),\n stream: true,\n ...(this.presetGenParams ?? {}),\n });\n\n return this._parseOpenAIStreamedResponse(stream, startTime);\n }\n\n // Handle non-streaming response\n const response = await this.client.chat.completions.create({\n model: modelName,\n messages: options.messages,\n tools: options.tools,\n tool_choice: this._formatToolChoice(options.toolChoice),\n stream: false,\n ...(this.presetGenParams ?? {}),\n });\n\n const choice = response.choices[0];\n const blocks: (TextBlock | ToolCallBlock | ThinkingBlock | DataBlock)[] = [];\n\n // handling text block\n if (choice.message.content) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: choice.message.content });\n }\n\n // handling tool calls\n if (choice.message.tool_calls && Array.isArray(choice.message.tool_calls)) {\n choice.message.tool_calls.forEach(toolCall => {\n if (toolCall.type === 'function') {\n blocks.push({\n type: 'tool_call',\n id: toolCall.id,\n name: toolCall.function.name,\n input: toolCall.function.arguments,\n state: 'pending',\n });\n }\n });\n }\n\n // handling usage\n const usage = response.usage\n ? {\n type: 'chat_usage',\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n time: (Date.now() - startTime) / 1000,\n }\n : undefined;\n\n return {\n type: 'chat',\n id: response.id,\n createdAt: new Date(response.created * 1000).toISOString(),\n content: blocks,\n usage,\n } as ChatResponse;\n }\n\n /**\n * Formats the tool choice for the API request.\n *\n * TODO: supports grouped tool choices.\n *\n * @param toolChoice - The tool choice option.\n * @returns The formatted tool choice.\n */\n _formatToolChoice(toolChoice?: ToolChoice): ChatCompletionToolChoiceOption {\n if (toolChoice) {\n // Directly return predefined options\n if (toolChoice === 'none' || toolChoice === 'auto' || toolChoice === 'required') {\n return toolChoice;\n }\n return {\n type: 'function',\n function: {\n name: toolChoice,\n },\n };\n }\n return 'auto';\n }\n\n /**\n * Parses a streamed response from OpenAI API.\n * An async generator that yields delta ChatResponse objects as they are received.\n *\n * @param stream - The OpenAI stream object.\n * @param startTime - The start time of the request for usage calculation.\n * @returns An async generator yielding delta ChatResponse objects, and returns the complete ChatResponse.\n */\n async *_parseOpenAIStreamedResponse(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n startTime: number\n ): AsyncGenerator<ChatResponse, ChatResponse> {\n let accText = '';\n // Store accumulated input strings for each tool call\n const accToolInputs: Map<string, string> = new Map();\n // Store tool call metadata (id, name)\n const toolCallMeta: Map<string, { id: string; name: string }> = new Map();\n let lastUsage: ChatUsage | null = null;\n let responseId = '';\n let createdTimestamp = 0;\n\n for await (const chunk of stream) {\n if (!responseId && chunk.id) {\n responseId = chunk.id;\n }\n if (!createdTimestamp && chunk.created) {\n createdTimestamp = chunk.created;\n }\n\n if (chunk.choices && chunk.choices.length > 0) {\n const choice = chunk.choices[0];\n\n // Delta data for this chunk\n let deltaText = '';\n const deltaToolCalls: Map<string, ToolCallBlock> = new Map();\n\n if (choice.delta?.content) {\n deltaText = choice.delta.content;\n accText += deltaText;\n }\n\n if (choice.delta?.tool_calls) {\n choice.delta.tool_calls.forEach(toolCall => {\n const index = toolCall.index.toString();\n\n // Initialize metadata if not exists\n if (!toolCallMeta.has(index)) {\n toolCallMeta.set(index, { id: '', name: '' });\n }\n if (!accToolInputs.has(index)) {\n accToolInputs.set(index, '');\n }\n\n // Update the tool call id\n if (toolCall.id) {\n toolCallMeta.get(index)!.id = toolCall.id;\n }\n // Update the tool call name\n if (toolCall.function?.name) {\n toolCallMeta.get(index)!.name = toolCall.function.name;\n }\n // Update the tool call input\n if (toolCall.function?.arguments) {\n const deltaArgs = toolCall.function.arguments;\n accToolInputs.set(index, accToolInputs.get(index)! + deltaArgs);\n\n // Create delta tool call with incremental input\n const meta = toolCallMeta.get(index)!;\n deltaToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: deltaArgs,\n state: 'pending',\n });\n }\n });\n }\n\n // Create a delta ChatResponse object\n const deltaBlocks = this._accDataToBlocks(deltaText, deltaToolCalls);\n\n yield {\n type: 'chat',\n id: responseId || crypto.randomUUID(),\n createdAt: createdTimestamp\n ? new Date(createdTimestamp * 1000).toISOString()\n : new Date().toISOString(),\n content: deltaBlocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n // Handle usage information (typically in the last chunk)\n if (chunk.usage) {\n lastUsage = {\n type: 'chat_usage',\n inputTokens: chunk.usage.prompt_tokens || 0,\n outputTokens: chunk.usage.completion_tokens || 0,\n time: (Date.now() - startTime) / 1000,\n };\n }\n }\n\n // Build final tool calls with complete JSON strings\n const finalToolCalls: Map<string, ToolCallBlock> = new Map();\n toolCallMeta.forEach((meta, index) => {\n finalToolCalls.set(index, {\n type: 'tool_call',\n id: meta.id,\n name: meta.name,\n input: accToolInputs.get(index) || '{}',\n state: 'pending',\n });\n });\n\n const blocks = this._accDataToBlocks(accText, finalToolCalls);\n return {\n type: 'chat',\n id: responseId || crypto.randomUUID(),\n createdAt: createdTimestamp\n ? new Date(createdTimestamp * 1000).toISOString()\n : new Date().toISOString(),\n content: blocks,\n usage: lastUsage,\n } as ChatResponse;\n }\n\n /**\n * Convert data into blocks\n *\n * @param text - The text response from the llm API\n * @param toolCalls - The tool calls\n * @returns An array of blocks\n */\n _accDataToBlocks(\n text: string,\n toolCalls: Map<string, ToolCallBlock>\n ): (TextBlock | ToolCallBlock)[] {\n const blocks: (TextBlock | ToolCallBlock)[] = [];\n if (text) {\n blocks.push({ id: crypto.randomUUID(), type: 'text', text: text });\n }\n // Push the tool calls into the blocks\n if (toolCalls.size > 0) {\n toolCalls.forEach(value => {\n blocks.push(value);\n });\n }\n\n return blocks;\n }\n\n /**\n * Format the tool schemas to the expected API format.\n * @param tools\n * @returns The formatted tool schemas.\n */\n _formatToolSchemas(tools: ToolSchema[] | undefined): ToolSchema[] {\n return tools || [];\n }\n}\n"],"mappings":"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","names":["format","response"]}