Skip to content

feat: support append-mode ACP system prompts - #653

Merged
benbrandt merged 2 commits into
mainfrom
feat/acp-system-prompts
Oct 20, 2026
Merged

benbrandt merged 2 commits into
mainfrom
feat/acp-system-prompts

Conversation

@benbrandt

Copy link
Copy Markdown
Member

Summary

  • Advertise and implement standard, unstable systemPrompt support on ACP v1 and v2 session lifecycle requests. Support text-only append mode; reject override, custom modes, and non-text content before lifecycle side effects.
  • Preserve AIR's existing instruction baseline. Append standard client text after AIR customInstructions when present, otherwise after configured Codex developer instructions. Leave Codex base instructions and workspace context intact. Requests without standard prompts retain legacy AIR behavior.
  • Carry known instruction state through new/resume/load/fork and through provider restarts/app-server recovery. Omitted/null prompts preserve known instructions while the adapter session remains open; clients should resend after closing/restarting the adapter.
  • For changed prompts on an idle, persisted thread, detach/reload under the same ID. Verify an actual unload instead of acknowledging an override Codex silently ignored. Check persisted history (a planned rollout path alone is not proof), block racing inputs/config changes, and restore delivery after rejected/failed changes.
  • Do not interrupt foreground work or background terminals, force compaction, restart the global app-server, rewrite history, or repurpose collaboration-mode instructions. Standard subagent support remains separate; the AIR subagent contract is unchanged.

Timing and limits

New sessions apply the prompt on their first turn. Changed prompts on existing sessions and forks become model-visible at the next compaction. Reload updates configuration but retained history still contains the previous developer message until context is rebuilt. This is the deferral allowed by the ACP system-prompt specification, similar to the Claude adapter's documented behavior.

Changed prompts on busy sessions, sessions with background terminals, or live sessions without a saved rollout are explicitly rejected with -32602; finish the work and retry, or create a new session for immediate instructions. A runtime that keeps the existing thread loaded also produces an error rather than false success. Busy-session changes are not automatically queued in this package.

Validation

  • npm run typecheck — passed, including examples.
  • npm test — 1,859 passed, 36 skipped; includes 38 system-prompt wire tests across v1/v2, concurrency guards, runtime refusal, restoration after failure, empty-content clearing, and provider-restart preservation.
  • npm run build — passed.
  • npm run test:integration — 7 passed against real Codex app-server with a local mock model. New v1/v2 tests inspect actual developer messages for new, changed resume, fork, full-history replay, and compaction, preserving AIR and configured baselines and keeping rejected unused sessions usable.
  • npm run codex-test live-model legacy smoke — passed.
  • Additional live-model ACP smoke: standard system prompt specified system-prompt-live-ok, user prompt was Greet me., and the model returned exactly the system-prompt marker with end_turn.
  • git diff --check — passed.
  • Verified all 33 AIR scenario snapshot changes add only the systemPrompt capability. The pinned compatibility baselines are unchanged; their allowed feature-delta rule accounts for the new advertisement.

The full live-model E2E suite was not run. Specification checked at agent-client-protocol@4034a8cbc99bc48fd4579f70a3407b07907e0eb6; backend behavior verified on Codex 0.160.1.

Follow-up observed during testing

The existing /compact command can answer on compaction-item completion shortly before Codex releases the underlying turn. The new integration fixture waits for the separate runtime turn completion before issuing the next probe. Changing that command's completion semantics is outside this package.

@benbrandt
benbrandt merged commit 5993a12 into main Oct 20, 2026
6 checks passed
@benbrandt
benbrandt deleted the feat/acp-system-prompts branch October 20, 2026 17:49
Rizzen pushed a commit that referenced this pull request Oct 26, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.3.0](v2.2.2...v2.3.0)
(2026-10-26)


### Features

* add ACP v2 support again
([#620](#620))
([9e1690f](9e1690f))
* mark session list rows of worktrees Codex made (agentWorktree)
([#631](#631))
([aa02d43](aa02d43))
* narrow models to what the providers/set gateway lists
([#627](#627))
([3f555f9](3f555f9))
* report the model of each native subagent session
([#678](#678))
([51005a6](51005a6))
* return initial ACP v2 session commands
([#652](#652))
([5e9b7c5](5e9b7c5))
* support AIR sessionIndex extension
([#590](#590)) v2
([#622](#622))
([2fd758c](2fd758c))
* support append-mode ACP system prompts
([#653](#653))
([5993a12](5993a12))


### Bug Fixes

* disable Codex's Visualize skill, whose output ACP clients show as raw
text
([#667](#667))
([0ba94f5](0ba94f5))
* display the selected wire provider as JetBrains Air Gateway
([#589](#589))
([cc54abf](cc54abf))
* explain Codex config load errors caused by a deleted working directory
([#626](#626))
([a636804](a636804))
* explain invalid_encrypted_content errors after a provider change
([#668](#668))
([a77829f](a77829f))
* hold a fork back from the session list until its session/fork response
is out
([#642](#642))
([59974c7](59974c7))
* include subagent edits in the agent file-change report
([#632](#632))
([7d07123](7d07123))
* leave codex exec runs out of the session list without sessionIndex
([#639](#639))
([df75d2b](df75d2b))
* migrate to ACP SDK 2.0
([#649](#649))
([c8fd166](c8fd166))
* publish the commands when the skills change
([#643](#643))
([a62b568](a62b568))
* report structured ACP v2 failures
([#651](#651))
([5377bfe](5377bfe))
* show a Codex subagent's follow-up turn in a new subagent session
([#634](#634))
([7c761c7](7c761c7))
* synchronize ACP v2 foreground state
([#650](#650))
([986955a](986955a))
* update codex to 0.164.0
([#666](#666))
([e227c0e](e227c0e))
* wait for the compact turn to finish
([#654](#654))
([ced4c34](ced4c34))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
mrmans0n added a commit to mrmans0n/codex-acp that referenced this pull request Oct 26, 2026
…rompt

Upstream v2.3.0 (agentclientprotocol#653) implements the standard ACP append-mode systemPrompt on session/new, load,
resume and fork: the text is appended to AIR customInstructions or the configured
developer_instructions, kept while the session is open and across app-server recovery, and a
changed prompt reloads an idle persisted thread. That covers the behaviour this patch carried from
the closed upstream PR agentclientprotocol#585, but on a different wire contract.

Keep the downstream contract that Alas uses on ACP v1: initialize advertises
_meta.systemPrompt {version, append, clear, maxBytes}, and _meta.systemPrompt.append on the four
session requests is validated as before and applied as the standard append-mode systemPrompt.
The downstream CodexAcpClient/SessionFork implementation is replaced by upstream's. ACP v2 gets
neither the advertisement nor the alias. Behaviour that now follows upstream: a changed append on
an idle loaded thread reloads it instead of being rejected, and an append combined with AIR
customInstructions is appended after them instead of being rejected.
Adapted from fc0eb68.

The v1 advertisement also changes the upstream snapshot
src/__tests__/CodexACPAgent/data/initialize-v1-routed-response.json, which is not a ledger file of
this patch: this commit binds only after that path is added to the patch tests (level 3).
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.

1 participant