mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
fix(stream): suppress compact malformed tool calls
This commit is contained in:
@@ -241,6 +241,11 @@ function containsTextualToolCallCandidate(text: unknown): boolean {
|
||||
return parseTextualToolCallCandidate(text) !== null;
|
||||
}
|
||||
|
||||
function containsMalformedTextualToolCall(text: unknown): boolean {
|
||||
if (typeof text !== "string") return false;
|
||||
return text.replace(/[\u200B-\u200D\uFEFF]/g, "").includes("[Tool call:");
|
||||
}
|
||||
|
||||
function collectPassthroughTextualToolCall(
|
||||
text: string,
|
||||
toolCalls: Map<string, ToolCall>
|
||||
@@ -1746,6 +1751,8 @@ export function createSSEStream(options: StreamOptions = {}) {
|
||||
if (content && collectPassthroughTextualToolCall(content, passthroughToolCalls)) {
|
||||
passthroughHasToolCalls = true;
|
||||
content = "";
|
||||
} else if (containsMalformedTextualToolCall(content)) {
|
||||
content = "";
|
||||
}
|
||||
const message: Record<string, unknown> = {
|
||||
role: "assistant",
|
||||
@@ -1987,6 +1994,8 @@ export function createSSEStream(options: StreamOptions = {}) {
|
||||
},
|
||||
});
|
||||
content = "";
|
||||
} else if (containsMalformedTextualToolCall(content)) {
|
||||
content = "";
|
||||
}
|
||||
const message: Record<string, unknown> = {
|
||||
role: "assistant",
|
||||
|
||||
@@ -267,6 +267,46 @@ test("createSSEStream passthrough suppresses malformed textual tool-call content
|
||||
assert.doesNotMatch(JSON.stringify(onCompletePayload.responseBody), /\[Tool call: terminal\]/);
|
||||
});
|
||||
|
||||
test("createSSEStream suppresses malformed compact textual tool-call content", async () => {
|
||||
let onCompletePayload = null;
|
||||
|
||||
const text = await readTransformed(
|
||||
[
|
||||
`data: ${JSON.stringify({
|
||||
candidates: [
|
||||
{
|
||||
content: {
|
||||
parts: [
|
||||
{
|
||||
text: "[Tool call: search_files_ide{file_glob:*combos*.ts,path:/opt/OmniRoute,target:files}]",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
})}\n\n`,
|
||||
`data: ${JSON.stringify({ candidates: [{ finishReason: "STOP" }] })}\n\n`,
|
||||
],
|
||||
{
|
||||
mode: "translate",
|
||||
targetFormat: FORMATS.ANTIGRAVITY,
|
||||
sourceFormat: FORMATS.OPENAI,
|
||||
provider: "antigravity",
|
||||
model: "antigravity/gemini-3.5-flash-low",
|
||||
body: { messages: [{ role: "user", content: "inspect files" }] },
|
||||
onComplete(payload) {
|
||||
onCompletePayload = payload;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const choice = onCompletePayload.responseBody.choices[0];
|
||||
assert.equal(choice.finish_reason, "stop");
|
||||
assert.equal(choice.message.content, null);
|
||||
assert.equal(choice.message.tool_calls, undefined);
|
||||
assert.doesNotMatch(JSON.stringify(onCompletePayload.responseBody), /\[Tool call:/);
|
||||
});
|
||||
|
||||
test("createSSEStream passthrough flushes a buffered final line without a trailing newline", async () => {
|
||||
const text = await readTransformed(
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user