Repository navigation
fix(agent-runtime): stop global AGENTS.md from starving project instructions - #1495
Conversation
…uctions The global ~/.pi/agent/AGENTS.md and the project chain shared one 32 KiB budget. The global file was read first, so a global file of 32 KiB or more used the whole budget and every project AGENTS.md/CLAUDE.md was dropped. The cut itself was silent: no marker told the model the file was incomplete. Give the global file and the project chain independent 32 KiB budgets, the same split Codex uses (its global AGENTS.md is outside the 32 KiB project_doc_max_bytes budget). When a file is cut, keep whole UTF-8 characters and append a notice naming the source and the loaded/total byte counts. Project files after a truncated one are not loaded, as before. Update ADR 0037, the agent-runtime spec, and E2E-AGENTS-001 (with their zh-CN copies) to describe the new budgets. Fixes vastsa#1490
…/review-pr1495-latest-base
|
Thanks for the thorough root-cause fix and regression coverage. I merged this after refreshing the branch onto the latest main; the updated CI, docs, Rust, and Electron E2E checks all passed. The separate instruction budgets and visible UTF-8-safe truncation notice address the reported failure directly. |
muzimu217
left a comment
There was a problem hiding this comment.
Verified locally on macOS (worktree off current main): project-instructions tests 16/16, full agent-runtime suite 94 files / 1300 tests pass.
The design is the right decomposition of #1490's two complaints:
- Independent budgets —
MAX_GLOBAL_INSTRUCTION_BYTESandMAX_PROJECT_INSTRUCTION_BYTES(32 KiB each), so an oversized~/.pi/agent/AGENTS.mdcan never starve projectAGENTS.md/CLAUDE.mdagain.loadInstructionChainno longer subtracts the global file from the project budget, and the only external caller (launch-resolver.ts) consumes entries without assuming the old combined cap — I checked for other 32 KiB combined-budget assumptions and found none. - Truncation is never silent —
limitInstructionappends a notice naming the source and the loaded/total byte counts ([PI-Desktop truncated <source>: loaded the first <n> of <total> bytes; ...]), cut on a UTF-8 character boundary, withtrimEndbefore the notice so the marker reads cleanly. - The chain break after a truncated file is explicit rather than implicit budget exhaustion, and the ADR 0037 amendment justifies the 64 KiB instruction-section ceiling with the Codex precedent (global
AGENTS.mdoutsideproject_doc_max_bytes) — a good external anchor for the budget split.
Tests cover the four interesting shapes: UTF-8 boundary + exact notice text, budget exhaustion stopping later project files, both-full independent budgets, and oversized-global-with-project-present. Spec + e2e plan updated in both languages, ADR amended with an Updated: line.
Nothing blocking.
Fixes #1490
Problem
~/.pi/agent/AGENTS.mdand the project instruction chain shared one 32 KiB budget inproject-instructions.ts. The global file was read first, so a global file of 32 KiB or more:AGENTS.md/CLAUDE.mdwas dropped (loadProjectInstructionsbroke out of its loop at once).Change
[PI-Desktop truncated <source>: loaded the first <n> of <total> bytes; the rest of this file is not in context.]ProjectInstruction/ theproject.instructions.resolvepayload shape is unchanged; the notice is part ofcontent.This follows Codex:
~/.codex/AGENTS.mdis loaded separately from the 32 KiBproject_doc_max_bytesbudget its project docs share. Unlike Codex, the global file keeps its own 32 KiB cap, so the worst case is 64 KiB, the same as theSYSTEM.md/APPEND_SYSTEM.mdcap. Raising or configuring the caps (option 3 in the issue) is left for a separate discussion.Before / after (repro from the issue: 64,992-byte global file + project
AGENTS.md)AGENTS.mdloaded in full.Specs
ADR 0037 decision 4 and consequences,
docs/spec/03-runtime/02-agent-runtime.md§7.3, and E2E-AGENTS-001 in04-e2e-test-plan.md(plus the zh-CN copies) now describe the split budgets and the notice.Verification (base
origin/main9f6aaa2)project-instructions.test.ts16/16pnpm build:js, agent-runtime and desktoptypecheck,pnpm lint,check-architecture,pnpm docs:check,pnpm check:pr-base: pass@pi-desktop/agent-runtimetests 1300/1300; host-runtime, pi-host, shared: passpnpm test:e2e:hosted-search(fixture-backed sidecar scenario for E2E-AGENTS-001): PASS, 8/8chat-error-message,jev-api-key-check,plugin-websocket) fail the same way on unmodified main in that environment.