openai / openai/codex

[Codex App Server] Support durable input requests across restarts

Open
#42,622 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app-server CLI enhancement
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What variant of Codex are you using?

codex app-server from Codex CLI 0.148.0.

What feature would you like to see?

Please add a supported way to defer an input-required operation so that the Codex process can exit and the operation can later continue after thread/resume in a new App Server process.

This would apply to pending operations such as:

  • command and file-change approvals;
  • requestUserInput;
  • permission requests;
  • MCP elicitation;
  • dynamic tool calls.

A possible protocol shape would be:

  1. Codex emits an input request with a durable request handle.
  2. The client acknowledges that the request is deferred.
  3. Codex persists enough state to stop or unwind the active turn safely.
  4. After App Server restart, thread/resume exposes the unresolved request.
  5. The client resolves the request exactly once and Codex continues the logical operation.

The exact API is not important. A Claude-style PreToolUse defer result, a persisted pending-request resource, or a dedicated resume operation could all satisfy the use case.

Additional information
Comparable Claude behavior

Claude Code supports this lifecycle in headless print mode. A PreToolUse hook can return permissionDecision: "defer" before the tool executes. The query then ends with stop_reason: "tool_deferred" and returns the session ID plus deferred_tool_use metadata identifying the pending tool call, including its ID, name, and input. The hosting process can exit while an external system waits for approval or another prerequisite.

When the caller later resumes that session, Claude presents the same pending tool call to PreToolUse again. The hook can then allow, modify, or deny it based on the now-available external state. The important semantics are that deferral is terminal for the current query, the tool has not executed, and resumption re-evaluates the pending call from durable session state rather than relying on the original process.

Codex does not need to copy this hook API exactly, but an equivalent lifecycle would solve this use case. Currently in Codex PreToolUse is close conceptually, but it has no durable defer outcome.

Why is this needed?

Some server deployments suspend idle or input-blocked workloads and preserve only durable storage such as CODEX_HOME. They cannot preserve process memory indefinitely.

Codex currently persists thread history, but pending input requests remain tied to live process state. In particular, the App Server's outgoing request callback and the active turn waiting behind it are in memory. MCP elicitation and dynamic tool calls have additional in-memory responders.

Consequently, persisting the visible request fields (thread ID, turn ID, item ID, tool arguments, and the eventual decision) is insufficient. A restarted App Server has no live continuation to which the response can be delivered.

Current behavior

I tested the following with Codex CLI 0.148.0:

  1. Start codex app-server with a persistent CODEX_HOME.
  2. Start a thread and trigger item/commandExecution/requestApproval.
  3. Record the thread ID and pending JSON-RPC request.
  4. Terminate App Server before answering.
  5. Start a new App Server using the same CODEX_HOME.
  6. Call thread/resume for the same thread.

The thread and persisted rollout history are restored, but the pending approval is not re-emitted. The interrupted turn is not continued, and responding with the old JSON-RPC request ID does not resolve anything in the new process. Note that this differs from reconnecting a client to the same live App Server.

It would be useful if upstream could clarify whether this recovery model fits the intended App Server architecture. If preserving the original turn is intentionally unsupported, an official two-phase pattern for ending the turn with a durable pending operation and starting a continuation turn after approval would also address the deployment requirement.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the codex app-server request lifecycle and the thread/resume entry point, then reproduce the documented approval flow across an App Server restart using persistent CODEX_HOME. Trace how pending approvals, user input, MCP elicitation, and dynamic tool calls are represented and resumed. Done means a deferred request survives restart, is exposed by thread/resume, resolves exactly once, and continues safely.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.