feat(webui): polish agent output and app discovery
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { describeTraceLine } from "@/components/thread/activity/trace-activity-model";
|
||||
import type { GenericToolStatus } from "@/components/thread/activity/generic-tool-model";
|
||||
|
||||
function describeTrace(line: string, status: GenericToolStatus = "done") {
|
||||
return describeTraceLine(line, status);
|
||||
}
|
||||
|
||||
describe("trace activity semantics", () => {
|
||||
it.each([
|
||||
['web_search({"query":"nanobot latest release"})', "done", "Searched nanobot latest release", ""],
|
||||
['web_fetch({"url":"https://example.com/docs?token=private"})', "done", "Read", "example.com/docs"],
|
||||
['read_file({"path":"/Users/alice/project/README.md"})', "done", "Read", "~/project/README.md"],
|
||||
['exec({"command":"date +%Y-%m-%d"})', "done", "Checked current time", ""],
|
||||
['exec_command({"cmd":"API_KEY=secret npm test"})', "running", "Running command", "API_KEY=•••• npm test"],
|
||||
['write_file({"path":"/home/alice/project/output.txt"})', "done", "Wrote file", "~/project/output.txt"],
|
||||
['apply_patch({"file_path":"src/app.tsx","patch":"private"})', "error", "Could not edit file", "src/app.tsx"],
|
||||
['third_party_sync({"token":"secret","payload":"private"})', "done", "Completed Third party sync", ""],
|
||||
["Finished collecting results", "done", "Completed step", "Finished collecting results"],
|
||||
] as const)("describes %s as one safe activity line", (line, status, label, detail) => {
|
||||
const result = describeTrace(line, status);
|
||||
expect(result).toMatchObject({ label, detail });
|
||||
expect(`${result.label} ${result.detail}`).not.toMatch(/[{}]|private|\/Users\/alice|\/home\/alice/);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["running", "Searching status test"],
|
||||
["done", "Searched status test"],
|
||||
["error", "Could not search status test"],
|
||||
] as const)("uses status-aware search copy for %s", (status, label) => {
|
||||
expect(describeTrace('web_search({"query":"status test"})', status).label).toBe(label);
|
||||
});
|
||||
|
||||
it("never exposes URL credentials, query secrets, or private-network links", () => {
|
||||
const publicResult = describeTrace(
|
||||
'web_fetch({"url":"https://user:password@example.com/docs?api_key=secret#section"})',
|
||||
);
|
||||
expect(publicResult).toMatchObject({ detail: "example.com/docs", host: "example.com" });
|
||||
expect(JSON.stringify(publicResult)).not.toMatch(/password|api_key|secret/);
|
||||
|
||||
const privateResult = describeTrace('web_fetch({"url":"http://127.0.0.1:8765/private"})');
|
||||
expect(privateResult.url).toBeUndefined();
|
||||
expect(privateResult.detail).not.toContain("127.0.0.1");
|
||||
});
|
||||
|
||||
it("summarizes multi-line commands without exposing every script line", () => {
|
||||
const result = describeTrace(
|
||||
'exec({"command":"npm test\\necho second-secret-line\\necho third-line"})',
|
||||
);
|
||||
expect(result).toMatchObject({
|
||||
label: "Ran command",
|
||||
detail: "npm test · script, 3 lines",
|
||||
});
|
||||
expect(result.detail).not.toContain("second-secret-line");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user