Repository navigation
fix: migrate to ACP SDK 2.0 - #649
Merged
Merged
Conversation
benbrandt
added a commit
that referenced
this pull request
Oct 20, 2026
## Summary Synchronize ACP v2 foreground state independently of prompt acceptance. This PR is based directly on main after #649 merged. - Send a current `state_update` after any requested history replay and before every successful `session/resume` response, including omitted/null `replayFrom`. - Restore active runtime state on resume and serialize snapshots with live state transitions so backpressure cannot send a stale snapshot after newer state. Idle snapshots repeat neither completion usage nor failure metadata. - Report `running` when Codex accepts or reports foreground work, including pre-insertion hooks. Prompt success still waits for the user-message echo. Work that starts but never inserts input still ends with an idle boundary, including transport loss before the turn-start acknowledgment. - Replace per-request requires_action/running brackets with session-owned pending interactions and runnable items. Parallel work can remain running; answering one wait does not blindly resume a still-blocked workflow. - Use actual runtime starts, streamed progress, and active status with no wait flags as positive progress evidence. Nonempty Codex wait flags count requests and are not by themselves evidence that the whole workflow is blocked. - Do not resume withdrawn interactions, and invalidate old waits at idle/close so late answers cannot revive an ended turn or alter a newer turn. - Update the developer contract, snapshots, and focused regression coverage. Add a real-process v2 integration test for early running, prompt insertion, and all three resume modes. ACP v1 behavior and the existing AIR subagent wire contract are preserved. Standard structured failure reporting, initial commands, system prompts, and standard subagent sessions remain separate work packages; failure stop reasons are intentionally unchanged here. ## Specification and runtime evidence Checked ACP specification revision `4034a8c`: - [Current-state synchronization](https://github.com/agentclientprotocol/agent-client-protocol/blob/4034a8cbc99bc48fd4579f70a3407b07907e0eb6/docs/protocol/v2/session-setup.mdx#L313-L329) - [Foreground state and user-action semantics](https://github.com/agentclientprotocol/agent-client-protocol/blob/4034a8cbc99bc48fd4579f70a3407b07907e0eb6/docs/protocol/v2/prompt-lifecycle.mdx#L843-L938) Codex runtime status semantics checked against bundled runtime `0.160.1` (`codex-rs/app-server/src/thread_status.rs`): wait flags count pending interactions; active status with no wait flags implies the runtime is running. ## Validation - `npm run typecheck` — passed, including examples. - `npm test` — 1,802 passed; 36 skipped. - `npm run build` — passed. - `npm run test:integration` — 5 passed, including the new real-process ACP v2 test with a local mock model. - `npm run codex-test` — live-model smoke test from an empty scratch directory completed with `end_turn`. - `git diff --check` — passed. The full live-model E2E suite was not run.
benbrandt
added a commit
that referenced
this pull request
Oct 20, 2026
## Summary Report terminal ACP v2 foreground failures through the standard `idle` / `stopReason: "error"` shape, with an `error` object containing a code and user-facing message. This is the next isolated package after #649 and #650, based on main. - Carry terminal failure independently of AIR negotiation and of the v1-shaped prompt result. Preserve v1 responses, AIR session-failure metadata, quota, and usage. - Cover ordinary prompted turns, local commands, compact/review commands, implementation follow-ups, and agent-initiated turns. - Before insertion, keep the JSON-RPC error response as well as the idle error when foreground work ends. After insertion, keep the successful messageId response and report the work outcome through idle. - Preserve cancellation precedence, including runtime errors raised while aborting. Retried model errors, individual failed tools, unrelated-turn errors, and idle background errors do not become terminal foreground failures. - Close unfinished v2 tool calls before the idle failure instead of clearing their tracker first. - Omit opaque error data from the new standard error object; use safe messages for process loss and unexpected internal exceptions. V2 fallback text for process loss is sanitized too. - Keep resume snapshots free of failure details so reconnecting does not replay a terminal incident as a new completion. The specification checked was `4034a8c`: [v2 failure semantics](https://github.com/agentclientprotocol/agent-client-protocol/blob/4034a8cbc99bc48fd4579f70a3407b07907e0eb6/docs/protocol/v2/prompt-lifecycle.mdx#L801-L839). Initial commands, system prompts, and standard subagent sessions remain separate work packages. Existing AIR subagent behavior is unchanged. ## Validation - `npm run typecheck` — passed, including examples. - `npm test` — 1,815 passed; 36 skipped. - `npm run build` — passed. - `npm run test:integration` — 5 passed against real Codex app-server with a local mock model. - The real-process v2 test now verifies terminal HTTP 401 -> idle/error with code -32000, then clears the mock failure and verifies a successful prompt and all resume modes. The mock holds the error across Codex's authentication retry rather than accidentally returning an unrelated error. - Focused wire/snapshot coverage checks AIR and non-AIR failures, pre-insertion authentication, cancellation races, failed-tool cleanup, implementation failures, unrelated errors, and resume behavior. - `npm run codex-test` — live-model smoke test from an empty scratch directory completed with end_turn (backward-compatibility check). - `git diff --check` — passed. The full live-model E2E suite was not run. Failure scenarios use the local model mock rather than changing real credentials or provoking failures against an external provider.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrate codex-acp from ACP SDK 1.5 to 2.0 while preserving the adapter's existing ACP v1, ACP v2, and AIR feature behavior.
.agentspath.Most changed files contain only SDK import-path changes. No existing snapshots were updated.
Scope
This is the SDK migration only. Foreground-state/resume synchronization, structured v2 failure reporting, initial slash commands, standard system prompts, and standard subagent sessions remain separate work packages. Existing AIR behavior is preserved; the bundled Codex runtime version is unchanged.
Validation
npm run typecheck— passed, including examples.npm test— 1,790 passed; 36 skipped.npm run build— passed.npm run test:integration— 4 passed against the real Codex app-server with a local mock model.sdk-upgrade-ok, with no file/tool access requested.git diff --check— passed.The full live-model E2E suite was not run. npm audit reports one pre-existing high-severity advisory in the development-only MCP test dependency; this PR does not change that dependency.