fix(buzz-acp): deliver standing context once per session - #4183
Conversation
Protocol-v1 agents received base prompt, persona, team instructions, core memory and canvas on every turn. Deliver them in the session's first message only; both legacy paths now render through a shared StandingContext. Signed-off-by: sumit-m <33051892+sumit-m@users.noreply.github.com>
2b99468 to
286f70c
Compare
|
Rebased onto current Sections 2 and 3 of the description above are obsolete — #4395 landed both upstream while this sat open, and I have dropped my versions rather than carry a competing implementation:
What remains is section 1 only: The "Behaviour changes worth calling out" section still applies as written. Verification on the rebased branch
The latter two are the unquoted Windows temp path in #3733, not this change. The live Windows verification in the description still stands for the user-message path (turn 1 of a new session carried |
Problem
An agent with no system-prompt route takes its standing context in the user message:
base_prompt, the persona, team instructions, core memory and the canvas.format_promptre-sent all of it on every turn.That is roughly 9 KB of
base_prompt.mdalone, repeated per turn, plus persona and core. It makes the standing framing both the largest and the most recent text in the window, so it outweighs the conversation it exists to frame and evicts real channel history sooner. Related: #3126, #3242.After #4395,
has_system_prompt_supportroutesbuzz-agent(top-levelsystemPrompt),claude-agent-acp(_meta.systemPrompt) and probed goose (its custom method) away from the user message. What remains on the legacy path is every adapter reportingprotocolVersion: 1without one of those routes —codex-acptoday — and that path is what this PR fixes.Change
New
queue::StandingContextholds base prompt, persona, team instructions, core and canvas, and renders them in one place, in the order legacy agents have always seen them:[Base],[System],[Team Instructions], core, canvas. Both legacy dispatch paths — the initial message and the batch flush — go through it, so their section set and ordering cannot drift apart.run_prompt_tasktracks delivery with astanding_context_sentflag derived fromis_new_session, andformat_promptgates on it.is_new_sessioncomes from the session registry, which is cleared on every invalidation path, so a replacement session re-delivers rather than leaving the agent unbriefed.Agents that do have a system-prompt route are unaffected:
prepend_standing_for_legacyis called with an effective protocol version of2wheneverhas_system_prompt_support()is true, so nothing is prepended for them.Behaviour changes worth calling out
[Base]and the canvas. Currently a legacy agent takes its first action with no persona and no memory.[Base]. This is the most separable part of the change; happy to drop it if you would rather keep heartbeats as they are.prepend_canvas_for_legacyis removed andprepend_base_for_legacybecomesprepend_standing_for_legacy. Its doc comment already noted that the gate lived in one place "so the heartbeat and initial-message dispatch paths can't drift apart again"; this extends that to the section set itself.Codex
codex-acpis the adapter this now helps most: it reportsprotocolVersion: 1and has no known_metaequivalent. We have no access to Codex models, so we could not check the adapter's behaviour or test against it directly. If it does expose a system-prompt route, the gate inhas_system_prompt_supportis the one place to add it.Verification
Live on Windows against a local relay: turn 1 of a new session carried
[Base],[System]and[Agent Memory — core]; turn 2 opened at[Context]with none of them.cargo test -p buzz-acpon the rebased branch — 687 passing, 3 failing. The same 3 fail on cleanmainat the same commit (685 passing there; this branch adds 2 tests):keepalive_resets_idle_past_deadline— wall-clock timing, passes in isolationacp_steer_request_omits_expected_run_id_and_carries_session_and_promptgoose_transport_wins_when_both_run_id_and_capability_presentThe latter two are the unquoted Windows temp path in #3733, not this change.