Skip to content

fix(tui): isolate scheduled top-level threads from the agent picker#185

Closed
andrei-hasna wants to merge 1 commit into
mainfrom
openloops/open-codewith/d03c86c9-bcc9-4f47-9f60-50c96ab3e82e-311dedbc
Closed

fix(tui): isolate scheduled top-level threads from the agent picker#185
andrei-hasna wants to merge 1 commit into
mainfrom
openloops/open-codewith/d03c86c9-bcc9-4f47-9f60-50c96ab3e82e-311dedbc

Conversation

@andrei-hasna

Copy link
Copy Markdown
Contributor

Summary

Global scheduled prompts resume their owning top-level thread, and the app server broadcasts that thread's ThreadStarted to every connected client. Unrelated TUI sessions unconditionally upserted any inactive ThreadStarted into the agent picker, so a scheduled thread leaked in as a subagent in sessions that don't own it.

This keeps scheduled task runtime behavior intact and isolates it from the agent UI: it gates the realtime picker upsert in infer_session_for_thread_notification on verified subagent lineage.

Changes

  • tui/src/app/thread_routing.rs: new thread_started_belongs_to_agent_picker guard — register only the primary thread, or a genuine ThreadSpawn subagent whose parent chains to the primary (directly or via an already-registered navigation entry). Thread channel/session buffering is unchanged, so schedule runtime and the owning session keep working.
  • tui/src/app/loaded_threads.rs: expose thread_spawn_parent_thread_id (pub(crate)) so the realtime guard and the resume-time walk (find_loaded_subagent_threads_for_primary) agree on what counts as subagent lineage.
  • tui/src/app.rs: import the shared helper.
  • tui/src/app/tests.rs: regression test scheduled_top_level_thread_started_is_isolated_from_agent_picker (scheduled top-level thread → buffered channel but no picker entry; genuine + deep subagents → registered); updated one existing realtime test to use genuine subagent lineage.

Schedule-manager UI (loop_display.rs / chatwidget/protocol.rs) and the ThreadScheduleUpdated/ThreadScheduleRunUpdated handling are untouched.

Validation

  • cargo test -p codex-tui --lib (new test passes; the only failures are pre-existing, environment-dependent chatwidget snapshot tests that also fail on the clean base)
  • cargo clippy -p codex-tui --all-targets -- -D warnings — clean
  • cargo fmt — clean

🤖 Generated with Claude Code

Global scheduled prompts resume their owning top-level thread, and the app
server broadcasts that thread's ThreadStarted to every connected client.
Unrelated TUI sessions unconditionally upserted any inactive ThreadStarted
into the agent picker, so a scheduled thread leaked in as a subagent.

Gate the realtime picker upsert in infer_session_for_thread_notification on
verified subagent lineage: register only the primary thread or a genuine
ThreadSpawn subagent whose parent chains to the primary (directly or via an
already-registered navigation entry), reusing thread_spawn_parent_thread_id
so the realtime and resume-time (find_loaded_subagent_threads_for_primary)
paths agree. Thread channel/session buffering is unchanged, so schedule
runtime and the owning session keep working; schedule-manager UI is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andrei-hasna

Copy link
Copy Markdown
Contributor Author

Closing as superseded after live PR0 wave2 recheck. This scheduled-thread / agent-picker leak fix is covered by newer PR #199, which is narrower and current. This PR is also unstable with red required checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant