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-33Gateway Runtime & State Management
TheGatewayRuntimeState 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
GatewayRuntimeState: The shared, thread-safe state containing configuration and handles to persistence crates/palyra-daemon/src/gateway.rs#168-200.AppState: The top-level Axum state used by the HTTP/gRPC transport layer, wrapping theGatewayRuntimeStatecrates/palyra-daemon/src/transport/http/handlers/console/chat.rs#10-15.
Session Resolution
When a message arrives, the system must bind it to a session. TheResolveSession logic (via resolve_orchestrator_session) performs the following:
- Validates the
session_id(ULID) crates/palyra-daemon/src/transport/http/handlers/console/chat.rs#42-49. - Retrieves or creates an
OrchestratorSessionRecordin theJournalStorecrates/palyra-daemon/src/gateway.rs#67-69. - Handles session resets or branching if requested crates/palyra-daemon/src/transport/http/handlers/console/chat.rs#107-137.
The Agent Run Loop (RunStream)
TheRunStream function implements the core iterative loop where the agent processes inputs, calls tools, and generates responses.
Execution Flow
Key Functions in the Loop
prepare_model_provider_input: Aggregates the session history (“tape”), RAG results from memory, and system prompts into a payload for the LLM crates/palyra-daemon/src/application/run_stream/orchestration.rs#16-18.execute_model_provider: Handles the actual network request to providers like OpenAI or Anthropic, with built-in cancellation polling crates/palyra-daemon/src/application/run_stream/orchestration.rs#147-183.RunStateMachine: Tracks the lifecycle of a run (e.g.,Accepted,InProgress,Done,Cancelled) crates/palyra-daemon/src/orchestrator.rs#29-30, crates/palyra-daemon/src/application/run_stream/orchestration.rs#198-203.
Tool Approval Workflow
Palyra enforces a strict security model for tool execution using Cedar policies and explicit user approvals.- Policy Evaluation: Before execution,
evaluate_with_configchecks the tool against the currentToolCallPolicySnapshotcrates/palyra-daemon/src/gateway.rs#23-28. - 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. - Human-in-the-Loop (HITL): If a tool requires approval, the run enters a waiting state. An
ApprovalRecordis created in theJournalStorecrates/palyra-daemon/src/gateway.rs#57-59. - Resolution: The user provides a decision via
ResolveApproval, which triggers the continuation of theRunStreamloop crates/palyra-daemon/src/gateway/runtime.rs#169-176.
ChannelRouter & Session Binding
TheChannelRouter manages integrations with external platforms (Discord, Slack, etc.) and maps their native identities to Palyra principals.
| Feature | Implementation | Description |
|---|---|---|
| Message Ingestion | InboundMessage | Normalizes external platform payloads into a standard internal format crates/palyra-daemon/src/channel_router.rs#215-227. |
| Pairing Workflow | PairingCodeRecord | Manages 8-character codes used to link external accounts to the daemon crates/palyra-daemon/src/channel_router.rs#19-85. |
| Broadcast Strategy | BroadcastStrategy | Controls whether the agent can @everyone or only @mentions in group chats crates/palyra-daemon/src/channel_router.rs#28-42. |
| Isolation | isolate_session_by_sender | If true, every user in a shared channel gets their own private session crates/palyra-daemon/src/channel_router.rs#169-188. |
Data Flow: Message to Journal
Every interaction is recorded in theJournalStore to ensure durability and auditability.
- Ingress: A message arrives via
RouteMessagecrates/palyra-daemon/src/gateway.rs#88. - Journaling: The message is appended to the
OrchestratorTapeRecordusing aJournalAppendRequestcrates/palyra-daemon/src/gateway.rs#63-69. - 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. - Compaction: Periodically, sessions are compacted into
OrchestratorCompactionArtifactRecordto manage LLM context window limits crates/palyra-daemon/src/gateway/runtime.rs#14-17.