Repository navigation
Expose non-interrupt queued delivery for cross-thread send_message_to_thread #30499
Description
Feature request
Codex Desktop/App already has user-facing Queue vs Steer concepts, but the app/tool surface exposed to agents for cross-thread orchestration appears to only provide send_message_to_thread without an explicit delivery mode.
For parent/worker thread orchestration, we need a way for a worker thread to send a completion notice back to a parent thread without interrupting the parent thread's current turn. The desired behavior is:
delivery: "queued"orinterrupt: falseforsend_message_to_thread/ equivalent cross-thread send- the message is accepted immediately as pending input for the target thread
- it is processed only after the target thread's current active turn completes
- it should not be treated as
turn/steeror an urgent interruption - it should be durable/visible enough that the parent does not need to poll child threads with
read_thread - optionally expose status such as queued, delivered, canceled, failed
Why this matters
A common Codex workflow is a durable parent/router thread with multiple worker threads. Worker completion notices currently have two bad options:
- Use direct
send_message_to_thread, which can interrupt or interleave with the parent thread's active reasoning and muddy decision-making. - Do not send a notice and require the parent to poll/read worker threads, which is easy to miss and makes the workflow stall.
A non-interrupt queued cross-thread send would let workers report completion reliably while preserving the parent thread's current reasoning turn.
Related/adjacent issues found
- Queue, Steer, (new) Stash #23615 Queue / Steer / Stash UX concepts
- Queueing does not work when project is not in focus in the Codex app #23100 queued messages not processing until project focus
- Desktop app: explicit cross-thread orchestration over existing thread/* and turn/* primitives #14923 cross-thread orchestration over existing thread/turn primitives
Those are related, but the specific request here is an explicit non-interrupt delivery mode for cross-thread programmatic sends, suitable for agent/worker completion notices.
Suggested API shape
send_message_to_thread({
threadId,
prompt,
delivery: "queued" // or interrupt: false
})or app-server equivalent:
{
"method": "thread/message/send",
"params": {
"threadId": "...",
"input": [{"type":"text","text":"WORKER_NOTICE ..."}],
"delivery": "queued"
}
}If an active turn exists, this should enqueue. If no active turn exists, it can start normally or remain queued depending on product semantics, but the delivery mode should be explicit and observable.
Activity
devansh-jain-18 commentedon Jul 9, 2026
I strongly support this, especially for parent/worker thread workflows.
The important distinction for me is that cross-thread communication should not always mean steering the target thread. If a worker finishes while the parent/router thread is still actively reasoning or executing, I want the worker's completion report to be queued as the parent's next input, not injected into or interleaved with the active turn.
A useful shape would be a configurable delivery mode on cross-thread sends, for example:
delivery: "queued"/interrupt: false: enqueue for after the current active turndelivery: "steer"/interrupt: true: urgent guidance for the current active turnThis would make multi-thread orchestration much calmer: workers can report completion reliably, but the parent thread keeps its current task boundary intact unless the sender explicitly chooses to interrupt.
michaelvd2 commentedon Jul 14, 2026
Non-interrupt queued delivery would help, but worker completion needs a slightly stronger app-server transaction to avoid both polling and duplicate/partial wake behavior.
Suggested scoped operation on the Desktop host that already owns the coordinator's app-server connection:
The append and wake should be serialized per parent thread. Duplicate nonce is a no-op. Unknown lineage, oversized payload, busy/non-wakeable coordinator, or any failed precondition must append nothing and start no turn.
This cannot be safely emulated by attaching workers to the ChatGPT-owned stdio transport, launching a second app-server, separate
thread/inject_itemsplusturn/startcalls, rollout edits, direct steering, polling, a watcher, or a local queue: none can atomically target the already-running Desktop task with exactly-once semantics.Useful acceptance fixtures: schema round-trip; valid append-plus-one-turn; duplicate nonce; wrong lineage; unknown thread; invalid/oversized payload; busy coordinator; rollback on precondition failure; and a Desktop-host integration proving one visible completion plus one coordinator turn on the owning connection. A negative fixture should show that a separately launched app-server cannot claim to wake the original Desktop task.
Nova-Exocortex commentedon Sep 1, 2026
Component: Codex Desktop cross-task messaging
(
codex_app.send_message_to_thread) and App Server queue integrationVersion: Codex Desktop 26.825.6671.0 on Windows
There is now a narrower implementation path for this request.
Since #38456, the public App Server exposes experimental persistent queue
operations (
thread/queue/add,list,update,delete,reorder, andstart), including FIFO dispatch, change notifications, a stable submissionID, and a client-provided message ID.
However, the cross-task
send_message_to_threadtool available in Desktopstill has no delivery mode, message ID, or delivery state. Sending to a task
with an active turn can steer or reprioritize that turn immediately. The
Desktop composer's Queue/Steer preference does not appear to govern these
programmatic cross-task sends.
Reproduction:
send_message_to_threadtargeting A.being held for A's next turn.
message was queued, steered, started, or rejected.
Impact:
Routine worker reports can change the subject of an orchestrator's active turn,
fragment an unfinished unit of work, or displace a pending user decision.
Avoiding the send forces callers to poll other tasks instead.
Expected behavior:
delivery_mode: "queue" | "steer"to cross-task sends.queue; require an explicitchoice for
steer.user messages already queued ahead of it.
emulating a queue in the Desktop client.
queued,started,applied,canceled,failed, orrejected.must not enqueue or apply the message twice.
immediately, while returning the same correlated acknowledgement.
This would preserve user priority while still allowing explicit urgent
steering. It would also align cross-task messaging with the queue primitives
that already exist in the public App Server.
rtol5 commentedon Sep 30, 2026
We tested both underlying delivery paths on September 29 in SSH-backed Desktop sessions, remote CLI 0.159.1: active
turn/steerwith an exactexpectedTurnId, and CLIcodex queuefor deferred input. Steering appended the request to the existing turn, and the peer returned a substantive result while the coordinator remained active.Explicit queue delivery is also essential. A useful native contract would let callers choose queue or steer, rather than infer urgency from target state. A stale-turn race or uncertain send should not silently switch modes.
One workflow hazard we encountered: if both chats keep their turns open waiting for replies queued behind those same turns, neither can progress. Queue-only requesters must yield or do independent work; responders send once and end. Separate delivery modes make that behavior easier to design correctly.
For this workflow, peers are independently existing feature-owner sessions, not only spawned workers. Native sender provenance and accepted/queued/delivered states would remove much of the custom coordination machinery. Unloaded-target wake-up is a separate limitation; queue acceptance alone did not wake our unloaded test chats.
ZuyVladislav commentedon Oct 9, 2026
Windows Desktop: supported queue-only delivery between existing chats
Please provide a supported way to pass requests between existing Codex Desktop chats through a queue. A new request should wait for the target's current turn to finish, without steering, interrupting, or changing that turn's task.
Environment checked on 2026-10-09: Windows, Codex Desktop 26.1002.7124.0, bundled core 0.162.0-alpha.2.
Our local checks found:
send_message_to_threadschema has no explicit queue-only delivery argument.thread/queue/*methods: add, list, update, delete, reorder, and start.No new live cross-chat send was performed during these checks. We did not attach to private application channels, launch a second app-server, or modify working chats. These observations do not prove that every native send interrupts a turn, or that no supported integration is possible.
What is the supported way to use this queue for existing Desktop chats? If it is not currently exposed, please provide a native queue-only operation, with a durable submission receipt, protection against duplicate delivery, and documented behavior after a manual stop. An idle-state snapshot followed by a normal send is not enough to guarantee non-interruption.
This is a request for supported integration and explicit delivery semantics, not a newly reproduced crash or delivery defect.