Skip to content

orchestration: restructure agent message loop to allow /plan cancel delivery during run_scheduler_loop (SEC-M34-002) #1603

@bug-ops

Description

@bug-ops

Background

run_scheduler_loop() holds &mut self for the entire plan execution, blocking the agent command dispatch loop. This means /plan cancel cannot be delivered while a plan is executing on CLI or any synchronous channel.

Current state

The CancellationToken plumbing is in place (PR #1515/#1516/#1457):

  • plan_cancel_token: Option<CancellationToken> field on Agent
  • run_scheduler_loop() has tokio::select! on the token at wait_event() and RunInline boundaries
  • handle_plan_cancel() fires the token if plan_cancel_token.is_some()

The mechanism is ready. The delivery path is not connected for CLI and synchronous channels.

What needs to change

The agent message loop must be restructured so that /plan cancel (and other commands) can be received and dispatched while the scheduler loop is active. Options:

  1. Spawn the scheduler loop as a tokio::task: requires decoupling the loop from &mut self (Arc/Mutex wrapping of shared state, or moving affected fields out of Agent).
  2. Side-channel via cancel_signal: Arc<Notify>: CLI/TUI reads stdin in a background task and writes to the shared notify; the scheduler loop polls it.
  3. Split agent state: separate mutable state needed by the scheduler loop from state needed by the command dispatch loop.

Affected channels

  • CLI (synchronous stdin): fully blocked during scheduler loop
  • TUI (crossterm events): has a separate event loop — may be wirable with less refactor
  • Telegram: separate teloxide task, already concurrent — may be wirable

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions