feat(agent): align the document tools with the harness-trained shape — ls, read(path), grep(pattern, path?)
This commit is contained in:
@@ -133,14 +133,22 @@ function addThinkingBlock(wrap, thinking) {
|
||||
body.insertBefore(block, body.querySelector(".bubble"));
|
||||
}
|
||||
|
||||
/* Tool-call lines (phase 37) — the local copy of the chat page's
|
||||
* appendToolLine: one visible "calling tool" row per saved
|
||||
* {name, argument} record, in saved order, above the answer. The
|
||||
* path argument goes through textContent, so nothing HTML-shaped can
|
||||
* come from storage. Lines are not interactive (no focus targets).
|
||||
* The two content marks (the read glyph / the list glyph) are the
|
||||
* exact app.js template strings — the frontend emoji guard strips
|
||||
* precisely those two literals in this file, as in app.js. */
|
||||
/* Tool-call lines (phase 37; phase 70 remapped the tool names to the
|
||||
* harness surface ls / read(path) / grep(pattern, path?)) — the local
|
||||
* copy of the chat page's appendToolLine: one visible "calling tool"
|
||||
* row per saved {name, argument} record, in saved order, above the
|
||||
* answer. Every argument (path / pattern / source scope) goes through
|
||||
* textContent, so nothing HTML-shaped can come from storage. Lines
|
||||
* are not interactive (no focus targets). Phase 70: the NEW names
|
||||
* render (read → the Reading line, grep → the Searching-for line,
|
||||
* ls → the Listing-documents line, scoped ls → the
|
||||
* Listing-documents-in-<scope> line), and the pre-phase-70 names
|
||||
* (read_document / search_documents / list_documents) still render
|
||||
* exactly as before — a row saved before the remap keeps its exact
|
||||
* line (no migration). The content marks are the exact app.js
|
||||
* template strings — the frontend emoji guard (tests/integration/
|
||||
* test_api.py) strips precisely those literals in this file, as in
|
||||
* app.js. */
|
||||
function addToolLines(wrap, tools) {
|
||||
if (!Array.isArray(tools) || !tools.length) return;
|
||||
const body = wrap.querySelector(".msg-body");
|
||||
@@ -156,11 +164,25 @@ function addToolLines(wrap, tools) {
|
||||
line.setAttribute("role", "listitem");
|
||||
const argument =
|
||||
typeof t.argument === "string" && t.argument ? t.argument : null;
|
||||
if (t.name === "read_document" && argument) {
|
||||
// Phase 70: new names first, legacy names kept — a conversation
|
||||
// saved before the remap renders byte-identical (no migration).
|
||||
if ((t.name === "read" || t.name === "read_document") && argument) {
|
||||
line.textContent = "📄 Reading ";
|
||||
const code = document.createElement("code");
|
||||
code.textContent = argument; // the path is data, never markup
|
||||
line.appendChild(code);
|
||||
} else if (
|
||||
(t.name === "grep" || t.name === "search_documents") && argument
|
||||
) {
|
||||
line.textContent = "🔎 Searching for ";
|
||||
const code = document.createElement("code");
|
||||
code.textContent = argument; // the pattern is data, never markup
|
||||
line.appendChild(code);
|
||||
} else if (t.name === "ls" && argument) {
|
||||
line.textContent = "🔎 Listing documents in ";
|
||||
const code = document.createElement("code");
|
||||
code.textContent = argument; // the source scope is data, never markup
|
||||
line.appendChild(code);
|
||||
} else {
|
||||
line.textContent = "🔎 Listing documents";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user