miniai/test_stream_tool.ts

46 lines
2.0 KiB
TypeScript

const BASE_URL = "https://ark.cn-beijing.volces.com/api/coding/v3";
const API_KEY = process.env.ARK_KEY;
const MODEL = "ark-code-latest";
const tools = [
{ type: "function", function: { name: "read_excel", description: "读取 Excel 前5行", parameters: { type: "object", properties: { path: { type: "string" }, sheet: { type: "string" }, limit: { type: "number" } }, required: ["path"] } } },
{ type: "function", function: { name: "list_directory", description: "列出目录", parameters: { type: "object", properties: { path: { type: "string" } } } } },
];
const body = {
messages: [{ role: "system", content: "请用 list_directory 查看 D:/workbench/miniai 目录,然后用 read_excel 读取其中的 data.xlsx 前3行。" }, { role: "user", content: "开始" }],
tools, tool_choice: "auto", stream: true, model: MODEL,
};
const resp = await fetch(BASE_URL.replace(/\/$/, "") + "/chat/completions", {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify(body),
});
console.log("status:", resp.status);
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let n = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
const t = line.trim();
if (!t.startsWith("data:")) continue;
const data = t.slice(5).trim();
if (data === "[DONE]") continue;
let j; try { j = JSON.parse(data); } catch { continue; }
const delta = j.choices?.[0]?.delta || {};
if (delta.tool_calls) {
for (const tc of delta.tool_calls) {
console.log(JSON.stringify({ index: tc.index, id: tc.id ?? null, name: tc.function?.name ?? "", args: tc.function?.arguments ?? "" }));
}
} else if (delta.content) {
console.log("content:", JSON.stringify(delta.content));
}
if (++n > 200) break;
}
if (n > 200) break;
}
console.log("--- end ---");