mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-06 15:22:12 +03:00
fix(tests): align deepseek-web-tools-execute with #9343 tool envelope contract
tests/unit/deepseek-web-tools-execute-2820.test.ts (executor level) was a
test-sibling forgotten when #9343 (commit d969555417) hardened tool-call
parsing: bare JSON with no explicit <tool>/<tool_call> envelope is never
promoted to tool_calls anymore (previously it was, whenever a tools[] set
was requested — a security gap allowing prose/code-fenced JSON echoed
back by the model, or a copy-attack, to trigger real tool execution).
Three siblings were updated in the same commit: web-tools-translation.test.ts
and web-tools-translation-2820.test.ts (parseToolCallsFromText, the shared
translator), and deepseek-web-tools-variants.test.ts (parseDeepSeekToolCalls,
deepseek-specific parser) — all inverted their bare-JSON assertions to
`toolCalls === null` + `content === text` (preserved verbatim, not stripped).
This file calls the executor's execute() (full HTTP round trip through
buildToolAwareResult), so it was not touched by that diff and kept
asserting the old contract (finish_reason: "tool_calls", content: null).
Verified against source (open-sse/executors/deepseek-web.ts
buildToolAwareResult): when parseDeepSeekToolCalls returns toolCalls=null,
hasCalls is false, so finish_reason is "stop", message.tool_calls is never
set, and message.content is the parser's returned content — which for text
with no <tool>/<tool_call> tag at all is the original string, unchanged
(parseToolCallsFromText's early-return branch). The test now asserts
exactly that shape, at the same executor level as the rest of the file's
tool_calls that make sense at that level as the rest of the file's tool_calls
Refs #9343
This commit is contained in:
@@ -132,7 +132,9 @@ test("execute (non-stream) parses <tool> reply into OpenAI tool_calls", async ()
|
||||
assert.equal(choice.finish_reason, "tool_calls");
|
||||
assert.equal(choice.message.tool_calls.length, 1);
|
||||
assert.equal(choice.message.tool_calls[0].function.name, "get_weather");
|
||||
assert.deepEqual(JSON.parse(choice.message.tool_calls[0].function.arguments), { city: "Paris" });
|
||||
assert.deepEqual(JSON.parse(choice.message.tool_calls[0].function.arguments), {
|
||||
city: "Paris",
|
||||
});
|
||||
assert.ok(
|
||||
!String(choice.message.content || "").includes("<tool>"),
|
||||
"raw tool block stripped from content"
|
||||
@@ -142,8 +144,9 @@ test("execute (non-stream) parses <tool> reply into OpenAI tool_calls", async ()
|
||||
}
|
||||
});
|
||||
|
||||
test("execute (non-stream) parses bare JSON reply into OpenAI tool_calls", async () => {
|
||||
const mock = installMock('{"name":"getWeather","arguments":{"city":"Paris"}}');
|
||||
test("execute (non-stream) does NOT promote bare JSON reply to tool_calls (#9343)", async () => {
|
||||
const bareJson = '{"name":"getWeather","arguments":{"city":"Paris"}}';
|
||||
const mock = installMock(bareJson);
|
||||
try {
|
||||
const executor = new DeepSeekWebExecutor();
|
||||
const result = await executor.execute({
|
||||
@@ -156,11 +159,17 @@ test("execute (non-stream) parses bare JSON reply into OpenAI tool_calls", async
|
||||
assert.ok(result.response.ok);
|
||||
const json = JSON.parse(await result.response.text());
|
||||
const choice = json.choices[0];
|
||||
assert.equal(choice.finish_reason, "tool_calls");
|
||||
assert.equal(choice.message.tool_calls.length, 1);
|
||||
assert.equal(choice.message.tool_calls[0].function.name, "get_weather");
|
||||
assert.deepEqual(JSON.parse(choice.message.tool_calls[0].function.arguments), { city: "Paris" });
|
||||
assert.equal(choice.message.content, null, "bare JSON tool call is stripped from content");
|
||||
assert.equal(
|
||||
choice.finish_reason,
|
||||
"stop",
|
||||
"bare JSON with no <tool> envelope must not be promoted to a tool call"
|
||||
);
|
||||
assert.ok(!choice.message.tool_calls, "no tool_calls on a bare JSON reply (#9343)");
|
||||
assert.equal(
|
||||
choice.message.content,
|
||||
bareJson,
|
||||
"bare JSON must be preserved verbatim as content, not stripped or promoted"
|
||||
);
|
||||
} finally {
|
||||
mock.restore();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user