Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/agent/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function buildHarnessFacts(
"- Shell file-writes and deletions are blocked; never use echo/heredoc/sed/rm as a substitute for product tools. Path tools are the DIY surface.",
]),
"- Use the provided tools for file reads/searches instead of shelling out as a substitute.",
"- read_file accepts a filesystem path or a tool-output:///{callId} URI from a prior tool result when the harness exposes one; prefer the URI over re-reading huge blobs.",
"- read_file accepts a filesystem path or a tool-output:///{callId} URI from a prior tool result when the harness exposes one. Only read_file a tool-output:// URI if the truncation notice on that result named one; do not re-read a complete inline result.",
"- run_shell has no default timeout; pass timeout for builds, tests, and other long commands. Prefer background:true for builds, test suites, and dev servers: it returns a shell_id at once, the result is delivered when the process finishes (foreground runs hold steers; background runs do not), and shell_collect collects or cancels later. background does not change the retained shell cwd.",
"- Shell find, rg, and grep -r are blocked — they can walk huge trees and OOM the host. Prefer the bounded grep/search_files tools, and do not substitute another unbounded walk (fd, ls -R, scripted os.walk).",
...(subAgent
Expand Down Expand Up @@ -226,7 +226,7 @@ export function buildPromptDisciplineBlock(

const TOOL_SUMMARIES: Record<string, string> = {
read_file:
"read a file or tool-output:///{callId} from a prior tool result (prefer over cat/head/tail in the shell)",
"read a file or tool-output:///{callId} from a prior tool result (prefer over cat/head/tail in the shell). Only read_file a tool-output:// URI if the truncation notice named one",
write_file: "create or overwrite a file (never shell redirects or heredocs)",
edit_file:
"make a surgical edit (exact old_string match, or start_line/end_line line-range mode; never include read_file's NNNNNN\\t line prefix; substring failures include nearby file text; prefer over sed/awk in the shell)",
Expand Down
20 changes: 20 additions & 0 deletions src/prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ test("harness facts state only the non-derivable tool and safety rules", () => {
expect(facts).not.toContain("Tool results already render richly");
});

test("harness facts gate tool-output URI reads on a named truncation notice", () => {
const facts = buildHarnessFacts();
expect(facts).toContain("read_file");
expect(facts).toMatch(/filesystem path/i);
expect(facts).toMatch(/tool-output:\/\//);
expect(facts).toContain("truncation notice on that result named one");
expect(facts).toContain("do not re-read a complete inline result");
expect(facts).not.toMatch(/prefer the URI/i);
expect(facts).not.toMatch(/re-reading huge blobs/i);
});

test("read_file catalog summary gates tool-output URI reads on truncation", () => {
const listed = buildAvailableTools(["read_file"]);
expect(listed).toContain("read_file");
expect(listed).toMatch(/tool-output:\/\//);
expect(listed).toContain("truncation notice named one");
expect(listed).toContain("cat/head/tail");
expect(listed).not.toMatch(/prefer the URI/i);
});

test("harness facts name skill_search as a resident catalog tool", () => {
const facts = buildHarnessFacts();
expect(facts).toMatch(
Expand Down
Loading