Skip to content

Event-driven AgentLoop with mailbox drain pattern #427

@bonk-moltbot

Description

@bonk-moltbot

What

Replace the closed while-loop AgentLoop with an event-driven architecture. Everything that enters the context window goes through PendingMessage as a single pipeline:

Event → Subscriber → PendingMessage(kind: background|active) → Drain → Promote → Message

One path for everything: user messages, agent messages, tool calls, tool responses, memories, skills, goals, sub-agent responses. No exceptions, no bypass routes.

Problem

  • AgentLoop is a closed while-loop invisible to EventBus — tool calls happen inside, subscribers can't react
  • Pending messages hang when agent is idle — waiting for user input to trigger processing
  • between_rounds is a hack to peek inside the closed loop
  • Messages enter context through multiple paths (direct persistence, phantom injection, pending messages)

Key design decisions

  • Two kinds of PendingMessage: active (triggers LLM request — user messages, sub-agent responses, tool responses) and background (appears in context silently — memories from Mneme, skills from Melete)
  • AASM state machine on Session: :idle / :awaiting / :executing — replaces manual locks, determines interrupt strategy
  • Mailbox drain pattern: SQLite serialized writes provide concurrency safety without mutex
  • Two interrupt types: mailbox interrupt (stop drain loop) and tool execution interrupt (synthetic tool_response)

Prerequisites (done)

References

Full exploration: thoughts/shared/notes/2026-04-03/qa-brainstorm-event-loop-mailbox.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitectural changesepicLarge multi-ticket initiative

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions