Download tests/agent.test.js from ProCreations/minicpm5-2b-webgpu: direct link, hf CLI and curl.
- Browser
- Download file 5.48 kB
-
https://huggingface.co/spaces/ProCreations/minicpm5-2b-webgpu/resolve/main/tests/agent.test.js
- Command line
-
hf download hf://spaces/ProCreations/minicpm5-2b-webgpu/tests/agent.test.js
-
curl -L -o agent.test.js https://huggingface.co/spaces/ProCreations/minicpm5-2b-webgpu/resolve/main/tests/agent.test.js
5.48 kB
| import test from "node:test"; | |
| import assert from "node:assert/strict"; | |
| import { runAgent } from "../src/agent.js"; | |
| import { renderMiniCPMPrompt, normalizedCall } from "../src/prompt.js"; | |
| import { DEFAULTS } from "../src/core.js"; | |
| const call = (args) => ({ | |
| index: 0, | |
| id: "test-call", | |
| function: { name: "create_html", arguments: args }, | |
| }); | |
| const chunk = (delta, finish) => ({ | |
| choices: [{ delta, finish_reason: finish }], | |
| }); | |
| test("an unterminated tool call is reported, repaired with a larger budget, executed and followed up", async () => { | |
| const history = [{ role: "user", content: "Create a black hole in HTML" }]; | |
| let requests = 0, | |
| created = 0; | |
| async function chat(messages, settings, tools, signal, emit) { | |
| requests++; | |
| if (requests === 1) { | |
| await emit( | |
| chunk( | |
| { tool_calls: [call('{"title":"Black hole","html":"<html>')] }, | |
| "length", | |
| ), | |
| ); | |
| return; | |
| } | |
| assert.doesNotThrow(() => renderMiniCPMPrompt(messages, { tools: [] })); | |
| for (const m of messages) | |
| for (const c of m.tool_calls || []) | |
| assert.doesNotThrow(() => JSON.parse(c.function.arguments)); | |
| if (requests === 2) { | |
| assert.ok(settings.maxTokens >= 8192); | |
| assert.equal(settings.thinking, false); | |
| assert.match(messages.at(-1).content, /cut off/); | |
| await emit( | |
| chunk( | |
| { | |
| tool_calls: [ | |
| call( | |
| JSON.stringify({ | |
| title: "Black hole", | |
| html: "<!doctype html><h1>Black hole</h1>", | |
| }), | |
| ), | |
| ], | |
| }, | |
| "tool_calls", | |
| ), | |
| ); | |
| return; | |
| } | |
| assert.equal(JSON.parse(messages.at(-1).content).success, true); | |
| await emit(chunk({ content: "Your black hole is ready." }, "stop")); | |
| } | |
| const events = []; | |
| await runAgent({ | |
| chat, | |
| history, | |
| settings: { ...DEFAULTS, maxTokens: 1536, thinking: true }, | |
| signal: new AbortController().signal, | |
| createArtifact: async (name, args) => { | |
| created++; | |
| assert.ok(args.html.includes("<h1>")); | |
| return { id: "file", filename: "Black-hole.html" }; | |
| }, | |
| onEvent: (event) => events.push(event), | |
| }); | |
| assert.equal(requests, 3); | |
| assert.equal(created, 1); | |
| assert.equal(events.find((e) => e.type === "tool-success").recovered, true); | |
| assert.equal(events.at(-1).type, "done"); | |
| }); | |
| test("tool validation errors are fed back and do not terminate the turn", async () => { | |
| let requests = 0, | |
| attempts = 0; | |
| const history = [{ role: "user", content: "Make a file" }]; | |
| async function chat(messages, settings, tools, signal, emit) { | |
| requests++; | |
| if (requests < 3) { | |
| if (requests === 2) assert.match(messages.at(-1).content, /closing tag/); | |
| await emit( | |
| chunk( | |
| { | |
| tool_calls: [ | |
| call( | |
| JSON.stringify({ | |
| title: "Page", | |
| html: | |
| requests === 1 | |
| ? '</span id="x">' | |
| : '<span id="x">Fixed</span>', | |
| }), | |
| ), | |
| ], | |
| }, | |
| "stop", | |
| ), | |
| ); | |
| } else await emit(chunk({ content: "Done" }, "stop")); | |
| } | |
| await runAgent({ | |
| chat, | |
| history, | |
| settings: DEFAULTS, | |
| signal: new AbortController().signal, | |
| createArtifact: async (_, args) => { | |
| attempts++; | |
| if (args.html.startsWith("</")) throw Error("Invalid closing tag"); | |
| return { id: "file", filename: "Page.html" }; | |
| }, | |
| }); | |
| assert.equal(requests, 3); | |
| assert.equal(attempts, 2); | |
| }); | |
| test("tool history serializes structured values once", () => { | |
| const c = { | |
| id: "x", | |
| function: { | |
| name: "create_spreadsheet", | |
| arguments: JSON.stringify({ sheets: [{ rows: [[1, true, null]] }] }), | |
| }, | |
| }; | |
| const prompt = renderMiniCPMPrompt([ | |
| { role: "user", content: "Make a sheet" }, | |
| { role: "assistant", content: "", tool_calls: [c] }, | |
| { role: "tool", content: "success" }, | |
| ]); | |
| assert.equal(prompt.match(/<function name=/g).length, 1); | |
| assert.ok(prompt.includes('[{"rows":[[1,true,null]]}]')); | |
| assert.ok(prompt.includes("<tool_response>\nsuccess")); | |
| }); | |
| test("malformed older history remains representable", () => { | |
| const c = normalizedCall({ | |
| function: { name: "create_html", arguments: '{"html":"unfinished' }, | |
| }); | |
| assert.equal( | |
| JSON.parse(c.function.arguments).invalid_arguments, | |
| '{"html":"unfinished', | |
| ); | |
| }); | |
| test("consumer errors propagate and cancellation stops callback streaming", async () => { | |
| const controller = new AbortController(); | |
| let delivered = 0; | |
| const chat = async (m, s, t, signal, emit) => { | |
| for (let i = 0; i < 10000; i++) { | |
| signal.throwIfAborted(); | |
| await emit(chunk({ content: "x" }, null)); | |
| } | |
| }; | |
| await assert.rejects( | |
| runAgent({ | |
| chat, | |
| history: [], | |
| settings: DEFAULTS, | |
| signal: controller.signal, | |
| createArtifact: () => {}, | |
| onEvent: (e) => { | |
| if (e.type === "chunk" && ++delivered === 500) controller.abort(); | |
| }, | |
| }), | |
| { name: "AbortError" }, | |
| ); | |
| assert.equal(delivered, 500); | |
| await assert.rejects( | |
| runAgent({ | |
| chat, | |
| history: [], | |
| settings: DEFAULTS, | |
| signal: new AbortController().signal, | |
| createArtifact: () => {}, | |
| onEvent: (e) => { | |
| if (e.type === "chunk") throw Error("consumer failed"); | |
| }, | |
| }), | |
| /consumer failed/, | |
| ); | |
| }); | |