Skip to content

feat(acp): negotiate persistent system prompts - #5386

Open
cmyk wants to merge 4 commits into
block:mainfrom
Peakhunter:fix/acp-persistent-system-prompt
Open

feat(acp): negotiate persistent system prompts#5386
cmyk wants to merge 4 commits into
block:mainfrom
Peakhunter:fix/acp-persistent-system-prompt

Conversation

@cmyk

@cmyk cmyk commented Aug 9, 2026

Copy link
Copy Markdown

Summary

Buzz-managed agents receive a sizeable block of static instructions: the managed-agent base prompt plus configured system, team/core, and channel-canvas context. For ACP adapters without a recognized persistent prompt transport, Buzz currently includes that static material in ordinary user prompts. This consumes context repeatedly and makes downstream conversation records harder to read and reason about.

This PR adds capability-negotiated persistent system prompts to buzz-acp:

  • read _meta.capabilities.persistentSystemPrompt from the adapter's initialize response;
  • when advertised, send the assembled static prompt once in session/new as _meta.systemPrompt;
  • omit that static material from ordinary prompts after session creation;
  • preserve the existing Claude-specific _meta.systemPrompt.append, Goose, and protocol-v2 transports;
  • retain the legacy repeated-prompt fallback for adapters that advertise no persistent transport;
  • pin the exact wire requests and prompt lifecycle in regression tests.

The resulting path is:

Buzz static context
  -> ACP session/new _meta.systemPrompt
  -> adapter-owned persistent instructions

ordinary channel turns
  -> only dynamic user/channel content

Companion work

Hard dependency for the accepted Codex path: the companion codex-acp contribution advertises the capability and persists _meta.systemPrompt as Codex developer instructions:

https://github.com/agentclientprotocol/codex-acp/compare/main...Peakhunter:codex-acp:fix/buzz-persistent-developer-instructions?expand=1

The companion branch was live-tested at exact head 1cf677dbe2801c4dbab678fc9e479a4a7fd87aa6.

Current Claude support remains on its existing provider-specific transport; this PR does not require a Claude adapter change.

Scope

This change owns prompt transport and repetition only. It does not add durable channel-to-ACP-session persistence across a Buzz Desktop restart, change Codex thread visibility in ChatGPT, alter lazy-pool sizing, or change outbound relay delivery/network policy.

Related work

  • Addresses part of Reduce repeated full-context injection for agent turns #3242: this PR removes repeated Buzz-owned static Base/System/team/core/canvas material for adapters that explicitly advertise persistent prompt support. It does not deduplicate dynamic thread context, so it should not close the broader issue by itself.
  • Related but not fixed — [Bug] buzz-acp loses channel sessions on restart and creates duplicate Codex cloud threads #5342: supervised restart acceptance confirmed that Buzz loses its process-local channel-to-session mapping and creates a new ACP/Codex session after Desktop restart. The new session still receives static instructions exactly once, but durable restart continuity remains separate work.
  • Complementary implementation — fix(buzz-acp): deliver standing context once per session #4183: that PR sends standing context once through the legacy user-message path for adapters without a persistent system-prompt transport. This PR instead negotiates adapter-owned system/developer instructions, preserving their authority and retaining the legacy fallback for unsupported adapters. The two approaches are semantically complementary, although both touch pool.rs and may require mechanical reconciliation depending on merge order.

No duplicate issue or pull request was found for the capability-negotiated transport introduced here.

Testing

Automated buzz-acp verification:

  • library tests: 695 passed;
  • integration tests: 9 passed;
  • combined: 704 passed, 0 failed.

Supervised macOS acceptance used the coordinated frozen Buzz and codex-acp candidates:

  • rebuilt buzz-acp SHA-256: b5a2cb7113a9ddadd76d93679ca6df7eb1a4e0eca6a0e5a8ec6577f53c415be9;
  • every adapter initialization advertised persistentSystemPrompt: true;
  • two ordinary turns continued the same main Codex session;
  • static Buzz instructions appeared once in initial developer instructions;
  • static Buzz instructions appeared zero times in either ordinary user-prompt record;
  • after an application restart, the new session again received static instructions once and its ordinary prompt contained no repeated static material.

The live-tested source head was 282988ea71869e82f05131d88307c4fce3750e49. The publication head is 1db51a13a60e09f0876c41e163fc082453c45456; it differs only by required DCO trailers. Both heads have the identical Git tree ae3312d03bc5bf757ccdb26c35b819194c378ba8, so the tested source and artifact are unchanged.

There is no visual UI change. Acceptance relied on UI continuity plus protocol/downstream structural evidence rather than treating visible replies alone as proof.

Signed-off-by: Reinhold <310554180+reinhold-ph@users.noreply.github.com>
Signed-off-by: Reinhold <310554180+reinhold-ph@users.noreply.github.com>
Signed-off-by: Reinhold <310554180+reinhold-ph@users.noreply.github.com>
Signed-off-by: Reinhold <310554180+reinhold-ph@users.noreply.github.com>
@cmyk
cmyk requested a review from a team as a code owner August 9, 2026 10:06
@cmyk

cmyk commented Aug 9, 2026

Copy link
Copy Markdown
Author

Companion adapter PR is now submitted:

That PR advertises persistentSystemPrompt and maps _meta.systemPrompt to Codex developer instructions. It is the hard dependency for the live-accepted Codex path described here.

@wolfyy970

wolfyy970 commented Aug 9, 2026

Copy link
Copy Markdown

I like the capability-negotiated transport. It gives configured instructions the right authority and preserves the legacy fallback.

Correction to my earlier review: I initially treated the memory and canvas lifecycle as a problem introduced here. It is not. This PR preserves the behavior already used for Claude and protocol-v2 agents, then adds the negotiated Codex path. The stale-revision risk is real, but it belongs in #3242 and should not block this PR.

The portability boundary still matters for the follow-up: authored instructions belong to the agent definition, while memory and channel state need their own refresh lifecycle. No change requested here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants