Desktop app: explicit cross-thread orchestration over existing thread/* and turn/* primitives
What variant of Codex are you using?
Codex desktop app
What feature would you like to see?
Summary
Codex already has official thread lifecycle primitives (thread/start, thread/resume, thread/fork, thread/read, thread/list, thread/archive) plus per-turn overrides on turn/start. Subagents solve delegation inside a parent thread, but there is still no first-class, explicitly gated way for one thread/agent in the desktop app to inspect or message another existing thread.
I think the missing abstraction is cross-thread orchestration, not just subagent orchestration.
Problem
Today, when one Codex thread needs input or work from another long-lived Codex thread, the user often becomes a manual relay:
- Ask thread A what it needs from thread B
- Copy that into thread B
- Copy the answer back into thread A
That works, but it breaks down once you have multiple durable workstreams (different repos, worktrees, roles, or settings). Subagents help for short-lived delegation, but they are still subordinate to one parent thread's control plane. They are not a full replacement for peer threads that are already durable, addressable, inspectable, and often tied to different projects.
Proposed solution
Add an opt-in cross-thread orchestration capability to the desktop app, backed by the existing thread/turn primitives.
Suggested shape:
- App-level setting such as
Cross-thread orchestration, default off - Optional per-thread permission / confirmation before another thread can inspect or message it
- Tool/UI surface for:
list_threadsread_threadcreate_threadfork_threadarchive_threadunarchive_threadsend_message_to_threadsend_message_to_threadshould support overrides that already conceptually exist in the stack:- model
- reasoning effort
- sandbox / approval policy
- network / access mode
- Clear audit trail in both the source and target thread so cross-thread actions are visible and attributable
- Optional
config.tomlsupport in addition to the UI toggle
Why this seems viable
This does not look like a net-new orchestration backend problem. It looks more like an app/tool-surface and permissions problem:
- the app server already understands thread lifecycle operations
- the SDK and docs already describe thread creation/resume flows
- the desktop app already has the concept of multiple durable threads/projects
So the main work appears to be:
- exposing the right primitives
- gating them explicitly
- making the UX legible and auditable
Why threads should be first-class here
Subagents are useful, but thread-first orchestration has different strengths:
- threads are durable across time, not just spawned under one parent
- threads can map cleanly to separate repos/worktrees/projects
- threads are inspectable and resumable
- threads can have distinct model/access/reasoning settings
- peer threads are a better fit for "agent A asks agent B" than forcing everything into one parent thread's internal hierarchy
Related issues
- #12462 Feature: Inter-Agent Communication Channels for Direct Agent-to-Agent Messaging
- #13641 Expose thread/read and thread/list as MCP tools for tool-only clients
- #12047 Multi-agent TUI overhaul: named agents, per-agent config, async orchestration & @mention messaging
- Closed predecessors that point in the same direction: #3280, #2604, #4219
Acceptance criteria
- Cross-thread orchestration is explicit, user-visible, and disabled by default
- A thread can list/read other threads only when the capability is enabled
- A thread can create/fork/archive/unarchive other threads through supported surfaces
- A thread can send a follow-up instruction to another existing thread
- Model/reasoning/access overrides can be applied intentionally when sending or creating
- Cross-thread activity is visible in the UI and attributable
- MCP/app-server surfaces gain parity where appropriate so orchestration is not app-only
Additional information
I think this is the right complement to subagents: subagents for internal delegation, threads for durable peer-to-peer orchestration.
13 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
like claude channels
I want to add a concrete Windows Desktop use case that strongly matches this feature request.
I am trying to use Codex Desktop as a project-level orchestration environment:
Right now I am prototyping this through a local external watcher/queue around
codex app-serverprimitives (thread/list,thread/resume,turn/start,thread/turns/list, etc.). It works well enough to prove the concept, but it is a workaround. The user has to build a local watcher, assignment files, lifecycle markers, a Rainmeter status widget, and manual handoff conventions just to make durable project-thread orchestration possible.What I would like to see natively in Codex Desktop is an explicit project-level orchestration mode, for example:
For my current workflow this would remove the need for a fragile external queue/watcher layer and make long-running project automation much more natural.
Related issue from this same experiment: Desktop currently appears to refresh app-server-updated worker threads only when the Windows Desktop window receives focus: #21177. That refresh issue is separate, but it becomes more visible when trying to build cross-thread orchestration on top of the existing app-server primitives.
Adding a concrete use case in support of this feature request: the important distinction is not just “more subagents,” but main-agent-to-main-agent communication across persistent sessions.
In active multi-repo or multi-workstream setups, users often keep separate long-lived Codex threads as durable “main agents” for different domains, repos, or authority lanes. Those threads accumulate context, local decisions, tool history, and their own operating posture. A spawned subagent is useful for bounded delegation, but it is not equivalent to asking another already-running main agent for a cross-check or handoff because the other main agent has persistent session context and may be the actual owner of that lane.
Desired capability:
Why it matters:
Persistent peer-thread feedback loops are a strong safety and quality pattern. They let one main agent check another main agent’s assumptions without flattening everything into a single overloaded thread or losing continuity by spawning a fresh subagent. This is especially useful when each main thread owns a different repo, worktree, policy lane, or long-running execution context.
A good mental model might be:
I would strongly prefer this to remain opt-in and permissioned, but first-class once enabled.
Adding one more concrete workflow detail from the motivating use case:
Right now, multi-thread orchestration is possible only through a manual copy/paste loop:
The requested feature would replace that with explicit cross-thread main-agent messaging:
This is materially different from subagents. Subagents are bounded child delegations created by a parent. The desired workflow is peer coordination between durable main-agent sessions that already exist and may each own a long-running domain/repo context.
Possible feature name: Cross-Thread Main Agent Messaging.
Important requirements:
The main goal is to remove the user from being the manual clipboard transport between persistent main-agent sessions while keeping the coordination explicit, permissioned, and inspectable.
Request: add a low-payload read mode for cross-thread orchestration.
Current
read_threadcan be much heavier than manual copy/paste when the caller only needs the target thread's final answer. In one Desktop case, a last-turn read with outputs disabled returned ~10k visible tokens, while the useful final assistant response was ~650 tokens.Suggested shape:
read_thread(threadId, turnLimit=1, view=latest_final)read_thread_latest_response(threadId)Priority: high. Cross-thread orchestration is much less useful if agent-side reads cost 10x-20x more context than manual copy/paste.
_Footnote: drafted by ChatGPT/Codex, directed and reviewed by Miguel before posting._
Request: expose explicit delivery semantics for
send_message_to_thread.I see app-server/TUI queue work in issues/PRs such as #23620 and #25258. The missing piece here is the model-callable cross-thread tool surface: an orchestrator agent needs to know whether it is queuing, steering, interrupting, or being rejected because the target thread is busy.
Suggested shape:
deliveryMode: queue | steer | interrupt | fail_if_busyqueueorfail_if_busyPriority: high. Durable peer-thread workflows need predictable delivery, not ambiguous message injection.
_Footnote: drafted by ChatGPT/Codex, directed and reviewed by Miguel before posting._
the main-agent-to-main-agent distinction @winnal draws is the one that matters. subagents-inside-a-thread is a different problem from two long-lived peers coordinating, and the user-as-manual-relay loop is the thing that actually eats the time.
for the CLI side of this i built repowire, where each session gets a mesh address and they ask/ack/notify/broadcast to each other. @migsferro's point about delivery semantics is spot on, the asks carry explicit outcomes (delivered, queued, blocked) rather than fire-and-forget, because did-the-other-agent-actually-get-this turns out to be the whole game.
honest caveat: repowire is daemon/mesh-centric across CLI sessions, not native to codex desktops
thread/*primitives. so for your desktop case a built-insend_message_to_threadwith real delivery semantics would be strictly better. but if anyone lands here needing main-to-main across CLI sessions today, the pattern works.dude, Codex ALREADY implemented the idea. there is thread management on Codex now, you can send messages from one thread to another now. stop trying to promote your own repo when Codex already implemented the feature.
@winnal damn. thanks i didnt know. it simplifies repowires architecture then.
@winnal wait, do threads work in an active TUI controlled session? or are they for programmatic delegation?
yes. it's pretty much exactly what i asked for. it's one of the best features they've added for agentic workflows tbh. you can easily find the docs on it how it works to answer your question. but it basically directly addresses what i spoke about. i posted a separate issue about it and marked it as complete since they released the feature: https://github.com/openai/codex/issues/22768
This proposal maps closely to LS work on trajectory continuity, verified shared state, and governed multi-agent coordination.
A useful distinction may be:
message delivered
≠ statement verified
≠ state accepted
≠ action authorized
Cross-thread orchestration needs more than a messaging API. The receiving thread should be able to determine:
A possible event envelope:
{
"schema_version": "cross-thread-event/v0.1",
"event_id": "evt-2026-001",
"trajectory_id": "project:migration",
"continuation_id": "thread-infra-04",
"source": {
"thread_id": "thread-infra",
"agent_id": "agent-infra",
"role": "infrastructure"
},
"target": {
"thread_id": "thread-application"
},
"event_type": "STATE_UPDATE",
"subject": "deployment.endpoint",
"payload": {
"value": "https://new-endpoint.example"
},
"evidence_refs": [
"tool-event:health-check-883",
"artifact:deployment-report"
],
"verification_status": "VERIFIED",
"authority": {
"may_inform": true,
"may_request_action": true,
"may_authorize_execution": false
}
}
The receiving thread should process it through explicit stages:
receive
→ authenticate source
→ validate trajectory and scope
→ inspect evidence
→ detect stale or conflicting state
→ accept / reject / defer
→ propose local action
→ normal approval and execution path
The core invariant would be:
«Cross-thread communication may inform reasoning, but it must not silently bypass the receiving thread’s approval, sandbox, or execution policy.»
A second invariant:
«Durable peer threads should exchange typed events, not only unstructured prose that can be mistaken for verified state.»
This could support the requested operations safely:
with per-operation capability checks.
For example:
{
"capability": "send_message_to_thread",
"source_thread": "thread-A",
"target_thread": "thread-B",
"allowed_event_types": [
"QUESTION",
"STATE_UPDATE",
"RESULT"
],
"requires_target_consent": true,
"expires_at": "2026-06-25T00:00:00Z"
}
A deterministic conformance suite could test:
Related LS work:
https://github.com/safal207/LS/pull/651
https://github.com/safal207/LS/issues/594
https://github.com/safal207/LS/issues/595
https://github.com/safal207/LS/issues/597
Would a small vendor-neutral "CrossThreadEvent" conformance fixture help separate messaging, verified shared state, capability checks, and execution authorization?