113 lines
4.2 KiB
JavaScript
113 lines
4.2 KiB
JavaScript
const test = require("node:test");
|
||
const assert = require("node:assert/strict");
|
||
|
||
const { responsesToChat } = require("../electron/lib/translate");
|
||
|
||
test("chat projection keeps completed custom tool results without forwarding tool protocol", () => {
|
||
const result = responsesToChat({
|
||
model: "codex-model",
|
||
stream: true,
|
||
tool_choice: "auto",
|
||
input: [
|
||
{ type: "additional_tools", role: "system", tools: [{ name: "exec_command" }] },
|
||
{ type: "message", role: "user", content: [{ type: "input_text", text: "识别这张图" }] },
|
||
{ type: "custom_tool_call", call_id: "call_1", name: "exec_command", input: "tesseract image.png" },
|
||
{ type: "custom_tool_call_output", call_id: "call_1", output: [{ type: "text", text: "识别结果:设置" }] },
|
||
{
|
||
type: "message",
|
||
role: "user",
|
||
content: [
|
||
{ type: "input_image", image_url: "data:image/png;base64,abc" },
|
||
{ type: "input_text", text: "[TD 多模态识别证据] 设置页面" },
|
||
],
|
||
},
|
||
],
|
||
}, "deepseek-chat");
|
||
|
||
assert.equal(result.model, "deepseek-chat");
|
||
assert.equal(result.tools, undefined);
|
||
assert.equal(result.tool_choice, undefined);
|
||
assert.match(result.messages[0].content, /不能调用本地工具/);
|
||
assert.ok(result.messages.some((message) => /工具:exec_command/.test(message.content)));
|
||
assert.ok(result.messages.some((message) => /识别结果:设置/.test(message.content)));
|
||
assert.ok(result.messages.some((message) => /TD 多模态识别证据/.test(message.content)));
|
||
assert.ok(result.messages.every((message) => message.role !== "tool" && !message.tool_calls));
|
||
});
|
||
|
||
test("chat projection forwards native tools only when they are supplied", () => {
|
||
const withoutTools = responsesToChat({ model: "model", tool_choice: "auto", input: "你好" });
|
||
assert.equal(withoutTools.tool_choice, undefined);
|
||
|
||
const withTools = responsesToChat({
|
||
model: "model",
|
||
tool_choice: "auto",
|
||
tools: [{ type: "function", name: "lookup", parameters: { type: "object" } }],
|
||
input: "你好",
|
||
});
|
||
assert.equal(withTools.tool_choice, "auto");
|
||
assert.equal(withTools.tools[0].function.name, "lookup");
|
||
});
|
||
|
||
test("chat projection forwards Codex additional_tools so coding agents can execute", () => {
|
||
const result = responsesToChat({
|
||
model: "deepseek-chat",
|
||
tool_choice: "auto",
|
||
input: [
|
||
{
|
||
type: "additional_tools",
|
||
role: "developer",
|
||
tools: [{
|
||
type: "function",
|
||
name: "exec_command",
|
||
description: "Run a shell command",
|
||
parameters: {
|
||
type: "object",
|
||
properties: { cmd: { type: "string" } },
|
||
required: ["cmd"],
|
||
},
|
||
}],
|
||
},
|
||
{ type: "message", role: "user", content: "发布热更" },
|
||
],
|
||
});
|
||
|
||
assert.equal(result.tool_choice, "auto");
|
||
assert.equal(result.tools.length, 1);
|
||
assert.equal(result.tools[0].function.name, "exec_command");
|
||
assert.doesNotMatch(result.messages[0].content, /不能调用本地工具/);
|
||
});
|
||
|
||
test("multimodal chat projection removes image reading but keeps coding tools", () => {
|
||
const result = responsesToChat({
|
||
model: "model",
|
||
tool_choice: "auto",
|
||
tools: [
|
||
{ type: "function", name: "exec_command", parameters: { type: "object" } },
|
||
{ type: "function", name: "view_image", parameters: { type: "object" } },
|
||
{ type: "web_search_preview" },
|
||
],
|
||
input: "识别图片",
|
||
}, undefined, { omitVisualTools: true });
|
||
|
||
assert.equal(result.tool_choice, "auto");
|
||
assert.deepEqual(result.tools.map((tool) => tool.function.name), ["exec_command"]);
|
||
});
|
||
|
||
test("chat projection never forwards media Base64 from tool messages", () => {
|
||
const image = "data:image/png;base64," + "A".repeat(2 * 1024 * 1024);
|
||
const result = responsesToChat({
|
||
model: "deepseek-chat",
|
||
input: [{
|
||
type: "message",
|
||
role: "tool",
|
||
content: [{ type: "input_image", image_url: image }],
|
||
}],
|
||
});
|
||
|
||
const content = result.messages.map((message) => String(message.content || "")).join("\n");
|
||
assert.match(content, /图像二进制已省略/);
|
||
assert.doesNotMatch(content, /data:image/);
|
||
assert.ok(result.messages.every((message) => message.role !== "tool"));
|
||
assert.ok(content.length < 1000);
|
||
});
|