Desktop app: explicit cross-thread orchestration over existing thread/* and turn/* primitives

Open 💬 13 comments Opened Mar 17, 2026 by TimesAndPlaces
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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:

  1. Ask thread A what it needs from thread B
  2. Copy that into thread B
  3. 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_threads
  • read_thread
  • create_thread
  • fork_thread
  • archive_thread
  • unarchive_thread
  • send_message_to_thread
  • send_message_to_thread should 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.toml support 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:

  1. exposing the right primitives
  2. gating them explicitly
  3. 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.

View original on GitHub ↗

13 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #13641

Powered by Codex Action

isCopyman · 3 months ago

like claude channels

MaximusStalsky · 2 months ago

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:

  • one persistent project thread acts as an orchestrator;
  • the orchestrator breaks a larger task into smaller worker tasks;
  • worker chats are durable project threads, not just temporary subagents;
  • the orchestrator should be able to create or reuse worker threads, send them assignments, observe completion, and continue with the next step;
  • the user should not have to manually copy/paste prompts between the orchestrator and worker chats.

Right now I am prototyping this through a local external watcher/queue around codex app-server primitives (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:

  • mark one thread as a project orchestrator;
  • let it create/reuse worker threads inside the same project;
  • let it assign tasks to up to N worker threads with clear permissions and audit trail;
  • show assignments, active workers, completed workers, and blocked/attention states in the UI;
  • allow the orchestrator to continue automatically after workers finish, without the human acting as a relay;
  • keep all cross-thread actions explicit, visible, and permission-gated.

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.

winnal · 2 months ago

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:

  • Let one main Codex thread message another existing main thread/session by explicit thread/session id or UI selection.
  • Preserve both threads as durable peer sessions, rather than converting one into a subordinate subagent.
  • Require explicit user-visible permission/gating before cross-thread reads or writes.
  • Record an audit trail in both source and target threads: who asked, what was sent, what was returned, and whether the target thread acted or only advised.
  • Support request/response patterns such as “ask thread B to review this plan,” “ask thread C for current repo state,” or “send this approved prompt to the repo-local head agent thread.”
  • Allow target threads to decline, report blockers, or answer read-only without mutating their workspace.

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:

  • Subagents = bounded child delegation inside one parent thread.
  • Cross-thread messaging = explicit, auditable peer coordination between durable main-agent sessions.

I would strongly prefer this to remain opt-in and permissioned, but first-class once enabled.

winnal · 2 months ago

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:

  1. A persistent head-agent thread finishes a repo/domain lane and emits a closeout summary.
  2. The user manually pastes that summary into an orchestrator/main-agent thread.
  3. The orchestrator interprets the state and writes the next prompt.
  4. The user manually pastes that prompt back into the head-agent thread.
  5. The pattern repeats, often across several persistent head-agent threads.

The requested feature would replace that with explicit cross-thread main-agent messaging:

  1. A head-agent thread can message the orchestrator thread directly when it reaches a blocker, closeout, or handoff point.
  2. The orchestrator thread can reply directly with the next approved prompt, a blocker, or a request for more evidence.
  3. The orchestrator can coordinate multiple durable head-agent threads in parallel.
  4. Each participating thread keeps its own persistent history, workspace context, authority lane, and audit trail.

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:

  • Message another persistent Codex thread/session by thread id or user-selected thread reference.
  • Preserve both threads’ histories and authority boundaries.
  • Require explicit user permission, allowlisting, or per-message confirmation.
  • Record auditable sent/received message entries in both source and target threads.
  • Support request/response handoff, status reporting, prompt delivery, review requests, blocker escalation, and completion callbacks.
  • Allow one orchestrator/main-agent thread to coordinate multiple persistent head-agent threads.
  • Keep this separate from ephemeral subagent spawning so peer sessions do not lose their durable identity or accumulated context.

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.

migsferro · 1 month ago

Request: add a low-payload read mode for cross-thread orchestration.

Current read_thread can 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)
  • or read_thread_latest_response(threadId)
  • exclude progress events, duplicated prompt/delegation input, file changes, tool calls, and metadata by default
  • return only: thread id, turn id, status, timestamp, final assistant text

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._

migsferro · 1 month ago

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_busy
  • safe default: queue or fail_if_busy
  • response reports: queued, started, steered, interrupted, or rejected
  • include target thread id, busy/idle state, and created turn id when applicable

Priority: high. Durable peer-thread workflows need predictable delivery, not ambiguous message injection.

_Footnote: drafted by ChatGPT/Codex, directed and reviewed by Miguel before posting._

prassanna-ravishankar · 1 month ago

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-in send_message_to_thread with real delivery semantics would be strictly better. but if anyone lands here needing main-to-main across CLI sessions today, the pattern works.

winnal · 1 month ago
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-in send_message_to_thread with 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.

prassanna-ravishankar · 1 month ago

@winnal damn. thanks i didnt know. it simplifies repowires architecture then.

prassanna-ravishankar · 1 month ago

@winnal wait, do threads work in an active TUI controlled session? or are they for programmatic delegation?

winnal · 1 month ago
@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

safal207 · 26 days ago

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:

  • which thread and agent produced the message;
  • which task trajectory it belongs to;
  • whether it is a proposal, observation, verified result, or command;
  • which evidence supports it;
  • whether it supersedes earlier state;
  • whether the sender is allowed to request the proposed action.

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:

  • "list_threads"
  • "read_thread"
  • "send_message_to_thread"
  • "fork_thread"
  • "create_thread"
  • "archive_thread"

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:

  1. orchestration disabled by default;
  2. thread A cannot read thread B without granted capability;
  3. a message appears in both source and target audit trails;
  4. unverified state update does not release a dependent task;
  5. stale event cannot overwrite a newer verified value;
  6. replayed duplicate event is idempotent;
  7. sender may request an action but cannot authorize execution;
  8. model, reasoning, sandbox, and approval overrides remain visible and attributable;
  9. archived or revoked thread cannot continue sending events;
  10. resumed thread preserves trajectory identity and event history.

Related LS work:

  • recovered-evidence continuation:

https://github.com/safal207/LS/pull/651

  • causal audit:

https://github.com/safal207/LS/issues/594

  • evidence gates:

https://github.com/safal207/LS/issues/595

  • deterministic replay:

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?