@code-yeongyu/senpi-ai 2026.7.28 → 2026.7.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/openai-client-auth.d.ts +7 -0
- package/dist/api/openai-client-auth.d.ts.map +1 -0
- package/dist/api/openai-client-auth.js +15 -0
- package/dist/api/openai-client-auth.js.map +1 -0
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +4 -20
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +9 -22
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/auth/headers.d.ts +5 -0
- package/dist/auth/headers.d.ts.map +1 -0
- package/dist/auth/headers.js +41 -0
- package/dist/auth/headers.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/tool-call-middleware/context-transformer.d.ts.map +1 -1
- package/dist/tool-call-middleware/context-transformer.js +9 -0
- package/dist/tool-call-middleware/context-transformer.js.map +1 -1
- package/dist/tool-call-middleware/index.d.ts +5 -0
- package/dist/tool-call-middleware/index.d.ts.map +1 -1
- package/dist/tool-call-middleware/index.js +12 -2
- package/dist/tool-call-middleware/index.js.map +1 -1
- package/dist/tool-call-middleware/protocols/kimi-xtml/format.d.ts +5 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/format.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/format.js +54 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/format.js.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/index.d.ts +4 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/index.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/index.js +4 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/index.js.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/markers.d.ts +10 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/markers.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/markers.js +30 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/markers.js.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/parse.d.ts +12 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/parse.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/parse.js +95 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/parse.js.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.d.ts +5 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.js +207 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.js.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/stream.d.ts +4 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/stream.d.ts.map +1 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/stream.js +181 -0
- package/dist/tool-call-middleware/protocols/kimi-xtml/stream.js.map +1 -0
- package/dist/tool-call-middleware/recovery-stream-wrapper.d.ts +2 -1
- package/dist/tool-call-middleware/recovery-stream-wrapper.d.ts.map +1 -1
- package/dist/tool-call-middleware/recovery-stream-wrapper.js +3 -2
- package/dist/tool-call-middleware/recovery-stream-wrapper.js.map +1 -1
- package/dist/tool-call-middleware/recovery-text-projection.d.ts +2 -1
- package/dist/tool-call-middleware/recovery-text-projection.d.ts.map +1 -1
- package/dist/tool-call-middleware/recovery-text-projection.js +2 -2
- package/dist/tool-call-middleware/recovery-text-projection.js.map +1 -1
- package/dist/tool-call-middleware/types.d.ts +2 -1
- package/dist/tool-call-middleware/types.d.ts.map +1 -1
- package/dist/tool-call-middleware/types.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/retry.d.ts +7 -0
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +29 -0
- package/dist/utils/retry.js.map +1 -1
- package/package.json +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-transformer.js","sourceRoot":"","sources":["../../src/tool-call-middleware/context-transformer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAssistantMessage,\n\tContext,\n\tMessage,\n\tTextContent,\n\tThinkingContent,\n\tToolResultMessage,\n\tUserMessage,\n} from \"../types.ts\";\nimport {\n\tanthropicXmlFormatToolCall,\n\tanthropicXmlFormatToolResponse,\n\tanthropicXmlFormatToolsSystemPrompt,\n\tcreateAnthropicXmlStreamParser,\n\tparseAnthropicXmlGeneratedText,\n} from \"./protocols/anthropic-xml/index.ts\";\nimport {\n\tantmlFormatToolCall,\n\tantmlFormatToolResponse,\n\tantmlFormatToolsSystemPrompt,\n\tcreateAntmlStreamParser,\n\tparseAntmlGeneratedText,\n} from \"./protocols/antml/index.ts\";\nimport {\n\tgemma4CreateStreamParser,\n\tgemma4FormatToolCall,\n\tgemma4FormatToolResponse,\n\tgemma4FormatToolsSystemPrompt,\n\tgemma4ParseGeneratedText,\n} from \"./protocols/gemma4.ts\";\nimport {\n\thermesCreateStreamParser,\n\thermesFormatToolCall,\n\thermesFormatToolResponse,\n\thermesFormatToolsSystemPrompt,\n\thermesParseGeneratedText,\n} from \"./protocols/hermes.ts\";\nimport {\n\tcreateMorphXmlStreamParser,\n\tmorphXmlFormatToolCall,\n\tmorphXmlFormatToolResponse,\n\tmorphXmlFormatToolsSystemPrompt,\n\tparseMorphXmlGeneratedText,\n} from \"./protocols/morph-xml.ts\";\nimport {\n\tcreateYamlXmlStreamParser,\n\tparseYamlXmlGeneratedText,\n\tyamlXmlFormatToolCall,\n\tyamlXmlFormatToolResponse,\n\tyamlXmlFormatToolsSystemPrompt,\n} from \"./protocols/yaml-xml.ts\";\nimport type { ToolCallFormat, ToolCallProtocol } from \"./types.ts\";\n\n/**\n * Hermes protocol implementation for tool call formatting and parsing.\n */\nconst hermesProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: hermesFormatToolsSystemPrompt,\n\tformatToolResponse: hermesFormatToolResponse,\n\tformatToolCall: hermesFormatToolCall,\n\tparseGeneratedText: hermesParseGeneratedText,\n\tcreateStreamParser: hermesCreateStreamParser,\n};\n\n/**\n * MorphXml protocol implementation for tool call formatting and parsing.\n */\nconst morphXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: morphXmlFormatToolsSystemPrompt,\n\tformatToolResponse: morphXmlFormatToolResponse,\n\tformatToolCall: morphXmlFormatToolCall,\n\tparseGeneratedText: parseMorphXmlGeneratedText,\n\tcreateStreamParser: createMorphXmlStreamParser,\n};\n\nconst yamlXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: yamlXmlFormatToolsSystemPrompt,\n\tformatToolResponse: yamlXmlFormatToolResponse,\n\tformatToolCall: yamlXmlFormatToolCall,\n\tparseGeneratedText: parseYamlXmlGeneratedText,\n\tcreateStreamParser: createYamlXmlStreamParser,\n};\n\n/**\n * Gemma 4 protocol implementation for tool call formatting and parsing.\n */\nconst gemma4Protocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: gemma4FormatToolsSystemPrompt,\n\tformatToolResponse: gemma4FormatToolResponse,\n\tformatToolCall: gemma4FormatToolCall,\n\tparseGeneratedText: gemma4ParseGeneratedText,\n\tcreateStreamParser: gemma4CreateStreamParser,\n};\n\nconst antmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: antmlFormatToolsSystemPrompt,\n\tformatToolResponse: antmlFormatToolResponse,\n\tformatToolCall: antmlFormatToolCall,\n\tparseGeneratedText: parseAntmlGeneratedText,\n\tcreateStreamParser: createAntmlStreamParser,\n};\n\nconst anthropicXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: anthropicXmlFormatToolsSystemPrompt,\n\tformatToolResponse: anthropicXmlFormatToolResponse,\n\tformatToolCall: anthropicXmlFormatToolCall,\n\tparseGeneratedText: parseAnthropicXmlGeneratedText,\n\tcreateStreamParser: createAnthropicXmlStreamParser,\n};\n\n/**\n * Protocol registry mapping format strings to protocol implementations.\n */\nconst protocolRegistry: Record<ToolCallFormat, ToolCallProtocol> = {\n\t\"anthropic-xml\": anthropicXmlProtocol,\n\tantml: antmlProtocol,\n\thermes: hermesProtocol,\n\txml: morphXmlProtocol,\n\t\"morph-xml\": morphXmlProtocol,\n\t\"yaml-xml\": yamlXmlProtocol,\n\t\"gemma4-delimiter\": gemma4Protocol,\n};\n\n/**\n * Gets the protocol implementation for a given tool call format.\n * @param format - The tool call format\n * @returns The protocol implementation\n * @throws Error if the format is not supported\n */\nexport function getProtocol(format: ToolCallFormat): ToolCallProtocol {\n\tconst protocol = protocolRegistry[format];\n\tif (!protocol) {\n\t\tthrow new Error(`Unsupported tool call format: ${format}`);\n\t}\n\treturn protocol;\n}\n\n/**\n * Transforms a context for text-based tool calling.\n * - Strips tools from context (provider sees tool-free request)\n * - Injects tool definitions into system prompt\n * - Converts tool call messages in history to text format\n * - Converts tool result messages to user messages with text content\n *\n * @param context - The original context\n * @param protocol - The protocol to use for formatting\n * @returns A new transformed context (original is not mutated)\n */\nexport function transformContext(context: Context, protocol: ToolCallProtocol): Context {\n\t// Build new context without mutating original\n\tconst transformed: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: context.messages.map((msg) => transformMessage(msg, protocol)),\n\t\ttools: undefined, // Strip tools - provider sees tool-free request\n\t};\n\n\t// Inject tool definitions into system prompt if tools exist\n\tif (context.tools && context.tools.length > 0) {\n\t\tconst toolPrompt = protocol.formatToolsSystemPrompt(context.tools);\n\t\tif (toolPrompt) {\n\t\t\ttransformed.systemPrompt = context.systemPrompt ? `${toolPrompt}\\n\\n${context.systemPrompt}` : toolPrompt;\n\t\t}\n\t}\n\n\treturn transformed;\n}\n\n/**\n * Transforms a single message for text-based tool calling.\n * - AssistantMessage with ToolCall blocks: convert to text\n * - ToolResultMessage: convert to UserMessage with text content\n * - Other messages: pass through unchanged\n */\nfunction transformMessage(message: Message, protocol: ToolCallProtocol): Message {\n\tswitch (message.role) {\n\t\tcase \"assistant\": {\n\t\t\treturn transformAssistantMessage(message, protocol);\n\t\t}\n\t\tcase \"toolResult\": {\n\t\t\treturn transformToolResultMessage(message, protocol);\n\t\t}\n\t\tdefault: {\n\t\t\treturn message;\n\t\t}\n\t}\n}\n\n/**\n * Transforms an AssistantMessage, converting ToolCall content blocks to text.\n *\n * Flagged incomplete calls replay as canonical formatted calls from their sanitized parsed arguments; the paired error toolResult (created by agent-loop/pair-repair) is what tells the model the call failed — raw truncated markup never re-enters context.\n */\nfunction transformAssistantMessage(message: AssistantMessage, protocol: ToolCallProtocol): AssistantMessage {\n\t// Check if message has any ToolCall content blocks\n\tconst hasToolCalls = message.content.some((block) => block.type === \"toolCall\");\n\tif (!hasToolCalls) {\n\t\t// No tool calls - pass through unchanged\n\t\treturn message;\n\t}\n\n\t// Transform content blocks\n\tconst newContent: (TextContent | ThinkingContent)[] = [];\n\n\tfor (const block of message.content) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\": {\n\t\t\t\tnewContent.push(block);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"thinking\": {\n\t\t\t\tnewContent.push(block);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"toolCall\": {\n\t\t\t\tconst toolCallText = protocol.formatToolCall(block.name, block.arguments);\n\t\t\t\tnewContent.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: toolCallText,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return new AssistantMessage with transformed content\n\treturn {\n\t\t...message,\n\t\tcontent: newContent,\n\t};\n}\n\n/**\n * Transforms a ToolResultMessage to a UserMessage with text content.\n */\nfunction transformToolResultMessage(message: ToolResultMessage, protocol: ToolCallProtocol): UserMessage {\n\t// Format tool result as text using protocol formatter\n\tconst formattedResponse = protocol.formatToolResponse(message.toolName, message.toolCallId, message.content);\n\n\t// Return as UserMessage with text content\n\treturn {\n\t\trole: \"user\",\n\t\tcontent: formattedResponse,\n\t\ttimestamp: message.timestamp,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context-transformer.js","sourceRoot":"","sources":["../../src/tool-call-middleware/context-transformer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAssistantMessage,\n\tContext,\n\tMessage,\n\tTextContent,\n\tThinkingContent,\n\tToolResultMessage,\n\tUserMessage,\n} from \"../types.ts\";\nimport {\n\tanthropicXmlFormatToolCall,\n\tanthropicXmlFormatToolResponse,\n\tanthropicXmlFormatToolsSystemPrompt,\n\tcreateAnthropicXmlStreamParser,\n\tparseAnthropicXmlGeneratedText,\n} from \"./protocols/anthropic-xml/index.ts\";\nimport {\n\tantmlFormatToolCall,\n\tantmlFormatToolResponse,\n\tantmlFormatToolsSystemPrompt,\n\tcreateAntmlStreamParser,\n\tparseAntmlGeneratedText,\n} from \"./protocols/antml/index.ts\";\nimport {\n\tgemma4CreateStreamParser,\n\tgemma4FormatToolCall,\n\tgemma4FormatToolResponse,\n\tgemma4FormatToolsSystemPrompt,\n\tgemma4ParseGeneratedText,\n} from \"./protocols/gemma4.ts\";\nimport {\n\thermesCreateStreamParser,\n\thermesFormatToolCall,\n\thermesFormatToolResponse,\n\thermesFormatToolsSystemPrompt,\n\thermesParseGeneratedText,\n} from \"./protocols/hermes.ts\";\nimport {\n\tcreateKimiXtmlStreamParser,\n\tkimiXtmlFormatToolCall,\n\tkimiXtmlFormatToolResponse,\n\tkimiXtmlFormatToolsSystemPrompt,\n\tparseKimiXtmlGeneratedText,\n} from \"./protocols/kimi-xtml/index.ts\";\nimport {\n\tcreateMorphXmlStreamParser,\n\tmorphXmlFormatToolCall,\n\tmorphXmlFormatToolResponse,\n\tmorphXmlFormatToolsSystemPrompt,\n\tparseMorphXmlGeneratedText,\n} from \"./protocols/morph-xml.ts\";\nimport {\n\tcreateYamlXmlStreamParser,\n\tparseYamlXmlGeneratedText,\n\tyamlXmlFormatToolCall,\n\tyamlXmlFormatToolResponse,\n\tyamlXmlFormatToolsSystemPrompt,\n} from \"./protocols/yaml-xml.ts\";\nimport type { ToolCallFormat, ToolCallProtocol } from \"./types.ts\";\n\n/**\n * Hermes protocol implementation for tool call formatting and parsing.\n */\nconst hermesProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: hermesFormatToolsSystemPrompt,\n\tformatToolResponse: hermesFormatToolResponse,\n\tformatToolCall: hermesFormatToolCall,\n\tparseGeneratedText: hermesParseGeneratedText,\n\tcreateStreamParser: hermesCreateStreamParser,\n};\n\n/**\n * MorphXml protocol implementation for tool call formatting and parsing.\n */\nconst morphXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: morphXmlFormatToolsSystemPrompt,\n\tformatToolResponse: morphXmlFormatToolResponse,\n\tformatToolCall: morphXmlFormatToolCall,\n\tparseGeneratedText: parseMorphXmlGeneratedText,\n\tcreateStreamParser: createMorphXmlStreamParser,\n};\n\nconst yamlXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: yamlXmlFormatToolsSystemPrompt,\n\tformatToolResponse: yamlXmlFormatToolResponse,\n\tformatToolCall: yamlXmlFormatToolCall,\n\tparseGeneratedText: parseYamlXmlGeneratedText,\n\tcreateStreamParser: createYamlXmlStreamParser,\n};\n\n/**\n * Gemma 4 protocol implementation for tool call formatting and parsing.\n */\nconst gemma4Protocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: gemma4FormatToolsSystemPrompt,\n\tformatToolResponse: gemma4FormatToolResponse,\n\tformatToolCall: gemma4FormatToolCall,\n\tparseGeneratedText: gemma4ParseGeneratedText,\n\tcreateStreamParser: gemma4CreateStreamParser,\n};\n\nconst antmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: antmlFormatToolsSystemPrompt,\n\tformatToolResponse: antmlFormatToolResponse,\n\tformatToolCall: antmlFormatToolCall,\n\tparseGeneratedText: parseAntmlGeneratedText,\n\tcreateStreamParser: createAntmlStreamParser,\n};\n\nconst kimiXtmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: kimiXtmlFormatToolsSystemPrompt,\n\tformatToolResponse: kimiXtmlFormatToolResponse,\n\tformatToolCall: kimiXtmlFormatToolCall,\n\tparseGeneratedText: parseKimiXtmlGeneratedText,\n\tcreateStreamParser: createKimiXtmlStreamParser,\n};\n\nconst anthropicXmlProtocol: ToolCallProtocol = {\n\tformatToolsSystemPrompt: anthropicXmlFormatToolsSystemPrompt,\n\tformatToolResponse: anthropicXmlFormatToolResponse,\n\tformatToolCall: anthropicXmlFormatToolCall,\n\tparseGeneratedText: parseAnthropicXmlGeneratedText,\n\tcreateStreamParser: createAnthropicXmlStreamParser,\n};\n\n/**\n * Protocol registry mapping format strings to protocol implementations.\n */\nconst protocolRegistry: Record<ToolCallFormat, ToolCallProtocol> = {\n\t\"anthropic-xml\": anthropicXmlProtocol,\n\tantml: antmlProtocol,\n\thermes: hermesProtocol,\n\txml: morphXmlProtocol,\n\t\"morph-xml\": morphXmlProtocol,\n\t\"yaml-xml\": yamlXmlProtocol,\n\t\"gemma4-delimiter\": gemma4Protocol,\n\t\"kimi-xtml\": kimiXtmlProtocol,\n};\n\n/**\n * Gets the protocol implementation for a given tool call format.\n * @param format - The tool call format\n * @returns The protocol implementation\n * @throws Error if the format is not supported\n */\nexport function getProtocol(format: ToolCallFormat): ToolCallProtocol {\n\tconst protocol = protocolRegistry[format];\n\tif (!protocol) {\n\t\tthrow new Error(`Unsupported tool call format: ${format}`);\n\t}\n\treturn protocol;\n}\n\n/**\n * Transforms a context for text-based tool calling.\n * - Strips tools from context (provider sees tool-free request)\n * - Injects tool definitions into system prompt\n * - Converts tool call messages in history to text format\n * - Converts tool result messages to user messages with text content\n *\n * @param context - The original context\n * @param protocol - The protocol to use for formatting\n * @returns A new transformed context (original is not mutated)\n */\nexport function transformContext(context: Context, protocol: ToolCallProtocol): Context {\n\t// Build new context without mutating original\n\tconst transformed: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: context.messages.map((msg) => transformMessage(msg, protocol)),\n\t\ttools: undefined, // Strip tools - provider sees tool-free request\n\t};\n\n\t// Inject tool definitions into system prompt if tools exist\n\tif (context.tools && context.tools.length > 0) {\n\t\tconst toolPrompt = protocol.formatToolsSystemPrompt(context.tools);\n\t\tif (toolPrompt) {\n\t\t\ttransformed.systemPrompt = context.systemPrompt ? `${toolPrompt}\\n\\n${context.systemPrompt}` : toolPrompt;\n\t\t}\n\t}\n\n\treturn transformed;\n}\n\n/**\n * Transforms a single message for text-based tool calling.\n * - AssistantMessage with ToolCall blocks: convert to text\n * - ToolResultMessage: convert to UserMessage with text content\n * - Other messages: pass through unchanged\n */\nfunction transformMessage(message: Message, protocol: ToolCallProtocol): Message {\n\tswitch (message.role) {\n\t\tcase \"assistant\": {\n\t\t\treturn transformAssistantMessage(message, protocol);\n\t\t}\n\t\tcase \"toolResult\": {\n\t\t\treturn transformToolResultMessage(message, protocol);\n\t\t}\n\t\tdefault: {\n\t\t\treturn message;\n\t\t}\n\t}\n}\n\n/**\n * Transforms an AssistantMessage, converting ToolCall content blocks to text.\n *\n * Flagged incomplete calls replay as canonical formatted calls from their sanitized parsed arguments; the paired error toolResult (created by agent-loop/pair-repair) is what tells the model the call failed — raw truncated markup never re-enters context.\n */\nfunction transformAssistantMessage(message: AssistantMessage, protocol: ToolCallProtocol): AssistantMessage {\n\t// Check if message has any ToolCall content blocks\n\tconst hasToolCalls = message.content.some((block) => block.type === \"toolCall\");\n\tif (!hasToolCalls) {\n\t\t// No tool calls - pass through unchanged\n\t\treturn message;\n\t}\n\n\t// Transform content blocks\n\tconst newContent: (TextContent | ThinkingContent)[] = [];\n\n\tfor (const block of message.content) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\": {\n\t\t\t\tnewContent.push(block);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"thinking\": {\n\t\t\t\tnewContent.push(block);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"toolCall\": {\n\t\t\t\tconst toolCallText = protocol.formatToolCall(block.name, block.arguments);\n\t\t\t\tnewContent.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: toolCallText,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return new AssistantMessage with transformed content\n\treturn {\n\t\t...message,\n\t\tcontent: newContent,\n\t};\n}\n\n/**\n * Transforms a ToolResultMessage to a UserMessage with text content.\n */\nfunction transformToolResultMessage(message: ToolResultMessage, protocol: ToolCallProtocol): UserMessage {\n\t// Format tool result as text using protocol formatter\n\tconst formattedResponse = protocol.formatToolResponse(message.toolName, message.toolCallId, message.content);\n\n\t// Return as UserMessage with text content\n\treturn {\n\t\trole: \"user\",\n\t\tcontent: formattedResponse,\n\t\ttimestamp: message.timestamp,\n\t};\n}\n"]}
|
|
@@ -11,4 +11,9 @@ export type { ParsedToolCall, StreamParser, StreamParserEvent, ToolCallFormat, T
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function getToolCallFormat<TApi extends Api>(model: Model<TApi>): ToolCallFormat | undefined;
|
|
13
13
|
export declare function shouldRecoverTextToolCalls<TApi extends Api>(model: Model<TApi>): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the model leaks Kimi XTML channel markers when tool calling fails,
|
|
16
|
+
* selecting the XTML recovery parser over the default invoke recovery parser.
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasKimiTextToolCallRecovery<TApi extends Api>(model: Model<TApi>): boolean;
|
|
14
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAA2B,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,YAAY,EACX,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAA2B,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,YAAY,EACX,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,GAAG,SAAS,CAsBlG;AAED,wBAAgB,0BAA0B,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAMxF;AAKD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAEzF"}
|
|
@@ -21,7 +21,8 @@ export function getToolCallFormat(model) {
|
|
|
21
21
|
format === "yaml-xml" ||
|
|
22
22
|
format === "gemma4-delimiter" ||
|
|
23
23
|
format === "anthropic-xml" ||
|
|
24
|
-
format === "antml"
|
|
24
|
+
format === "antml" ||
|
|
25
|
+
format === "kimi-xtml") {
|
|
25
26
|
return format;
|
|
26
27
|
}
|
|
27
28
|
return undefined;
|
|
@@ -32,6 +33,15 @@ export function shouldRecoverTextToolCalls(model) {
|
|
|
32
33
|
if (model.recoverTextToolCalls !== undefined) {
|
|
33
34
|
return typeof model.recoverTextToolCalls === "boolean" ? model.recoverTextToolCalls : false;
|
|
34
35
|
}
|
|
35
|
-
return
|
|
36
|
+
return CLAUDE_MODEL_ID_PATTERN.test(model.id) || KIMI_MODEL_ID_PATTERN.test(model.id);
|
|
37
|
+
}
|
|
38
|
+
const CLAUDE_MODEL_ID_PATTERN = /(^|[^a-z0-9])claude([^a-z0-9]|$)/i;
|
|
39
|
+
const KIMI_MODEL_ID_PATTERN = /(^|[^a-z0-9])kimi([^a-z0-9]|$)/i;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the model leaks Kimi XTML channel markers when tool calling fails,
|
|
42
|
+
* selecting the XTML recovery parser over the default invoke recovery parser.
|
|
43
|
+
*/
|
|
44
|
+
export function hasKimiTextToolCallRecovery(model) {
|
|
45
|
+
return KIMI_MODEL_ID_PATTERN.test(model.id);
|
|
36
46
|
}
|
|
37
47
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tool-call-middleware/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAUvE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAmB,KAAkB;IACrE,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAA6C,CAAC;IACnE,MAAM,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IACC,MAAM,KAAK,QAAQ;QACnB,MAAM,KAAK,KAAK;QAChB,MAAM,KAAK,WAAW;QACtB,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,kBAAkB;QAC7B,MAAM,KAAK,eAAe;QAC1B,MAAM,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tool-call-middleware/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAUvE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAmB,KAAkB;IACrE,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAA6C,CAAC;IACnE,MAAM,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IACC,MAAM,KAAK,QAAQ;QACnB,MAAM,KAAK,KAAK;QAChB,MAAM,KAAK,WAAW;QACtB,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,kBAAkB;QAC7B,MAAM,KAAK,eAAe;QAC1B,MAAM,KAAK,OAAO;QAClB,MAAM,KAAK,WAAW,EACrB,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAmB,KAAkB;IAC9E,IAAI,iBAAiB,CAAC,KAAK,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACzD,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC9C,OAAO,OAAO,KAAK,CAAC,oBAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7F,CAAC;IACD,OAAO,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,uBAAuB,GAAG,mCAAmC,CAAC;AACpE,MAAM,qBAAqB,GAAG,iCAAiC,CAAC;AAEhE;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAmB,KAAkB;IAC/E,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import type { Api, Model, OpenAICompletionsCompat } from \"../types.ts\";\nimport type { ToolCallFormat } from \"./types.ts\";\n\nexport { getProtocol, transformContext } from \"./context-transformer.ts\";\nexport { wrapStreamWithToolCallMiddleware } from \"./stream-wrapper.ts\";\nexport type {\n\tParsedToolCall,\n\tStreamParser,\n\tStreamParserEvent,\n\tToolCallFormat,\n\tToolCallProtocol,\n\tToolResultContent,\n} from \"./types.ts\";\n\n/**\n * Extracts the tool call format from a model's compatibility settings.\n * Only applies to models using the \"openai-completions\" API with compat settings.\n * @param model - The model to check\n * @returns The configured supported tool call format, or undefined if not set. \"morph-xml\" is canonical; \"xml\" remains a deprecated alias.\n */\nexport function getToolCallFormat<TApi extends Api>(model: Model<TApi>): ToolCallFormat | undefined {\n\tif (model.api !== \"openai-completions\") {\n\t\treturn undefined;\n\t}\n\tconst compat = model.compat as OpenAICompletionsCompat | undefined;\n\tconst format = compat?.toolCallFormat;\n\tif (!format) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tformat === \"hermes\" ||\n\t\tformat === \"xml\" ||\n\t\tformat === \"morph-xml\" ||\n\t\tformat === \"yaml-xml\" ||\n\t\tformat === \"gemma4-delimiter\" ||\n\t\tformat === \"anthropic-xml\" ||\n\t\tformat === \"antml\" ||\n\t\tformat === \"kimi-xtml\"\n\t) {\n\t\treturn format;\n\t}\n\treturn undefined;\n}\n\nexport function shouldRecoverTextToolCalls<TApi extends Api>(model: Model<TApi>): boolean {\n\tif (getToolCallFormat(model) !== undefined) return false;\n\tif (model.recoverTextToolCalls !== undefined) {\n\t\treturn typeof model.recoverTextToolCalls === \"boolean\" ? model.recoverTextToolCalls : false;\n\t}\n\treturn CLAUDE_MODEL_ID_PATTERN.test(model.id) || KIMI_MODEL_ID_PATTERN.test(model.id);\n}\n\nconst CLAUDE_MODEL_ID_PATTERN = /(^|[^a-z0-9])claude([^a-z0-9]|$)/i;\nconst KIMI_MODEL_ID_PATTERN = /(^|[^a-z0-9])kimi([^a-z0-9]|$)/i;\n\n/**\n * Whether the model leaks Kimi XTML channel markers when tool calling fails,\n * selecting the XTML recovery parser over the default invoke recovery parser.\n */\nexport function hasKimiTextToolCallRecovery<TApi extends Api>(model: Model<TApi>): boolean {\n\treturn KIMI_MODEL_ID_PATTERN.test(model.id);\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ImageContent, TextContent, Tool } from "../../../types.ts";
|
|
2
|
+
export declare function kimiXtmlFormatToolCall(name: string, args: Record<string, unknown>): string;
|
|
3
|
+
export declare function kimiXtmlFormatToolResponse(toolName: string, _toolCallId: string, content: (TextContent | ImageContent)[]): string;
|
|
4
|
+
export declare function kimiXtmlFormatToolsSystemPrompt(tools: Tool[]): string;
|
|
5
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAuBzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAQ1F;AAED,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,GACrC,MAAM,CAMR;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAqBrE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { XTML_ARGUMENT_CLOSE, XTML_ARGUMENT_OPEN, XTML_CALL_CLOSE, XTML_SEP, XTML_TOOLS_CLOSE, XTML_TOOLS_OPEN, } from "./markers.js";
|
|
2
|
+
function inferXtmlType(value) {
|
|
3
|
+
if (typeof value === "number")
|
|
4
|
+
return "number";
|
|
5
|
+
if (typeof value === "boolean")
|
|
6
|
+
return "boolean";
|
|
7
|
+
if (Array.isArray(value))
|
|
8
|
+
return "array";
|
|
9
|
+
if (typeof value === "object" && value !== null)
|
|
10
|
+
return "object";
|
|
11
|
+
return "string";
|
|
12
|
+
}
|
|
13
|
+
function serializeXtmlValue(value, type) {
|
|
14
|
+
if (type === "object" || type === "array")
|
|
15
|
+
return JSON.stringify(value);
|
|
16
|
+
return String(value);
|
|
17
|
+
}
|
|
18
|
+
export function kimiXtmlFormatToolCall(name, args) {
|
|
19
|
+
const renderedArgs = Object.entries(args)
|
|
20
|
+
.map(([key, value]) => {
|
|
21
|
+
const type = inferXtmlType(value);
|
|
22
|
+
return `${XTML_ARGUMENT_OPEN}key="${key}" type="${type}"${XTML_SEP}${serializeXtmlValue(value, type)}${XTML_ARGUMENT_CLOSE}`;
|
|
23
|
+
})
|
|
24
|
+
.join("");
|
|
25
|
+
return `${XTML_TOOLS_OPEN}${"<|open|>call "}tool="${name}" index="1"${XTML_SEP}${renderedArgs}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}`;
|
|
26
|
+
}
|
|
27
|
+
export function kimiXtmlFormatToolResponse(toolName, _toolCallId, content) {
|
|
28
|
+
const text = content
|
|
29
|
+
.filter((item) => item.type === "text")
|
|
30
|
+
.map((item) => item.text)
|
|
31
|
+
.join("\n");
|
|
32
|
+
return `## Return of ${toolName}\n${text}`;
|
|
33
|
+
}
|
|
34
|
+
export function kimiXtmlFormatToolsSystemPrompt(tools) {
|
|
35
|
+
if (tools.length === 0)
|
|
36
|
+
return "";
|
|
37
|
+
const toolDescriptions = tools
|
|
38
|
+
.map((tool) => `Name: ${tool.name}\nDescription: ${tool.description}\nParameters Schema:\n${JSON.stringify(tool.parameters, null, 3)}`)
|
|
39
|
+
.join("\n\n");
|
|
40
|
+
return `You have access to the following tools. Use them when appropriate.
|
|
41
|
+
|
|
42
|
+
${toolDescriptions}
|
|
43
|
+
|
|
44
|
+
When you need to use a tool, format your response exactly like this, with no other text inside the tools block:
|
|
45
|
+
|
|
46
|
+
${XTML_TOOLS_OPEN}${"<|open|>call "}tool="tool_name" index="1"${XTML_SEP}${XTML_ARGUMENT_OPEN}key="param" type="string"${XTML_SEP}value${XTML_ARGUMENT_CLOSE}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}
|
|
47
|
+
|
|
48
|
+
Formatting rules:
|
|
49
|
+
- Emit one ${"<|open|>call "}...${XTML_CALL_CLOSE} section per tool call inside a single tools block.
|
|
50
|
+
- Argument types: string (default when type is omitted), number, boolean, object, array.
|
|
51
|
+
- object and array values must be strict JSON; string values are raw text and need no quoting.
|
|
52
|
+
- Example: ${XTML_TOOLS_OPEN}${"<|open|>call "}tool="get_weather" index="1"${XTML_SEP}${XTML_ARGUMENT_OPEN}key="city" type="string"${XTML_SEP}Seoul${XTML_ARGUMENT_CLOSE}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}`;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/format.ts"],"names":[],"mappings":"AACA,OAAO,EACN,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,eAAe,GACf,MAAM,cAAc,CAAC;AAEtB,SAAS,aAAa,CAAC,KAAc;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/C,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAC;IACjE,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc,EAAE,IAAY;IACvD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,IAA6B;IACjF,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,GAAG,kBAAkB,QAAQ,GAAG,WAAW,IAAI,IAAI,QAAQ,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,mBAAmB,EAAE,CAAC;IAC9H,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,OAAO,GAAG,eAAe,GAAG,eAAe,SAAS,IAAI,cAAc,QAAQ,GAAG,YAAY,GAAG,eAAe,GAAG,gBAAgB,EAAE,CAAC;AACtI,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,QAAgB,EAChB,WAAmB,EACnB,OAAuC;IAEvC,MAAM,IAAI,GAAG,OAAO;SAClB,MAAM,CAAC,CAAC,IAAI,EAAuB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;SAC3D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,gBAAgB,QAAQ,KAAK,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAa;IAC5D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,gBAAgB,GAAG,KAAK;SAC5B,GAAG,CACH,CAAC,IAAI,EAAE,EAAE,CACR,SAAS,IAAI,CAAC,IAAI,kBAAkB,IAAI,CAAC,WAAW,yBAAyB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CACxH;SACA,IAAI,CAAC,MAAM,CAAC,CAAC;IACf,OAAO;;EAEN,gBAAgB;;;;EAIhB,eAAe,GAAG,eAAe,6BAA6B,QAAQ,GAAG,kBAAkB,4BAA4B,QAAQ,QAAQ,mBAAmB,GAAG,eAAe,GAAG,gBAAgB;;;aAGpL,eAAe,MAAM,eAAe;;;aAGpC,eAAe,GAAG,eAAe,+BAA+B,QAAQ,GAAG,kBAAkB,2BAA2B,QAAQ,QAAQ,mBAAmB,GAAG,eAAe,GAAG,gBAAgB,EAAE,CAAC;AAChN,CAAC","sourcesContent":["import type { ImageContent, TextContent, Tool } from \"../../../types.ts\";\nimport {\n\tXTML_ARGUMENT_CLOSE,\n\tXTML_ARGUMENT_OPEN,\n\tXTML_CALL_CLOSE,\n\tXTML_SEP,\n\tXTML_TOOLS_CLOSE,\n\tXTML_TOOLS_OPEN,\n} from \"./markers.ts\";\n\nfunction inferXtmlType(value: unknown): string {\n\tif (typeof value === \"number\") return \"number\";\n\tif (typeof value === \"boolean\") return \"boolean\";\n\tif (Array.isArray(value)) return \"array\";\n\tif (typeof value === \"object\" && value !== null) return \"object\";\n\treturn \"string\";\n}\n\nfunction serializeXtmlValue(value: unknown, type: string): string {\n\tif (type === \"object\" || type === \"array\") return JSON.stringify(value);\n\treturn String(value);\n}\n\nexport function kimiXtmlFormatToolCall(name: string, args: Record<string, unknown>): string {\n\tconst renderedArgs = Object.entries(args)\n\t\t.map(([key, value]) => {\n\t\t\tconst type = inferXtmlType(value);\n\t\t\treturn `${XTML_ARGUMENT_OPEN}key=\"${key}\" type=\"${type}\"${XTML_SEP}${serializeXtmlValue(value, type)}${XTML_ARGUMENT_CLOSE}`;\n\t\t})\n\t\t.join(\"\");\n\treturn `${XTML_TOOLS_OPEN}${\"<|open|>call \"}tool=\"${name}\" index=\"1\"${XTML_SEP}${renderedArgs}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}`;\n}\n\nexport function kimiXtmlFormatToolResponse(\n\ttoolName: string,\n\t_toolCallId: string,\n\tcontent: (TextContent | ImageContent)[],\n): string {\n\tconst text = content\n\t\t.filter((item): item is TextContent => item.type === \"text\")\n\t\t.map((item) => item.text)\n\t\t.join(\"\\n\");\n\treturn `## Return of ${toolName}\\n${text}`;\n}\n\nexport function kimiXtmlFormatToolsSystemPrompt(tools: Tool[]): string {\n\tif (tools.length === 0) return \"\";\n\tconst toolDescriptions = tools\n\t\t.map(\n\t\t\t(tool) =>\n\t\t\t\t`Name: ${tool.name}\\nDescription: ${tool.description}\\nParameters Schema:\\n${JSON.stringify(tool.parameters, null, 3)}`,\n\t\t)\n\t\t.join(\"\\n\\n\");\n\treturn `You have access to the following tools. Use them when appropriate.\n\n${toolDescriptions}\n\nWhen you need to use a tool, format your response exactly like this, with no other text inside the tools block:\n\n${XTML_TOOLS_OPEN}${\"<|open|>call \"}tool=\"tool_name\" index=\"1\"${XTML_SEP}${XTML_ARGUMENT_OPEN}key=\"param\" type=\"string\"${XTML_SEP}value${XTML_ARGUMENT_CLOSE}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}\n\nFormatting rules:\n- Emit one ${\"<|open|>call \"}...${XTML_CALL_CLOSE} section per tool call inside a single tools block.\n- Argument types: string (default when type is omitted), number, boolean, object, array.\n- object and array values must be strict JSON; string values are raw text and need no quoting.\n- Example: ${XTML_TOOLS_OPEN}${\"<|open|>call \"}tool=\"get_weather\" index=\"1\"${XTML_SEP}${XTML_ARGUMENT_OPEN}key=\"city\" type=\"string\"${XTML_SEP}Seoul${XTML_ARGUMENT_CLOSE}${XTML_CALL_CLOSE}${XTML_TOOLS_CLOSE}`;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export {\n\tkimiXtmlFormatToolCall,\n\tkimiXtmlFormatToolResponse,\n\tkimiXtmlFormatToolsSystemPrompt,\n} from \"./format.ts\";\nexport { parseKimiXtmlGeneratedText } from \"./parse.ts\";\nexport { createKimiXtmlStreamParser } from \"./stream.ts\";\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const XTML_TOOLS_OPEN = "<|open|>tools<|sep|>";
|
|
2
|
+
export declare const XTML_TOOLS_CLOSE = "<|close|>tools<|sep|>";
|
|
3
|
+
export declare const XTML_CALL_OPEN = "<|open|>call ";
|
|
4
|
+
export declare const XTML_CALL_CLOSE = "<|close|>call<|sep|>";
|
|
5
|
+
export declare const XTML_ARGUMENT_OPEN = "<|open|>argument ";
|
|
6
|
+
export declare const XTML_ARGUMENT_CLOSE = "<|close|>argument<|sep|>";
|
|
7
|
+
export declare const XTML_SEP = "<|sep|>";
|
|
8
|
+
export declare function parseXtmlAttributes(header: string): Record<string, string>;
|
|
9
|
+
export declare function getPartialXtmlSuffix(text: string, tokens: readonly string[]): string;
|
|
10
|
+
//# sourceMappingURL=markers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markers.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/markers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AACxD,eAAO,MAAM,cAAc,kBAAkB,CAAC;AAC9C,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AACtD,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,QAAQ,YAAY,CAAC;AAIlC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ1E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAUpF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const XTML_TOOLS_OPEN = "<|open|>tools<|sep|>";
|
|
2
|
+
export const XTML_TOOLS_CLOSE = "<|close|>tools<|sep|>";
|
|
3
|
+
export const XTML_CALL_OPEN = "<|open|>call ";
|
|
4
|
+
export const XTML_CALL_CLOSE = "<|close|>call<|sep|>";
|
|
5
|
+
export const XTML_ARGUMENT_OPEN = "<|open|>argument ";
|
|
6
|
+
export const XTML_ARGUMENT_CLOSE = "<|close|>argument<|sep|>";
|
|
7
|
+
export const XTML_SEP = "<|sep|>";
|
|
8
|
+
const ATTRIBUTE_PATTERN = /([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s<]+))/g;
|
|
9
|
+
export function parseXtmlAttributes(header) {
|
|
10
|
+
const attributes = {};
|
|
11
|
+
for (const match of header.matchAll(ATTRIBUTE_PATTERN)) {
|
|
12
|
+
const key = match[1];
|
|
13
|
+
if (!key)
|
|
14
|
+
continue;
|
|
15
|
+
attributes[key] = match[2] ?? match[3] ?? match[4] ?? "";
|
|
16
|
+
}
|
|
17
|
+
return attributes;
|
|
18
|
+
}
|
|
19
|
+
export function getPartialXtmlSuffix(text, tokens) {
|
|
20
|
+
for (const token of tokens) {
|
|
21
|
+
for (let length = token.length - 1; length > 0; length -= 1) {
|
|
22
|
+
const prefix = token.slice(0, length);
|
|
23
|
+
if (text.endsWith(prefix)) {
|
|
24
|
+
return prefix;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=markers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markers.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/markers.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;AAC9C,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;AACtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAC9D,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAC;AAElC,MAAM,iBAAiB,GAAG,mDAAmD,CAAC;AAE9E,MAAM,UAAU,mBAAmB,CAAC,MAAc;IACjD,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACxD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,MAAyB;IAC3E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,OAAO,MAAM,CAAC;YACf,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC","sourcesContent":["export const XTML_TOOLS_OPEN = \"<|open|>tools<|sep|>\";\nexport const XTML_TOOLS_CLOSE = \"<|close|>tools<|sep|>\";\nexport const XTML_CALL_OPEN = \"<|open|>call \";\nexport const XTML_CALL_CLOSE = \"<|close|>call<|sep|>\";\nexport const XTML_ARGUMENT_OPEN = \"<|open|>argument \";\nexport const XTML_ARGUMENT_CLOSE = \"<|close|>argument<|sep|>\";\nexport const XTML_SEP = \"<|sep|>\";\n\nconst ATTRIBUTE_PATTERN = /([\\w-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s<]+))/g;\n\nexport function parseXtmlAttributes(header: string): Record<string, string> {\n\tconst attributes: Record<string, string> = {};\n\tfor (const match of header.matchAll(ATTRIBUTE_PATTERN)) {\n\t\tconst key = match[1];\n\t\tif (!key) continue;\n\t\tattributes[key] = match[2] ?? match[3] ?? match[4] ?? \"\";\n\t}\n\treturn attributes;\n}\n\nexport function getPartialXtmlSuffix(text: string, tokens: readonly string[]): string {\n\tfor (const token of tokens) {\n\t\tfor (let length = token.length - 1; length > 0; length -= 1) {\n\t\t\tconst prefix = token.slice(0, length);\n\t\t\tif (text.endsWith(prefix)) {\n\t\t\t\treturn prefix;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\";\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Tool } from "../../../types.ts";
|
|
2
|
+
import type { ParsedToolCall, ParserOptions } from "../../types.ts";
|
|
3
|
+
type CoercedValue = {
|
|
4
|
+
ok: true;
|
|
5
|
+
value: unknown;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
};
|
|
9
|
+
export declare function coerceXtmlArgumentValue(raw: string, type: string | undefined): CoercedValue;
|
|
10
|
+
export declare function parseKimiXtmlGeneratedText(text: string, tools: Tool[], options?: ParserOptions): ParsedToolCall[];
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAYpE,KAAK,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAEjE,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAuB3F;AA4BD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc,EAAE,CAoCjH"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { parseXtmlAttributes, XTML_ARGUMENT_CLOSE, XTML_ARGUMENT_OPEN, XTML_CALL_CLOSE, XTML_CALL_OPEN, XTML_SEP, XTML_TOOLS_CLOSE, XTML_TOOLS_OPEN, } from "./markers.js";
|
|
2
|
+
export function coerceXtmlArgumentValue(raw, type) {
|
|
3
|
+
switch (type) {
|
|
4
|
+
case undefined:
|
|
5
|
+
case "string":
|
|
6
|
+
return { ok: true, value: raw };
|
|
7
|
+
case "number": {
|
|
8
|
+
const parsed = Number(raw);
|
|
9
|
+
return Number.isNaN(parsed) ? { ok: false } : { ok: true, value: parsed };
|
|
10
|
+
}
|
|
11
|
+
case "boolean":
|
|
12
|
+
if (raw === "true")
|
|
13
|
+
return { ok: true, value: true };
|
|
14
|
+
if (raw === "false")
|
|
15
|
+
return { ok: true, value: false };
|
|
16
|
+
return { ok: false };
|
|
17
|
+
case "object":
|
|
18
|
+
case "array":
|
|
19
|
+
try {
|
|
20
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { ok: false };
|
|
24
|
+
}
|
|
25
|
+
default:
|
|
26
|
+
return { ok: true, value: raw };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function parseCallBody(body, tool, options) {
|
|
30
|
+
const args = {};
|
|
31
|
+
let rest = body;
|
|
32
|
+
for (;;) {
|
|
33
|
+
rest = rest.replace(/^\s+/, "");
|
|
34
|
+
if (!rest.startsWith(XTML_ARGUMENT_OPEN))
|
|
35
|
+
break;
|
|
36
|
+
const headerEnd = rest.indexOf(XTML_SEP, XTML_ARGUMENT_OPEN.length);
|
|
37
|
+
if (headerEnd === -1)
|
|
38
|
+
break;
|
|
39
|
+
const attributes = parseXtmlAttributes(rest.slice(XTML_ARGUMENT_OPEN.length, headerEnd));
|
|
40
|
+
const key = attributes.key;
|
|
41
|
+
const valueStart = headerEnd + XTML_SEP.length;
|
|
42
|
+
const valueEnd = rest.indexOf(XTML_ARGUMENT_CLOSE, valueStart);
|
|
43
|
+
if (valueEnd === -1 || !key)
|
|
44
|
+
break;
|
|
45
|
+
const coerced = coerceXtmlArgumentValue(rest.slice(valueStart, valueEnd), attributes.type);
|
|
46
|
+
if (!coerced.ok) {
|
|
47
|
+
options?.onError?.(`kimi-xtml: invalid value for argument "${key}" on tool "${tool.name}".`, {
|
|
48
|
+
toolCall: rest.slice(0, valueEnd + XTML_ARGUMENT_CLOSE.length),
|
|
49
|
+
});
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
args[key] = coerced.value;
|
|
53
|
+
rest = rest.slice(valueEnd + XTML_ARGUMENT_CLOSE.length);
|
|
54
|
+
}
|
|
55
|
+
return args;
|
|
56
|
+
}
|
|
57
|
+
export function parseKimiXtmlGeneratedText(text, tools, options) {
|
|
58
|
+
const parsed = [];
|
|
59
|
+
let cursor = 0;
|
|
60
|
+
while (cursor < text.length) {
|
|
61
|
+
const blockStart = text.indexOf(XTML_TOOLS_OPEN, cursor);
|
|
62
|
+
if (blockStart === -1)
|
|
63
|
+
break;
|
|
64
|
+
const bodyStart = blockStart + XTML_TOOLS_OPEN.length;
|
|
65
|
+
const blockEnd = text.indexOf(XTML_TOOLS_CLOSE, bodyStart);
|
|
66
|
+
const block = blockEnd === -1 ? text.slice(bodyStart) : text.slice(bodyStart, blockEnd);
|
|
67
|
+
cursor = blockEnd === -1 ? text.length : blockEnd + XTML_TOOLS_CLOSE.length;
|
|
68
|
+
let callCursor = 0;
|
|
69
|
+
while (callCursor < block.length) {
|
|
70
|
+
const callStart = block.indexOf(XTML_CALL_OPEN, callCursor);
|
|
71
|
+
if (callStart === -1)
|
|
72
|
+
break;
|
|
73
|
+
const headerEnd = block.indexOf(XTML_SEP, callStart + XTML_CALL_OPEN.length);
|
|
74
|
+
if (headerEnd === -1)
|
|
75
|
+
break;
|
|
76
|
+
const attributes = parseXtmlAttributes(block.slice(callStart + XTML_CALL_OPEN.length, headerEnd));
|
|
77
|
+
const bodyEnd = block.indexOf(XTML_CALL_CLOSE, headerEnd + XTML_SEP.length);
|
|
78
|
+
const callBody = bodyEnd === -1
|
|
79
|
+
? block.slice(headerEnd + XTML_SEP.length)
|
|
80
|
+
: block.slice(headerEnd + XTML_SEP.length, bodyEnd);
|
|
81
|
+
callCursor = bodyEnd === -1 ? block.length : bodyEnd + XTML_CALL_CLOSE.length;
|
|
82
|
+
const name = attributes.tool;
|
|
83
|
+
const tool = name ? tools.find((candidate) => candidate.name === name) : undefined;
|
|
84
|
+
if (!tool) {
|
|
85
|
+
options?.onError?.(`kimi-xtml: call for unknown tool "${name ?? ""}".`, { toolCall: callBody });
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const args = parseCallBody(callBody, tool, options);
|
|
89
|
+
if (args)
|
|
90
|
+
parsed.push({ name: tool.name, arguments: args });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return parsed;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/parse.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,eAAe,GACf,MAAM,cAAc,CAAC;AAItB,MAAM,UAAU,uBAAuB,CAAC,GAAW,EAAE,IAAwB;IAC5E,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ;YACZ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACjC,KAAK,QAAQ,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC3E,CAAC;QACD,KAAK,SAAS;YACb,IAAI,GAAG,KAAK,MAAM;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACrD,IAAI,GAAG,KAAK,OAAO;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACvD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QACtB,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO;YACX,IAAI,CAAC;gBACJ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YACtB,CAAC;QACF;YACC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAClC,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,IAAU,EAAE,OAAuB;IACvE,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,SAAS,CAAC;QACT,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC;YAAE,MAAM;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACpE,IAAI,SAAS,KAAK,CAAC,CAAC;YAAE,MAAM;QAC5B,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACzF,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC;QAC3B,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;QAC/D,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG;YAAE,MAAM;QACnC,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3F,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,OAAO,EAAE,CAAC,0CAA0C,GAAG,cAAc,IAAI,CAAC,IAAI,IAAI,EAAE;gBAC5F,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC;aAC9D,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;QAC1B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,IAAY,EAAE,KAAa,EAAE,OAAuB;IAC9F,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,MAAM;QAC7B,MAAM,SAAS,GAAG,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACxF,MAAM,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC;QAE5E,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,OAAO,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAC5D,IAAI,SAAS,KAAK,CAAC,CAAC;gBAAE,MAAM;YAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7E,IAAI,SAAS,KAAK,CAAC,CAAC;gBAAE,MAAM;YAC5B,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;YAClG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC5E,MAAM,QAAQ,GACb,OAAO,KAAK,CAAC,CAAC;gBACb,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAC1C,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACtD,UAAU,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC;YAE9E,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnF,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,EAAE,OAAO,EAAE,CAAC,qCAAqC,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAChG,SAAS;YACV,CAAC;YACD,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACpD,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC","sourcesContent":["import type { Tool } from \"../../../types.ts\";\nimport type { ParsedToolCall, ParserOptions } from \"../../types.ts\";\nimport {\n\tparseXtmlAttributes,\n\tXTML_ARGUMENT_CLOSE,\n\tXTML_ARGUMENT_OPEN,\n\tXTML_CALL_CLOSE,\n\tXTML_CALL_OPEN,\n\tXTML_SEP,\n\tXTML_TOOLS_CLOSE,\n\tXTML_TOOLS_OPEN,\n} from \"./markers.ts\";\n\ntype CoercedValue = { ok: true; value: unknown } | { ok: false };\n\nexport function coerceXtmlArgumentValue(raw: string, type: string | undefined): CoercedValue {\n\tswitch (type) {\n\t\tcase undefined:\n\t\tcase \"string\":\n\t\t\treturn { ok: true, value: raw };\n\t\tcase \"number\": {\n\t\t\tconst parsed = Number(raw);\n\t\t\treturn Number.isNaN(parsed) ? { ok: false } : { ok: true, value: parsed };\n\t\t}\n\t\tcase \"boolean\":\n\t\t\tif (raw === \"true\") return { ok: true, value: true };\n\t\t\tif (raw === \"false\") return { ok: true, value: false };\n\t\t\treturn { ok: false };\n\t\tcase \"object\":\n\t\tcase \"array\":\n\t\t\ttry {\n\t\t\t\treturn { ok: true, value: JSON.parse(raw) };\n\t\t\t} catch {\n\t\t\t\treturn { ok: false };\n\t\t\t}\n\t\tdefault:\n\t\t\treturn { ok: true, value: raw };\n\t}\n}\n\nfunction parseCallBody(body: string, tool: Tool, options?: ParserOptions): Record<string, unknown> | null {\n\tconst args: Record<string, unknown> = {};\n\tlet rest = body;\n\tfor (;;) {\n\t\trest = rest.replace(/^\\s+/, \"\");\n\t\tif (!rest.startsWith(XTML_ARGUMENT_OPEN)) break;\n\t\tconst headerEnd = rest.indexOf(XTML_SEP, XTML_ARGUMENT_OPEN.length);\n\t\tif (headerEnd === -1) break;\n\t\tconst attributes = parseXtmlAttributes(rest.slice(XTML_ARGUMENT_OPEN.length, headerEnd));\n\t\tconst key = attributes.key;\n\t\tconst valueStart = headerEnd + XTML_SEP.length;\n\t\tconst valueEnd = rest.indexOf(XTML_ARGUMENT_CLOSE, valueStart);\n\t\tif (valueEnd === -1 || !key) break;\n\t\tconst coerced = coerceXtmlArgumentValue(rest.slice(valueStart, valueEnd), attributes.type);\n\t\tif (!coerced.ok) {\n\t\t\toptions?.onError?.(`kimi-xtml: invalid value for argument \"${key}\" on tool \"${tool.name}\".`, {\n\t\t\t\ttoolCall: rest.slice(0, valueEnd + XTML_ARGUMENT_CLOSE.length),\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\targs[key] = coerced.value;\n\t\trest = rest.slice(valueEnd + XTML_ARGUMENT_CLOSE.length);\n\t}\n\treturn args;\n}\n\nexport function parseKimiXtmlGeneratedText(text: string, tools: Tool[], options?: ParserOptions): ParsedToolCall[] {\n\tconst parsed: ParsedToolCall[] = [];\n\tlet cursor = 0;\n\twhile (cursor < text.length) {\n\t\tconst blockStart = text.indexOf(XTML_TOOLS_OPEN, cursor);\n\t\tif (blockStart === -1) break;\n\t\tconst bodyStart = blockStart + XTML_TOOLS_OPEN.length;\n\t\tconst blockEnd = text.indexOf(XTML_TOOLS_CLOSE, bodyStart);\n\t\tconst block = blockEnd === -1 ? text.slice(bodyStart) : text.slice(bodyStart, blockEnd);\n\t\tcursor = blockEnd === -1 ? text.length : blockEnd + XTML_TOOLS_CLOSE.length;\n\n\t\tlet callCursor = 0;\n\t\twhile (callCursor < block.length) {\n\t\t\tconst callStart = block.indexOf(XTML_CALL_OPEN, callCursor);\n\t\t\tif (callStart === -1) break;\n\t\t\tconst headerEnd = block.indexOf(XTML_SEP, callStart + XTML_CALL_OPEN.length);\n\t\t\tif (headerEnd === -1) break;\n\t\t\tconst attributes = parseXtmlAttributes(block.slice(callStart + XTML_CALL_OPEN.length, headerEnd));\n\t\t\tconst bodyEnd = block.indexOf(XTML_CALL_CLOSE, headerEnd + XTML_SEP.length);\n\t\t\tconst callBody =\n\t\t\t\tbodyEnd === -1\n\t\t\t\t\t? block.slice(headerEnd + XTML_SEP.length)\n\t\t\t\t\t: block.slice(headerEnd + XTML_SEP.length, bodyEnd);\n\t\t\tcallCursor = bodyEnd === -1 ? block.length : bodyEnd + XTML_CALL_CLOSE.length;\n\n\t\t\tconst name = attributes.tool;\n\t\t\tconst tool = name ? tools.find((candidate) => candidate.name === name) : undefined;\n\t\t\tif (!tool) {\n\t\t\t\toptions?.onError?.(`kimi-xtml: call for unknown tool \"${name ?? \"\"}\".`, { toolCall: callBody });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst args = parseCallBody(callBody, tool, options);\n\t\t\tif (args) parsed.push({ name: tool.name, arguments: args });\n\t\t}\n\t}\n\treturn parsed;\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Tool } from "../../../types.ts";
|
|
2
|
+
import type { ParserOptions } from "../../types.ts";
|
|
3
|
+
import type { RecoveryStreamParser } from "../anthropic-xml/recovery-stream.ts";
|
|
4
|
+
export declare function createXtmlRecoveryStreamParser(tools: readonly Tool[], options?: ParserOptions): RecoveryStreamParser;
|
|
5
|
+
//# sourceMappingURL=recovery-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-stream.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/kimi-xtml/recovery-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAwChF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAgLpH"}
|