Skip to content

refactor: deliver messages directly to agent mailbox, remove TUI inbox routing#84

Merged
yishuiliunian merged 1 commit intomainfrom
refactor/agent-mailbox-direct-delivery
Apr 5, 2026
Merged

refactor: deliver messages directly to agent mailbox, remove TUI inbox routing#84
yishuiliunian merged 1 commit intomainfrom
refactor/agent-mailbox-direct-delivery

Conversation

@yishuiliunian
Copy link
Copy Markdown
Contributor

Summary

  • Remove TUI concept leakage from agent runtime: TUI no longer buffers messages locally or mutates agent state
  • Fix ephemeral agent premature exit on user input (drain_pending now reliable without yield_now)
  • Consolidate redundant types (InputFromClient → AgentInput) and harden status/backpressure semantics

Architecture changes

Principle: Agent owns its internal state. External actors interact only via mailbox delivery + explicit interrupt. TUI state is derived solely from agent events.

  • agent_idle field removed — derived via AgentViewState::is_idle() from observable.status
  • Inbox struct removed — TUI calls append_user_display() + route_message() directly, no local buffering
  • Ephemeral idle check — dropped yield_now(), drain_pending() is reliable now that messages go directly to agent mailbox
  • InterruptSignal purified — only carries cancel/shutdown semantics, no longer overloaded with "new message arrived"
  • drain_pending() returns Vec<AgentInput> — Control commands no longer silently dropped
  • InputFromClient merged into AgentInput — eliminates duplicate types (Interrupt variant was vestigial)
  • Status rollback on emit failure — keeps runner status consistent with observer view
  • Observation channel drops upgraded to warn — prod visibility for lost MessageRouted/SubAgentSpawned/Finished events

Files changed

  • loopal-session: removed inbox.rs, added is_idle()/is_active_agent_idle(), new append_user_display()
  • loopal-tui: direct message delivery in key_dispatch_ops.rs, all agent_idle readers migrated
  • loopal-runtime: drain_pending_input() processes Control inline, ephemeral idle simplified, status transition rollback
  • loopal-agent-server: HubFrontend uses AgentInput, drain_pending() preserves Control
  • loopal-agent-hub: observation event drops logged at warn level
  • loopal-protocol: InterruptSignal semantics documented, ObservableAgentState::status contract

Test plan

  • CI passes (49 tests, clippy, rustfmt)

…x routing

TUI previously buffered messages in a local Inbox and used agent_idle as a
routing decision: when agent was busy, messages were queued locally and an
interrupt signal was used to wake the agent to drain the queue. This was
TUI concept leakage into the agent runtime — agent internal state was
being directly mutated by the display layer, and interrupt was overloaded
with "cancel work" AND "new message arrived" semantics.

The worst symptom: ephemeral agents exited immediately on user input
because the yield_now idle check fired before the TUI's delayed inbox
forward could complete the IPC round-trip.

Architecture principles applied:
- Agent owns its internal state (idle/busy); external actors interact only
  via mailbox delivery + explicit interrupt
- TUI state (observable.status, is_idle) is derived solely from agent
  events, never set directly
- InterruptSignal carries only cancel/shutdown semantics

Key changes:
- Remove agent_idle field; derive via AgentViewState::is_idle() from status
- Remove Inbox struct entirely (dead after routing bypass)
- TUI calls append_user_display() + route_message() directly — no buffering
- Ephemeral idle check: drop yield_now(), drain_pending() is reliable now
- drain_pending() returns Vec<AgentInput> so Control commands are not
  silently dropped
- Merge InputFromClient into AgentInput (Interrupt variant was vestigial)
- Status transition rolls back on emit failure for consistency
- Upgrade observation-channel try_send drops from debug to warn for prod
  visibility

49/49 tests pass, zero clippy warnings, rustfmt clean.
@yishuiliunian yishuiliunian merged commit ebc445a into main Apr 5, 2026
3 checks passed
@yishuiliunian yishuiliunian deleted the refactor/agent-mailbox-direct-delivery branch April 5, 2026 08:54
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