Skip to main content

Component

Trait Component 

Source
pub trait Component: Send + Sync {
Show 17 methods // Required methods fn id(&self) -> &ComponentId; fn status(&self) -> Status; fn on_request(&mut self, request: &Request) -> Result<Value, ComponentError>; fn on_signal(&mut self, signal: &Signal) -> SignalResponse; fn abort(&mut self); // Provided methods fn subscriptions(&self) -> &[EventCategory] { ... } fn subscription_entries(&self) -> Vec<SubscriptionEntry> { ... } fn status_detail(&self) -> Option<StatusDetail> { ... } fn init(&mut self, _config: &Value) -> Result<(), ComponentError> { ... } fn shutdown(&mut self) { ... } fn runtime_hints(&self) -> RuntimeHints { ... } fn as_packageable(&self) -> Option<&dyn Packageable> { ... } fn as_packageable_mut(&mut self) -> Option<&mut dyn Packageable> { ... } fn set_emitter(&mut self, _emitter: Box<dyn Emitter>) { ... } fn set_child_context(&mut self, _ctx: Box<dyn ChildContext>) { ... } fn snapshot(&self) -> Result<ComponentSnapshot, SnapshotError> { ... } fn restore( &mut self, _snapshot: &ComponentSnapshot, ) -> Result<(), SnapshotError> { ... }
}
Expand description

Component trait for EventBus participants.

Components are the primary actors in the ORCS system. They communicate via the EventBus using Request/Response patterns.

§Required Methods

MethodPurpose
idComponent identification
statusCurrent execution status
subscriptionsEvent categories to receive
on_requestHandle incoming requests
on_signalHandle control signals
abortImmediate termination

§Subscription-based Routing

Components declare which EventCategory they subscribe to. The EventBus routes requests only to subscribers of the matching category.

Component::subscriptions() -> [Hil, Echo]
    │
    ▼
EventBus::register(component, categories)
    │
    ▼
Request { category: Hil, operation: "submit" }
    │
    ▼ (routed only to Hil subscribers)
HilComponent::on_request()

§Signal Handling Contract

Components must handle signals, especially:

  • Veto: Must abort immediately
  • Cancel: Must check scope and abort if applicable

This is the foundation of “Human as Superpower” - humans can always interrupt any operation.

§Thread Safety

Components must be Send + Sync for concurrent access. Use interior mutability patterns if needed.

Required Methods§

Source

fn id(&self) -> &ComponentId

Returns the component’s identifier.

Used for:

  • Request routing
  • Signal scope checking
  • Logging and debugging
Source

fn status(&self) -> Status

Returns the current execution status.

Called by the engine to monitor component health.

Source

fn on_request(&mut self, request: &Request) -> Result<Value, ComponentError>

Handle an incoming request.

Called when a request is routed to this component.

§Arguments
  • request - The incoming request
§Returns
  • Ok(Value) - Successful response payload
  • Err(ComponentError) - Operation failed
§Example Operations
ComponentOperations
LLMchat, complete, embed
Toolsread, write, edit, bash
HILapprove, reject
Source

fn on_signal(&mut self, signal: &Signal) -> SignalResponse

Handle an incoming signal.

Signals are highest priority - process immediately.

§Required Handling
  • Veto: Must call abort() and return Abort
  • Cancel (in scope): Should abort
  • Other: Check relevance and handle or ignore
§Returns
  • Handled: Signal was processed
  • Ignored: Signal not relevant
  • Abort: Component is stopping
Source

fn abort(&mut self)

Immediate abort.

Called on Veto signal. Must:

  • Stop all ongoing work immediately
  • Cancel pending operations
  • Release resources
  • Set status to Aborted
§Contract

After abort():

  • Component will not receive more requests
  • Any pending responses should be dropped

Provided Methods§

Source

fn subscriptions(&self) -> &[EventCategory]

Returns the event categories this component subscribes to.

The EventBus routes requests only to components that subscribe to the request’s category.

§Default

Default implementation returns [Lifecycle] only. Override to receive requests from other categories.

§Example
fn subscriptions(&self) -> &[EventCategory] {
    &[EventCategory::Hil, EventCategory::Lifecycle]
}
Source

