[macOS App] Commentary progress messages render twice while final answers render once
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.901.20858 (bundled app-server 0.153.0-alpha.5)
What subscription do you have?
API key / custom Responses-compatible provider (not signed in with ChatGPT)
What platform is your computer?
Darwin 25.6.0 arm64 arm
What issue are you seeing?
Every user-visible assistant progress update with phase: "commentary" is rendered twice in the Codex desktop transcript. The completed response with phase: "final_answer" is rendered once.
This reproduces in a fresh local task after fully quitting and relaunching the app. It is not a duplicate user submission and does not appear to be duplicate model output: thread/read reconstructs one commentary item and one final-answer item for the affected turn.
The configuration uses an API key with a custom Responses-compatible provider and gpt-5.6-sol.
What steps can reproduce the bug?
- Configure Codex desktop to use an API key and a custom provider with
wire_api = "responses". - Fully quit and relaunch the desktop app.
- Create a new local task.
- Send a prompt that requires tool use, so the assistant emits a progress/commentary message before using the tool.
- Observe that the commentary message appears twice with identical text.
- Let the turn finish and observe that the final answer appears only once.
This reproduced in two separate tasks, including a brand-new task after restart.
What is the expected behavior?
Each logical agentMessage should render once. A matching item/completed event should finalize or update the existing item by ID, not create a second visible commentary block. The behavior should be consistent for commentary and final_answer phases.
Additional information
Evidence from an affected turn:
thread/readreturns exactly oneagentMessagewithphase: "commentary"and one withphase: "final_answer".- The raw JSONL has the expected lifecycle/persistence pair for each logical message: one
event_msg.item_completedfollowed by oneresponse_item.message, sharing the exact same item ID, phase, and text. - The UI deduplicates this pair for
final_answerbut displays both copies forcommentary. codex doctorreports the desktop installation, app-server handshake, configuration, and rollout DB parity as healthy. There are no duplicate rollout paths or thread IDs.- No API keys, provider credentials, local usernames, or private prompt data are included here.
The App Server documentation says item/completed is the authoritative final state for the item:
https://learn.chatgpt.com/docs/app-server#items
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing desktop transcript handling for the item/completed and response_item.message lifecycle, using thread/read and the raw JSONL evidence in the report. Compare how matching item IDs are deduplicated for final_answer versus commentary, then reproduce with a custom Responses-compatible provider; done means each logical agentMessage renders once.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100