Skip to main content
The Gateway Runtime is the central coordination hub of the Palyra daemon (palyrad). It manages the lifecycle of Sessions (durable conversation threads) and Runs (active agent execution turns), providing the state machinery required to bridge external transports (gRPC, HTTP) with the internal agent loop, tool execution, and the journal audit system.

GatewayRuntimeState: The System Hub

GatewayRuntimeState is the shared, thread-safe state container that persists across the daemon’s lifetime. It serves as the primary interface for all transport surfaces to interact with the underlying JournalStore and specialized runtimes (Memory, Skills, Workers).

Key Responsibilities

Data Flow: Inbound to Dispatch

The following diagram illustrates how a message travels from a transport layer through the GatewayRuntimeState into the orchestrator. Message Admission & State Association Sources: crates/palyra-daemon/src/gateway/runtime.rs#26-48, crates/palyra-daemon/src/orchestrator.rs#1-10, crates/palyra-daemon/src/journal.rs#1-9.

Run and Session State Machine

Palyra distinguishes between a Session (the long-lived context) and a Run (a single execution attempt). A session can have many runs, but only one active run at a time is enforced by the RunStateMachine.

Run Lifecycle States (RunLifecycleState)

The state machine tracks the progression of an agent turn:
  1. Queued: The run is created but not yet active.
  2. Running: The agent loop is actively processing provider turns or tools.
  3. Waiting: The run is suspended awaiting operator approval or external input.
  4. Terminal: The run has ended (Completed, Cancelled, or Failed).
State Transition Logic Sources: crates/palyra-daemon/src/orchestrator.rs#107-107, crates/palyra-daemon/src/gateway/runtime.rs#8-12.

The Orchestrator and Agent Loop

The process_run_stream_message function in orchestration.rs is the entry point for the streaming agent loop. It coordinates provider turns, tool execution, and tape recording.

The Agent Loop (AgentRunLoopState)

The loop iterates through the following phases:

Tape: The Deterministic Journal

Every observable event in the agent loop is mirrored to the Orchestrator Tape. This is an append-only log in the journal that allows for deterministic replay and auditability of agent decisions crates/palyra-daemon/src/application/run_stream/orchestration.rs#7-9. Agent Loop Execution Flow
PhaseEntityRole
IntakeInboundCoalescerMerges rapid-fire messages into a single turn crates/palyra-daemon/src/application/inbound_coalescer.rs#1-10.
Planningplan_usage_routingSelects the model provider and budget crates/palyra-daemon/src/application/run_stream/orchestration.rs#69-69.
Executiontool_flowManages parallel tool execution and approval gates crates/palyra-daemon/src/application/run_stream/tool_flow.rs#138-150.
RecordingOrchestratorTapeAppendRequestPersists every step to the journal crates/palyra-daemon/src/application/run_stream/orchestration.rs#48-52.
Sources: crates/palyra-daemon/src/application/run_stream/orchestration.rs#1-15, crates/palyra-daemon/src/application/run_stream/tool_flow.rs#1-11.

Inbound Message Admission & Coalescing

Before a run begins, inbound messages from external platforms (Slack, Discord, etc.) pass through the InboundCoalescer. This component prevents “race conditions” where multiple messages arrive in quick succession, ensuring they are processed as a single logical turn for the agent crates/palyra-daemon/src/application/inbound_coalescer.rs#1-10.

Channel Turn Lifecycle

  1. Admission: The ChannelRouter identifies the principal and session.
  2. Coalescing: Messages are buffered for a short window.
  3. Dispatch: The coalesced payload is sent to process_run_stream_message.
  4. Delivery: The agent’s response is routed back through the OutboundLifecycle.
Sources: crates/palyra-daemon/src/gateway.rs#79-83, crates/palyra-daemon/src/application/mod.rs#47-48.