fn subscription_entries(&self) -> Vec<SubscriptionEntry>

Returns subscription entries with optional operation-level filtering.

This method enables fine-grained subscription control. Components can declare not only which categories they subscribe to, but also which operations within those categories they accept.

The default implementation wraps subscriptions() with wildcard operations (all operations accepted per category).

§Example
fn subscription_entries(&self) -> Vec<SubscriptionEntry> {
    vec![
        SubscriptionEntry::all(EventCategory::UserInput),
        SubscriptionEntry::with_operations(
            EventCategory::extension("lua", "Extension"),
            ["route_response".to_string()],
        ),
    ]
}
Source

fn status_detail(&self) -> Option<StatusDetail>

Returns detailed status information.

Optional - returns None by default. Override for UI display or debugging.

Source

fn init(&mut self, _config: &Value) -> Result<(), ComponentError>

Initialize the component with optional configuration.

Called once before the component receives any requests. The config parameter contains per-component settings from [components.settings.<name>] in the config file. Default implementation ignores the config.

§Errors

Return Err if initialization fails. The component will not be registered with the EventBus.

Source

fn shutdown(&mut self)

Shutdown the component.

Called when the engine is stopping. Default implementation does nothing.

Should:

  • Clean up resources
  • Persist state if needed
  • Cancel background tasks
Source

fn runtime_hints(&self) -> RuntimeHints

Returns runtime hints for this component.

The Runtime uses these hints to configure channel spawning:

  • output_to_io: route Output events to the IO channel
  • elevated: use an elevated auth session
  • child_spawner: enable child spawning capability
§Default

All hints are false (most restrictive).

Source

fn as_packageable(&self) -> Option<&dyn Packageable>

Returns this component as a Packageable if supported.

Override this method in components that implement Packageable to enable package management.

§Default

Returns None - component does not support packages.

Source

fn as_packageable_mut(&mut self) -> Option<&mut dyn Packageable>

Returns this component as a mutable Packageable if supported.

Override this method in components that implement Packageable to enable package installation/uninstallation.

§Default

Returns None - component does not support packages.

Source

fn set_emitter(&mut self, _emitter: Box<dyn Emitter>)

Sets the event emitter for this component.

The emitter allows the component to emit events to:

  • The owning Channel (for IO output)
  • All Components (via signal broadcast)

Called by ClientRunner during component initialization.

§Default

Default implementation does nothing. Override if your component needs to emit events.

§Example
fn set_emitter(&mut self, emitter: Box<dyn Emitter>) {
    self.emitter = Some(emitter);
}

// Later, emit output
if let Some(emitter) = &self.emitter {
    emitter.emit_output("Result: success");
}
Source

fn set_child_context(&mut self, _ctx: Box<dyn ChildContext>)

Sets the child context for this component.

Override this method if your component needs to spawn children.

§Default

No-op - component does not use child context.

Source

fn snapshot(&self) -> Result<ComponentSnapshot, SnapshotError>

Captures the component’s current state as a snapshot.

Override this method to enable session persistence for your component. The snapshot can later be restored via restore.

§Default

Returns NotSupported - component does not support snapshots.

§Example
fn snapshot(&self) -> Result<ComponentSnapshot, SnapshotError> {
    ComponentSnapshot::from_state(self.id.fqn(), &self.state)
}
Source

fn restore( &mut self, _snapshot: &ComponentSnapshot, ) -> Result<(), SnapshotError>

Restores the component’s state from a snapshot.

Override this method to enable session restoration for your component.

§Contract

Implementations must be idempotent: calling restore() multiple times with the same snapshot must produce the same result as calling it once. This is a trait-level guarantee that all implementations must uphold regardless of internal data structure (e.g., use insert/replace, not append).

§Default

Returns NotSupported - component does not support snapshots.

§Errors
  • SnapshotError::NotSupported - Component doesn’t support snapshots
  • SnapshotError::ComponentMismatch - Snapshot is for different component
  • SnapshotError::Serialization - Failed to deserialize state
§Example
fn restore(&mut self, snapshot: &ComponentSnapshot) -> Result<(), SnapshotError> {
    self.state = snapshot.to_state()?;
    Ok(())
}

Implementors§