pub struct EventLoop { /* private fields */ }Expand description
The main event loop orchestrator.
Implementations§
Source§impl EventLoop
impl EventLoop
Sourcepub fn new(config: RalphConfig) -> Self
pub fn new(config: RalphConfig) -> Self
Creates a new event loop from configuration.
Sourcepub fn with_context(config: RalphConfig, context: LoopContext) -> Self
pub fn with_context(config: RalphConfig, context: LoopContext) -> Self
Creates a new event loop with a loop context for path resolution.
The loop context determines where events, tasks, and other state files are located. Use this for multi-loop scenarios where each loop runs in an isolated workspace (git worktree).
Sourcepub fn with_context_and_diagnostics(
config: RalphConfig,
context: LoopContext,
diagnostics: DiagnosticsCollector,
) -> Self
pub fn with_context_and_diagnostics( config: RalphConfig, context: LoopContext, diagnostics: DiagnosticsCollector, ) -> Self
Creates a new event loop with explicit loop context and diagnostics.
Sourcepub fn with_diagnostics(
config: RalphConfig,
diagnostics: DiagnosticsCollector,
) -> Self
pub fn with_diagnostics( config: RalphConfig, diagnostics: DiagnosticsCollector, ) -> Self
Creates a new event loop with explicit diagnostics collector (for testing).
Sourcepub fn loop_context(&self) -> Option<&LoopContext>
pub fn loop_context(&self) -> Option<&LoopContext>
Returns the loop context, if one was provided.
Sourcepub fn config(&self) -> &RalphConfig
pub fn config(&self) -> &RalphConfig
Returns the configuration.
Sourcepub fn registry(&self) -> &HatRegistry
pub fn registry(&self) -> &HatRegistry
Returns the hat registry.
Sourcepub fn get_hat_backend(&self, hat_id: &HatId) -> Option<&HatBackend>
pub fn get_hat_backend(&self, hat_id: &HatId) -> Option<&HatBackend>
Gets the backend configuration for a hat.
If the hat has a backend configured, returns that. Otherwise, returns None (caller should use global backend).
Sourcepub fn add_observer<F>(&mut self, observer: F)
pub fn add_observer<F>(&mut self, observer: F)
Adds an observer that receives all published events.
Multiple observers can be added (e.g., session recorder + TUI). Each observer is called before events are routed to subscribers.
Sourcepub fn set_observer<F>(&mut self, observer: F)
👎Deprecated since 2.0.0: Use add_observer instead
pub fn set_observer<F>(&mut self, observer: F)
Sets a single observer, clearing any existing observers.
Prefer add_observer when multiple observers are needed.
Sourcepub fn check_termination(&self) -> Option<TerminationReason>
pub fn check_termination(&self) -> Option<TerminationReason>
Checks if any termination condition is met.
Sourcepub fn initialize(&mut self, prompt_content: &str)
pub fn initialize(&mut self, prompt_content: &str)
Initializes the loop by publishing the start event.
Sourcepub fn initialize_resume(&mut self, prompt_content: &str)
pub fn initialize_resume(&mut self, prompt_content: &str)
Initializes the loop for resume mode by publishing task.resume.
Per spec: “User can run ralph resume to restart reading existing scratchpad.”
The planner should read the existing scratchpad rather than doing fresh gap analysis.
Sourcepub fn next_hat(&self) -> Option<&HatId>
pub fn next_hat(&self) -> Option<&HatId>
Gets the next hat to execute (if any have pending events).
Per “Hatless Ralph” architecture: When custom hats are defined, Ralph is always the executor. Custom hats define topology (pub/sub contracts) that Ralph uses for coordination context, but Ralph handles all iterations.
- Solo mode (no custom hats): Returns “ralph” if Ralph has pending events
- Multi-hat mode (custom hats defined): Always returns “ralph” if ANY hat has pending events
Sourcepub fn has_pending_events(&self) -> bool
pub fn has_pending_events(&self) -> bool
Checks if any hats have pending events.
Use this after process_output to detect if the LLM failed to publish an event.
If false after processing, the loop will terminate on the next iteration.
Sourcepub fn has_pending_human_events(&self) -> bool
pub fn has_pending_human_events(&self) -> bool
Checks if any pending events are human-related (human.response, human.guidance).
Used to skip cooldown delays when a human event is next, since we don’t want to artificially delay the response to a human interaction.
Sourcepub fn get_hat_publishes(&self, hat_id: &HatId) -> Vec<String>
pub fn get_hat_publishes(&self, hat_id: &HatId) -> Vec<String>
Gets the topics a hat is allowed to publish.
Used to build retry prompts when the LLM forgets to publish an event.
Sourcepub fn inject_fallback_event(&mut self) -> bool
pub fn inject_fallback_event(&mut self) -> bool
Injects a fallback event to recover from a stalled loop.
When no hats have pending events (agent failed to publish), this method
injects a task.resume event which Ralph will handle to attempt recovery.
Returns true if a fallback event was injected, false if recovery is not possible.
Sourcepub fn build_prompt(&mut self, hat_id: &HatId) -> Option<String>
pub fn build_prompt(&mut self, hat_id: &HatId) -> Option<String>
Builds the prompt for a hat’s execution.
Per “Hatless Ralph” architecture:
- Solo mode: Ralph handles everything with his own prompt
- Multi-hat mode: Ralph is the sole executor, custom hats define topology only
When in multi-hat mode, this method collects ALL pending events across all hats
and builds Ralph’s prompt with that context. The ## HATS section in Ralph’s
prompt documents the topology for coordination awareness.
If memories are configured with inject: auto, this method also prepends
primed memories to the prompt context. If a scratchpad file exists and is
non-empty, its content is also prepended (before memories).
Sourcepub fn build_ralph_prompt(&self, prompt_content: &str) -> String
pub fn build_ralph_prompt(&self, prompt_content: &str) -> String
Builds the Ralph prompt (coordination mode).
Sourcepub fn get_active_hat_id(&self) -> HatId
pub fn get_active_hat_id(&self) -> HatId
Returns the primary active hat ID for display purposes. Returns the first active hat, or “ralph” if no specific hat is active.
Sourcepub fn record_event_count(&mut self) -> usize
pub fn record_event_count(&mut self) -> usize
Records the current event count before hat execution.
Call this before executing a hat, then use check_default_publishes
after execution to inject a fallback event if needed.
Sourcepub fn check_default_publishes(&mut self, hat_id: &HatId, _events_before: usize)
pub fn check_default_publishes(&mut self, hat_id: &HatId, _events_before: usize)
Checks if hat wrote any events, and injects default if configured.
Call this after hat execution with the count from record_event_count.
If no new events were written AND the hat has default_publishes configured,
this will inject the default event automatically.
Sourcepub fn bus(&mut self) -> &mut EventBus
pub fn bus(&mut self) -> &mut EventBus
Returns a mutable reference to the event bus for direct event publishing.
This is primarily used for planning sessions to inject user responses as events into the orchestration loop.
Sourcepub fn process_output(
&mut self,
hat_id: &HatId,
output: &str,
success: bool,
) -> Option<TerminationReason>
pub fn process_output( &mut self, hat_id: &HatId, output: &str, success: bool, ) -> Option<TerminationReason>
Processes output from a hat execution.
Returns the termination reason if the loop should stop.
Sourcepub fn process_events_from_jsonl(&mut self) -> Result<bool>
pub fn process_events_from_jsonl(&mut self) -> Result<bool>
Processes events from JSONL and routes orphaned events to Ralph.
Also handles backpressure for malformed JSONL lines by:
- Emitting
event.malformedsystem events for each parse failure - Tracking consecutive failures for termination check
- Resetting counter when valid events are parsed
Returns true if Ralph should be invoked to handle orphaned events.
Sourcepub fn check_ralph_completion(&self, output: &str) -> bool
pub fn check_ralph_completion(&self, output: &str) -> bool
Checks if output contains LOOP_COMPLETE from Ralph.
Only Ralph can trigger loop completion. Hat outputs are ignored.
Sourcepub fn publish_terminate_event(&mut self, reason: &TerminationReason) -> Event
pub fn publish_terminate_event(&mut self, reason: &TerminationReason) -> Event
Publishes the loop.terminate system event to observers.
Per spec: “Published by the orchestrator (not agents) when the loop exits.” This is an observer-only event—hats cannot trigger on it.
Returns the event for logging purposes.
Sourcepub fn telegram_shutdown_flag(&self) -> Option<Arc<AtomicBool>>
pub fn telegram_shutdown_flag(&self) -> Option<Arc<AtomicBool>>
Returns the Telegram service’s shutdown flag, if active.
Signal handlers can set this flag to interrupt wait_for_response()
without waiting for the full timeout.
Sourcepub fn telegram_service(&self) -> Option<&TelegramService>
pub fn telegram_service(&self) -> Option<&TelegramService>
Returns a reference to the Telegram service, if active.
Sourcepub fn telegram_service_mut(&mut self) -> Option<&mut TelegramService>
pub fn telegram_service_mut(&mut self) -> Option<&mut TelegramService>
Returns a mutable reference to the Telegram service, if active.
Sourcepub fn check_for_user_prompt(&self, events: &[Event]) -> Option<UserPrompt>
pub fn check_for_user_prompt(&self, events: &[Event]) -> Option<UserPrompt>
Check if any event is a user.prompt event.
Returns the first user prompt event found, or None.
Auto Trait Implementations§
impl Freeze for EventLoop
impl !RefUnwindSafe for EventLoop
impl Send for EventLoop
impl !Sync for EventLoop
impl Unpin for EventLoop
impl !UnwindSafe for EventLoop
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Erasable for T
impl<T> Erasable for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more