mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-28 01:21:36 +00:00
fix(Gateway ): strip tool_call and tool_result XML blocks from assistant visible text
This commit is contained in:
committed by
Peter Steinberger
parent
f00c8c1b87
commit
980439b9e6
@@ -116,6 +116,31 @@ describe("stripAssistantInternalScaffolding", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("strips closed <tool_result> blocks", () => {
|
||||
expectVisibleText(
|
||||
'Prefix\n<tool_result> {"output": "file contents"} </tool_result>\nSuffix',
|
||||
"Prefix\n\nSuffix",
|
||||
);
|
||||
});
|
||||
|
||||
it("strips dangling <tool_result> content to end-of-string", () => {
|
||||
expectVisibleText('Result:\n<tool_result>\n{"output": "data"}\n', "Result:\n");
|
||||
});
|
||||
|
||||
it("strips <tool_result> closed with mismatched </tool_call> and preserves trailing text", () => {
|
||||
expectVisibleText(
|
||||
'Prefix\n<tool_result> {"output": "data"} </tool_call>\nSuffix',
|
||||
"Prefix\n\nSuffix",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not let </tool_result> close a <tool_call> block", () => {
|
||||
expectVisibleText(
|
||||
'Prefix\n<tool_call>{"name":"x"}</tool_result>LEAK</tool_call>\nSuffix',
|
||||
"Prefix\n\nSuffix",
|
||||
);
|
||||
});
|
||||
|
||||
it("hides dangling <tool_call> content to end-of-string", () => {
|
||||
expectVisibleText(
|
||||
'Let me run.\n<tool_call>\n{"name": "find", "arguments": {}}\n',
|
||||
|
||||
@@ -10,8 +10,14 @@ const MEMORY_TAG_QUICK_RE = /<\s*\/?\s*relevant[-_]memories\b/i;
|
||||
* This stateful pass hides content from an opening tag through the matching
|
||||
* closing tag, or to end-of-string if the stream was truncated mid-tag.
|
||||
*/
|
||||
const TOOL_CALL_QUICK_RE = /<\s*\/?\s*(?:tool_call|function_calls?|tool_calls)\b/i;
|
||||
const TOOL_CALL_TAG_NAMES = new Set(["tool_call", "function_call", "function_calls", "tool_calls"]);
|
||||
const TOOL_CALL_QUICK_RE = /<\s*\/?\s*(?:tool_call|tool_result|function_calls?|tool_calls)\b/i;
|
||||
const TOOL_CALL_TAG_NAMES = new Set([
|
||||
"tool_call",
|
||||
"tool_result",
|
||||
"function_call",
|
||||
"function_calls",
|
||||
"tool_calls",
|
||||
]);
|
||||
const TOOL_CALL_JSON_PAYLOAD_START_RE =
|
||||
/^(?:\s+[A-Za-z_:][-A-Za-z0-9_:.]*\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))*\s*(?:\r?\n\s*)?[[{]/;
|
||||
|
||||
@@ -151,7 +157,7 @@ function parseToolCallTagAt(text: string, start: number): ParsedToolCallTag | nu
|
||||
};
|
||||
}
|
||||
|
||||
function stripToolCallXmlTags(text: string): string {
|
||||
export function stripToolCallXmlTags(text: string): string {
|
||||
if (!text || !TOOL_CALL_QUICK_RE.test(text)) {
|
||||
return text;
|
||||
}
|
||||
@@ -224,7 +230,8 @@ function stripToolCallXmlTags(text: string): string {
|
||||
}
|
||||
} else if (
|
||||
tag.isClose &&
|
||||
tag.tagName === toolCallBlockTagName &&
|
||||
(tag.tagName === toolCallBlockTagName ||
|
||||
(toolCallBlockTagName === "tool_result" && tag.tagName === "tool_call")) &&
|
||||
!endsInsideQuotedString(text, toolCallContentStart, idx)
|
||||
) {
|
||||
inToolCallBlock = false;
|
||||
|
||||
Reference in New Issue
Block a user