fix: 修复文本解析兜底正则不匹配模型实际输出格式
模型实际输出格式:
Action: write_file
Action Input: {"path": "测试.md", "content": ""}
原正则用 [\r\n]+ 强制要求换行,且 Action: 后的冒号和
Action Input: 的冒号处理冲突导致匹配失败。
改为 [\r\n\s]* 灵活匹配空白/换行。
This commit is contained in:
@@ -104,10 +104,13 @@ const VALID_TOOL_NAMES = new Set([
|
|||||||
function parseToolCallsFromText(content: string): ToolCall[] {
|
function parseToolCallsFromText(content: string): ToolCall[] {
|
||||||
const calls: ToolCall[] = [];
|
const calls: ToolCall[] = [];
|
||||||
|
|
||||||
// 匹配模式1: **Action:** tool_name **Action Input:** {json}
|
// 匹配:Action: tool_name(可选加粗标记)
|
||||||
// 匹配模式2: Action: tool_name Action Input: {json}
|
// 然后紧跟 Action Input: {json}
|
||||||
// 同时支持 Action 和 Action Input 写在同一段或多行
|
// 支持格式:
|
||||||
const actionRegex = /\*?\*?Action:?\*?\*?\s*([\w]+)\s*[\r\n]+\s*\*?\*?Action\s*Input:?\*?\*?\s*(\{[\s\S]*?\})/gi;
|
// Action: write_file Action: write_file
|
||||||
|
// Action Input: {...} **Action Input:** {...}
|
||||||
|
// 也支持写在同一段落的情况
|
||||||
|
const actionRegex = /\*{0,2}Action:?\*{0,2}\s*(\w+)\s+[\r\n\s]*\*{0,2}Action\s*Input:?\*{0,2}\s*(\{[\s\S]*?\})/gi;
|
||||||
|
|
||||||
let match;
|
let match;
|
||||||
while ((match = actionRegex.exec(content)) !== null) {
|
while ((match = actionRegex.exec(content)) !== null) {
|
||||||
@@ -127,7 +130,6 @@ function parseToolCallsFromText(content: string): ToolCall[] {
|
|||||||
} catch {
|
} catch {
|
||||||
// JSON 解析失败,尝试修复常见问题
|
// JSON 解析失败,尝试修复常见问题
|
||||||
try {
|
try {
|
||||||
// 处理单引号、尾逗号等
|
|
||||||
let fixed = argsStr
|
let fixed = argsStr
|
||||||
.replace(/'/g, '"')
|
.replace(/'/g, '"')
|
||||||
.replace(/,\s*}/g, '}')
|
.replace(/,\s*}/g, '}')
|
||||||
@@ -146,23 +148,6 @@ function parseToolCallsFromText(content: string): ToolCall[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 备选模式:Action 和 Action Input 写在一行或用不同分隔
|
|
||||||
if (calls.length === 0) {
|
|
||||||
const singleLineRegex = /Action:\s*(\w+)\s*.*?Action\s*Input:\s*(\{[^}]+\})/gi;
|
|
||||||
while ((match = singleLineRegex.exec(content)) !== null) {
|
|
||||||
const toolName = match[1].trim();
|
|
||||||
const argsStr = match[2].trim();
|
|
||||||
if (!VALID_TOOL_NAMES.has(toolName)) continue;
|
|
||||||
try {
|
|
||||||
const args = JSON.parse(argsStr);
|
|
||||||
calls.push({
|
|
||||||
type: 'function',
|
|
||||||
function: { name: toolName, arguments: args }
|
|
||||||
});
|
|
||||||
} catch { /* skip */ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (calls.length > 0) {
|
if (calls.length > 0) {
|
||||||
logInfo(`文本解析兜底: 从回复中提取到 ${calls.length} 个工具调用`, calls.map(c => c.function.name).join(', '));
|
logInfo(`文本解析兜底: 从回复中提取到 ${calls.length} 个工具调用`, calls.map(c => c.function.name).join(', '));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user