Skip to content

refactor: extract active turn lifecycle handling into dedicated modules#148

Merged
wangtsiao merged 16 commits into
mainfrom
dev/bug_fix_0630
Jul 5, 2026
Merged

refactor: extract active turn lifecycle handling into dedicated modules#148
wangtsiao merged 16 commits into
mainfrom
dev/bug_fix_0630

Conversation

@wangtsiao

Copy link
Copy Markdown
Contributor

No description provided.

wangtsiao added 16 commits July 1, 2026 02:32
…itor.


Accumulate child streaming output for parent polling, add auto-cursor and cancel-aware waits, inherit parent ACP connections for child turns, and improve sub-agent list/transcript UX in the TUI.
Turns now execute inline on each session's actor task instead of a
separately spawned task, so interrupting/closing a session could no
longer be stopped via JoinHandle::abort() and would hang forever
waiting on a provider response. Race the model query against the
turn's cancellation token instead, and stop removing that token from
the shared map when cancelling it (only finalize should remove it),
since the removal raced with the query fetching its own clone and
could silently hand it a fresh, disconnected token.

Also fixes several self-deadlocks introduced by the actor refactor,
where turn-completion code tried to read the currently-executing
actor's own state through its mailbox (which is not polled again
until the in-flight turn finishes): subagent stop hooks, goal
accounting's plan-mode check, and duplicate "closed" notifications
when a child agent's turn is interrupted mid-close.

Additionally adds request/stream idle timeouts to the provider HTTP
client so a stalled upstream connection can no longer wedge a turn
indefinitely, and folds turn_exec.rs into a turn_exec/ module split
for maintainability.
Reject malformed JSON-RPC payloads with ParseError/InvalidRequest responses before handler dispatch, and document stdio NDJSON framing.
…r concurrency.

Replace the unbounded notification queue and multi-stage stdio writer with a single bounded OutboundFrame channel and OutboundWriter task, add semaphore-limited inbound dispatch with a fast path for client responses, and document that ACP session/prompt remains blocking while event-driven clients use _devo/turn/start.
Running tools now reuse the same Input rendering as completed tools, and cold code_search runs emit a progress notice before building the index.
…g bootstrap

When another subscriber has already been installed (e.g. by
tokio-console), LoggingBootstrap::install() now emits a warning
and continues instead of returning an error. This allows optional
diagnostic subscribers to coexist with the file-logging path
without requiring callers to manage installation order.
Adds a tokio-console feature (gated behind cfg(feature = tokio-console))
that initializes a console-subscriber before the tokio runtime starts,
enabling real-time async task inspection via tokio-console CLI.

- arg0: new maybe_init_tokio_console() + wired into run_server_alias_dispatch
- cli: forwarded feature + init before server logging in Command::Server
- Both entry points (standalone devo-server and CLI-spawned server) covered
- Environment variable TOKIO_CONSOLE must be set at runtime to activate
- File logging is gracefully suppressed when console-subscriber takes over
Records every NDJSON frame sent and received to a structured trace
file under DEVO_HOME/traces/ when DEVO_PROTOCOL_TRACE=1 is set.
Useful for debugging client-server communication issues without
modifying application-level logging.

- Adds devo-util-paths dependency for DEVO_HOME resolution
- Trace file location can be overridden with DEVO_PROTOCOL_TRACE_FILE
- Each record includes monotonic seq, UTC timestamp, direction and payload
…bagent usage ownership

- event_stream: drop overflow events instead of spawning unbounded
  tokio tasks that would block forever and prevent channel close
- subagent_usage: track usage ownership per subagent turn for accurate
  parent-child token accounting across the agent tree
- finalize: add stream idle timeout to provider HTTP client so a
  stalled upstream connection can no longer wedge a turn
- items/turn_inline: consolidate inline item persistence to reduce
  mailbox round-trips during active turn execution
… and agent-delta fast path

The turn event stream is a single point of failure: when broadcast_event
blocks on outbound capacity, the event channel fills, enqueue_query_event
spawns unbounded overflow tasks whose sender clones prevent channel
close, and the session actor hangs forever on event_task.await.

- outbound: add enqueue_outbound_notification with 200ms max wait
  before dropping, so streaming notifications never stall the event task
- connection: add broadcast_streaming_agent_message_delta fast path that
  skips the full broadcast_event (no registry scans, no buffer locks)
- subagent: change OutputBuffer::push to try_push_text_delta so
  wait_agent's lock does not gate token streaming to the TUI
- items/handle: add non-blocking try_touch_last_activity + fallback
  item-seq counter to avoid mailbox round-trips from event-stream code
- agent_message delta handlers use the new fast path; record_subagent_
  output_event is moved after outbound delivery
…diff during research

Research runs outside the session actor (unlike execute_turn_in_actor).
Without an inline stream, every item persist/usage update sends blocking
mailbox commands and can stall inbound handlers that need the same actor.

- Add BeginInlineTurn / EndInlineTurn commands to install inline state
  for out-of-actor turns, with merge-back into actor state on completion
- Register active_stream in begin_research_turn_stream so persist_item
  uses the fast inline path instead of the mailbox
- Add record_parent_turn_totals_and_latest for research ledger snapshots

TUI: /research turns now set active_turn_is_research so automatic
git-diff overlays are suppressed during research sessions.
@wangtsiao wangtsiao merged commit 3d9cbb1 into main Jul 5, 2026
2 of 4 checks passed
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