feat(assistant): #91 steps humains en direct + outils web_search/fetch_url (labels backend, SSE step, garde SSRF)
This commit is contained in:
@@ -335,7 +335,7 @@ async function main() {
|
||||
await test("agent tool calls collapse into a discreet steps block", () => {
|
||||
const b = new BooksLM();
|
||||
const trace = b._renderToolActivity([
|
||||
{ name: "read_file", ok: true },
|
||||
{ name: "read_file", ok: true, step: { key: "file_read", params: { value: "a.md" } } },
|
||||
{ name: "search", ok: true },
|
||||
]);
|
||||
assert.equal(trace.tagName, "DETAILS", "collapsible details element");
|
||||
@@ -345,6 +345,18 @@ async function main() {
|
||||
assert.equal(trace.querySelectorAll(".bookslm-tool-line").length, 2, "each step listed inside");
|
||||
});
|
||||
|
||||
await test("_stepText uses the backend label key, falls back to tool name", () => {
|
||||
const b = new BooksLM();
|
||||
// No locales loaded in the JSDOM harness → t() returns the key, so the
|
||||
// fallback path (legacy name) is what surfaces; assert it never throws
|
||||
// and produces a non-empty string for both shapes.
|
||||
const withStep = b._stepText({ name: "read_file", step: { key: "file_read", params: { value: "a.md" } } });
|
||||
const legacy = b._stepText({ name: "read_file" });
|
||||
assert.equal(typeof withStep, "string");
|
||||
assert.equal(typeof legacy, "string");
|
||||
assert.ok(legacy.length > 0);
|
||||
});
|
||||
|
||||
// ── 5. Source guards: no window.prompt() and authenticated BooksLM ──
|
||||
await test("ai.js no longer uses window.prompt()", async () => {
|
||||
const { readFileSync } = await import("node:fs");
|
||||
|
||||
Reference in New Issue
Block a user