Skip to main content
The Gateway and Agent Run Loop represent the central nervous system of the Palyra daemon. This system manages the lifecycle of gRPC streams, orchestrates LLM interactions, handles tool execution with human-in-the-loop (HITL) approvals, and maintains session consistency through the JournalStore.

System Architecture Overview

The architecture bridges incoming user requests (via gRPC or the Channel Router) to the execution engine.

Component Relationship Diagram

This diagram maps the high-level concepts to the specific Rust modules and classes that implement them. Sources: crates/palyra-daemon/src/gateway.rs#41-82, crates/palyra-daemon/src/application/run_stream/orchestration.rs#11-33

Gateway Runtime & State Management

The GatewayRuntimeState is the primary orchestrator for the daemon’s internal logic. It holds references to all major sub-systems, including the JournalStore, ModelProvider, and ChannelRouter.

Key State Structures

Session Resolution

When a message arrives, the system must bind it to a session. The ResolveSession logic (via resolve_orchestrator_session) performs the following:
  1. Validates the session_id (ULID) crates/palyra-daemon/src/transport/http/handlers/console/chat.rs#42-49.
  2. Retrieves or creates an OrchestratorSessionRecord in the JournalStore crates/palyra-daemon/src/gateway.rs#67-69.
  3. Handles session resets or branching if requested crates/palyra-daemon/src/transport/http/handlers/console/chat.rs#107-137.
Sources: crates/palyra-daemon/src/gateway.rs#168-200, crates/palyra-daemon/src/transport/http/handlers/console/chat.rs#42-137

The Agent Run Loop (RunStream)

The RunStream function implements the core iterative loop where the agent processes inputs, calls tools, and generates responses.

Execution Flow

Key Functions in the Loop

Sources: crates/palyra-daemon/src/application/run_stream/orchestration.rs#107-203, crates/palyra-daemon/src/gateway.rs#77-82

Tool Approval Workflow

Palyra enforces a strict security model for tool execution using Cedar policies and explicit user approvals.
  1. Policy Evaluation: Before execution, evaluate_with_config checks the tool against the current ToolCallPolicySnapshot crates/palyra-daemon/src/gateway.rs#23-28.
  2. Risk Assessment: Tools are assigned risk levels (e.g., ApprovalRiskLevel). Sensitive tools default to a “Deny” state unless an approval channel is active crates/palyra-daemon/src/gateway.rs#95-101.
  3. Human-in-the-Loop (HITL): If a tool requires approval, the run enters a waiting state. An ApprovalRecord is created in the JournalStore crates/palyra-daemon/src/gateway.rs#57-59.
  4. Resolution: The user provides a decision via ResolveApproval, which triggers the continuation of the RunStream loop crates/palyra-daemon/src/gateway/runtime.rs#169-176.
Sources: crates/palyra-daemon/src/gateway.rs#23-101, crates/palyra-daemon/src/gateway/runtime.rs#169-186

ChannelRouter & Session Binding

The ChannelRouter manages integrations with external platforms (Discord, Slack, etc.) and maps their native identities to Palyra principals.
FeatureImplementationDescription
Message IngestionInboundMessageNormalizes external platform payloads into a standard internal format crates/palyra-daemon/src/channel_router.rs#215-227.
Pairing WorkflowPairingCodeRecordManages 8-character codes used to link external accounts to the daemon crates/palyra-daemon/src/channel_router.rs#19-85.
Broadcast StrategyBroadcastStrategyControls whether the agent can @everyone or only @mentions in group chats crates/palyra-daemon/src/channel_router.rs#28-42.
Isolationisolate_session_by_senderIf true, every user in a shared channel gets their own private session crates/palyra-daemon/src/channel_router.rs#169-188.
Sources: crates/palyra-daemon/src/channel_router.rs#19-227

Data Flow: Message to Journal

Every interaction is recorded in the JournalStore to ensure durability and auditability.
  1. Ingress: A message arrives via RouteMessage crates/palyra-daemon/src/gateway.rs#88.
  2. Journaling: The message is appended to the OrchestratorTapeRecord using a JournalAppendRequest crates/palyra-daemon/src/gateway.rs#63-69.
  3. Tape Sequences: Every event in a session is assigned a tape_seq (monotonically increasing integer) to maintain strict ordering crates/palyra-daemon/src/application/run_stream/orchestration.rs#112-113.
  4. Compaction: Periodically, sessions are compacted into OrchestratorCompactionArtifactRecord to manage LLM context window limits crates/palyra-daemon/src/gateway/runtime.rs#14-17.
Sources: crates/palyra-daemon/src/gateway.rs#63-88, crates/palyra-daemon/src/application/run_stream/orchestration.rs#112-113, crates/palyra-daemon/src/gateway/runtime.rs#14-17