Skip to main content

UnifiedRuntime

Struct UnifiedRuntime 

Source
pub struct UnifiedRuntime { /* private fields */ }

Implementations§

Source§

impl UnifiedRuntime

Source

pub async fn register_peer_mob(&self, mob_id: &str, handle: MobHandle)

Register an external mob’s handle for same-process cross-mob communication.

Source

pub fn set_contact_directory(&mut self, directory: ContactDirectory)

Set the contact directory for cross-mob address resolution.

Source

pub fn set_gateway_peer_keys(&mut self, keys: GatewayPeerKeys)

Install the long-lived Ed25519 keypair this gateway advertises via mobkit/peer_pubkey and (when meerkat-comms grows out-of-process transports) signs outbound envelopes with.

Inproc-only deployments and most tests skip this — the in-process router authorises by identity map and signature verification is moot. Production gateways and any cross-process integration test must call this.

Source

pub fn gateway_peer_keys(&self) -> Option<&GatewayPeerKeys>

Borrow the local gateway keypair if one was installed.

Source

pub async fn wire_cross_mob( &self, local_member_id: &str, remote_member_id: &str, remote_mob_id: &str, ) -> Result<(), CrossMobError>

Wire a local member to a member in an external mob.

Resolves both members’ peer IDs from roster entries, builds peer specs using the transport scheme advertised by the contact directory entry (inproc, tcp, or uds), and registers the peer on both sides to establish bidirectional trust.

§Local vs remote dispatch

The destination mob is dispatched as either [LocalOrRemote::Local] (when an Arc<MobHandle> was registered via Self::register_peer_mob) or [LocalOrRemote::Remote] (when only a contact-directory TCP/UDS entry exists). Phase 1 ships the structural seam; Phase 2 wires the real cross-process control RPC — see runtime::cross_mob_remote::RemoteMobProxy.

Source

pub async fn unwire_cross_mob( &self, local_member_id: &str, remote_member_id: &str, remote_mob_id: &str, ) -> Result<(), CrossMobError>

Unwire a cross-mob peering.

Best-effort on both sides — attempts to unwire both the local and remote members. Partial cleanup is better than aborting after one side fails, which would leave asymmetric peering.

Source

pub async fn send_cross_mob( &self, from_local_member: &str, remote_member_id: &str, remote_mob_id: &str, content: impl Into<ContentInput>, ) -> Result<String, CrossMobError>

Inject a message into a remote mob member’s session.

This is an app-level injection — the remote agent receives the message as an external turn but does not know who sent it. For agent-to-agent communication with sender identity and reply path, use wire_cross_mob to set up peering, then agents communicate directly via their comms send tool.

from_local_member is recorded for audit/logging but does not affect delivery — the message is injected via the remote mob handle.

Source

pub fn list_external_mobs(&self) -> Vec<ContactEntry>

List external mobs from the contact directory.

Source

pub fn has_contact_directory(&self) -> bool

Whether a contact directory is configured (cross-mob operations available).

Source

pub async fn has_peer_mob_handles(&self) -> bool

Whether any peer mob handles are registered (required for high-level cross-mob wire/unwire/send).

Source

pub fn has_inproc_contacts(&self) -> bool

Whether the contact directory has any inproc entries.

Source

pub fn has_remote_contacts(&self) -> bool

Whether the contact directory has any cross-process (TCP/UDS) entries. Useful for opting into the remote-mob proxy code path.

Source

pub fn mob_id(&self) -> String

Return the local mob’s ID.

Source

pub async fn local_member_peer_info( &self, member_id: &str, ) -> Result<(String, String, String), CrossMobError>

Get comms peer info for a local member. Returns (peer_id, comms_name, address) — the address is always inproc://{comms_name} for local members. For cross-process peering, the caller should replace the address with the remote gateway’s TCP/UDS endpoint.

Source

pub async fn wire_local( &self, local_member_id: &str, remote_comms_name: &str, remote_peer_id: &str, remote_address: &str, remote_pubkey: Option<[u8; 32]>, ) -> Result<(), CrossMobError>

Wire a local member to an external peer using provided comms info. Only wires the local side — for the bidirectional wire, call this on both gateways.

remote_address is the comms transport address (e.g. "inproc://name" for same-process, "tcp://host:port" for cross-process). remote_pubkey is the peer gateway’s 32-byte Ed25519 verifying key. Inproc transports may pass None (the in-process router authorises by identity map). Non-inproc transports MUST supply a non-zero pubkey — this call fails closed with CrossMobError::MissingPeerPubkey otherwise so unsigned descriptors never reach a real transport.

Source

pub async fn unwire_local( &self, local_member_id: &str, remote_comms_name: &str, remote_peer_id: &str, remote_address: &str, remote_pubkey: Option<[u8; 32]>, ) -> Result<(), CrossMobError>

Undo a wire_local — unwire a local member from a previously wired peer. Only affects the local side; the remote side is left unchanged.

Source§

impl UnifiedRuntime

Source

pub async fn reconcile( &self, desired_specs: Vec<SpawnMemberSpec>, ) -> Result<UnifiedRuntimeReconcileReport, UnifiedRuntimeReconcileError>

Source

pub async fn reconcile_edges(&self) -> UnifiedRuntimeReconcileEdgesReport

Reconcile dynamic peer edges using fresh roster state.

Refreshes the roster, runs edge discovery if configured, diffs desired vs managed edges, and calls wire/unwire as needed.

Source§

impl UnifiedRuntime

Source§

impl UnifiedRuntime

Source

pub async fn rediscover( &self, ) -> Result<Option<RediscoverReport>, MobRuntimeError>

Reset the mob and re-run discovery + edge reconciliation.

Sequence:

  1. MobHandle::reset() — retires all members, clears projections, restarts MCP servers, returns mob to Running state
  2. Re-runs the stored Discovery (with Value::Null context since PreSpawnHook is consumed at boot and cannot be replayed)
  3. Spawns discovered members via spawn_many
  4. Clears managed dynamic edges (stale after reset)
  5. Runs edge reconciliation if EdgeDiscovery is configured

Returns None if no Discovery is configured (nothing to rediscover).

Source

pub async fn run<F>( &self, listener: TcpListener, decisions: RuntimeDecisionState, shutdown_signal: F, ) -> UnifiedRuntimeRunReport
where F: Future<Output = ()> + Send + 'static,

Source

pub async fn serve( &self, listener: TcpListener, decisions: RuntimeDecisionState, ) -> Result<()>

Source

pub fn spawn_event_drain_task(self: Arc<Self>) -> JoinHandle<()>

Spawn a detached task that periodically drains mob agent events and projects them onto the ConsoleEventStore. Returns a [JoinHandle] — callers that manage graceful shutdown should abort it before stopping the runtime.

Use this when embedding UnifiedRuntime inside a host-owned axum server (so Self::serve’s built-in drain loop isn’t running). Without this task the mob event router fills up, agent turns never reach the console SSE stream, and event-log consumers miss events.

Source

pub async fn shutdown(&self) -> UnifiedRuntimeShutdownReport

Source

pub async fn drain_mob_agent_events(&self) -> Result<(), UnifiedRuntimeError>

Drain pending agent/module events from the mob event router and project them onto the ConsoleEventStore + event log. Callers that embed UnifiedRuntime inside their own axum server (rather than using .serve()) must poll this periodically — typically via UnifiedRuntime::spawn_event_drain_task — or console/event-log consumers will never see agent responses.

Source

pub async fn dispatch_schedule_tick( &self, schedules: &[ScheduleDefinition], tick_ms: u64, ) -> Result<ScheduleDispatchReport, UnifiedRuntimeError>

Source§

impl UnifiedRuntime

Source

pub fn mob_handle(&self) -> MobHandle

Source

pub fn mob_runtime(&self) -> &MobRuntime

Access the underlying MobRuntime (owns the session service + ephemeral dir).

Source

pub async fn spawn( &self, spec: SpawnMemberSpec, ) -> Result<SpawnResult, MobRuntimeError>

Spawn a member, firing post_spawn_hook on success and the shared error hook on failure. For raw spawning without hooks, use mob_handle().spawn_spec(...).

Source

pub async fn spawn_many( &self, specs: Vec<SpawnMemberSpec>, ) -> Result<Vec<SpawnResult>, MobRuntimeError>

Spawn many members, firing post_spawn_hook once on success with all ids.

Source§

impl UnifiedRuntime

Source

pub async fn module_is_running(&self) -> bool

Source

pub async fn loaded_modules(&self) -> Vec<String>

Source

pub async fn reconcile_modules( &self, modules: Vec<String>, timeout: Duration, ) -> Result<usize, RuntimeMutationError>

Reconcile modules — runs blocking subprocess I/O via block_in_place.

Source

pub async fn resolve_routing( &self, request: RoutingResolveRequest, ) -> Result<RoutingResolution, RoutingResolveError>

Resolve routing — runs blocking MCP boundary call via block_in_place.

Source

pub async fn send_delivery( &self, request: DeliverySendRequest, ) -> Result<DeliveryRecord, DeliverySendError>

Send delivery — runs blocking MCP boundary call via block_in_place.

Source

pub async fn evaluate_schedule_tick( &self, schedules: &[ScheduleDefinition], tick_ms: u64, ) -> Result<ScheduleEvaluation, ScheduleValidationError>

Source

pub async fn list_runtime_routes(&self) -> Vec<RuntimeRoute>

Source

pub async fn add_runtime_route( &self, route: RuntimeRoute, ) -> Result<RuntimeRoute, RuntimeRouteMutationError>

Source

pub async fn delete_runtime_route( &self, route_key: &str, ) -> Result<RuntimeRoute, RuntimeRouteMutationError>

Source

pub async fn delivery_history( &self, request: DeliveryHistoryRequest, ) -> DeliveryHistoryResponse

Source

pub async fn memory_stores(&self) -> Vec<MemoryStoreInfo>

Source

pub async fn memory_index( &self, request: MemoryIndexRequest, ) -> Result<MemoryIndexResult, MemoryIndexError>

Source

pub async fn memory_query( &self, request: MemoryQueryRequest, ) -> MemoryQueryResult

Source

pub async fn evaluate_gating_action( &self, request: GatingEvaluateRequest, ) -> GatingEvaluateResult

Source

pub async fn list_gating_pending(&self) -> Vec<GatingPendingEntry>

Source

pub async fn decide_gating_action( &self, request: GatingDecideRequest, ) -> Result<GatingDecisionResult, GatingDecideError>

Source

pub async fn gating_audit_entries(&self, limit: usize) -> Vec<GatingAuditEntry>

Source

pub async fn spawn_member( &self, module_id: &str, timeout: Duration, ) -> Result<(), RuntimeMutationError>

Spawn a module member — runs blocking subprocess I/O via block_in_place.

Source

pub async fn route_module_call( &self, request: &ModuleRouteRequest, timeout: Duration, ) -> Result<ModuleRouteResponse, ModuleRouteError>

Route a module call — runs blocking MCP boundary call via block_in_place.

Source

pub async fn module_lifecycle_events(&self) -> Vec<LifecycleEvent>

Source

pub async fn module_health_transitions(&self) -> Vec<ModuleHealthTransition>

Source

pub async fn module_events(&self) -> Vec<EventEnvelope<UnifiedEvent>>

Source

pub async fn subscribe_events( &self, request: SubscribeRequest, ) -> Result<SubscribeResponse, UnifiedRuntimeError>

Source§

impl UnifiedRuntime

Source

pub fn builder() -> UnifiedRuntimeBuilder

Source

pub async fn bootstrap( mob_spec: MobBootstrapSpec, module_config: MobKitConfig, timeout: Duration, ) -> Result<Self, UnifiedRuntimeBootstrapError>

Source

pub async fn bootstrap_with_options( mob_spec: MobBootstrapSpec, module_config: MobKitConfig, module_agent_events: Vec<EventEnvelope<UnifiedEvent>>, timeout: Duration, options: RuntimeOptions, persistent_metadata: Arc<dyn PersistentMetadataStore>, ) -> Result<Self, UnifiedRuntimeBootstrapError>

Source

pub async fn bootstrap_edges_report( &self, ) -> Option<UnifiedRuntimeReconcileEdgesReport>

Bootstrap edge reconciliation report, if edge discovery was configured.

Inspect after build() to detect incomplete startup topology. Returns None if no edge discovery was configured.

Source

pub fn set_error_hook(&mut self, hook: ErrorHook)

Register an error hook after construction. Useful when the runtime is built via bootstrap() rather than the builder.

Source

pub fn start_event_log(&mut self, config: EventLogConfig)

Start the event log ingestion engine. Must be called after construction (the builder calls this automatically when event_log config is provided).

Source

pub fn binary_blob_store(&self) -> Option<Arc<dyn BinaryBlobStore>>

Source

pub fn session_bridge(&self) -> Option<&Arc<dyn SessionBridge>>

Return the session bridge for identity-first operations, if configured.

Source

pub fn identity_first_context( &self, ) -> Option<&Arc<IdentityFirstRuntimeContext>>

Source

pub fn identity_runtime(&self) -> Option<&Arc<IdentityRuntime>>

Source

pub fn attach_identity_first_context( &mut self, context: Arc<IdentityFirstRuntimeContext>, )

Source

pub async fn refresh_desired_topology( &self, ) -> Result<Option<RestoreFlowResult>, IdentityRuntimeError>

Source

pub async fn materialize_identity_first_for_flow( &self, ) -> Result<Vec<ContinuityRecord>, IdentityRuntimeError>

Hydrate identity-first lazy members before handing control to concrete mob APIs that operate on already-materialized runtime members.

Source

pub fn metadata_table(&self) -> &Arc<RuntimeMetadataTable>

Return the mob/run label sidecar table.

Mobkit owns this table — meerkat-mob has no concept of mob- or run-level labels. Apps use it to attach external context (repo, branch, customer, deployment, environment) to a mob or a flow run.

Source

pub fn persistent_metadata(&self) -> &Arc<dyn PersistentMetadataStore>

Return the persistent metadata adapter — used by the structural-events subscription to checkpoint its last-projected cursor. Tests and integration code that need to inspect the persisted cursor reach through this accessor.

Source

pub async fn set_mob_labels(&self, labels: BTreeMap<String, String>)

Replace the label set associated with this mob.

An empty labels map clears the entry. Replacement is wholesale — existing labels not present in labels are dropped. To merge, read first via Self::get_mob_labels and combine.

Source

pub async fn get_mob_labels(&self) -> BTreeMap<String, String>

Return the label set associated with this mob, or an empty map.

Source

pub async fn delete_mob_labels(&self)

Remove the label set associated with this mob.

Source

pub async fn set_run_labels( &self, run_id: &str, labels: BTreeMap<String, String>, )

Replace the label set for run_id under this mob.

Source

pub async fn get_run_labels(&self, run_id: &str) -> BTreeMap<String, String>

Return the label set for run_id under this mob, or an empty map.

Source

pub async fn delete_run_labels(&self, run_id: &str)

Remove the label set for run_id under this mob.

Source

pub fn event_log_store(&self) -> Option<Arc<dyn EventLogStore>>

Return the underlying event log store if one is configured.

Used to share the store with sub-handlers (e.g. console RPC) that don’t hold a full UnifiedRuntime reference.

Source

pub fn console_log_store(&self) -> Arc<dyn ConsoleLogStore>

Source

pub fn set_console_log_store(&mut self, store: Arc<dyn ConsoleLogStore>)

Source

pub async fn query_mob_events( &self, query: &EventQuery, ) -> Result<Vec<MobStructuralEventEnvelope>, MobEventsQueryError>

Query structural mob events from the meerkat ledger.

Returns events filtered by EventQuery in cursor-ascending order. EventQuery::after_seq acts as the pagination cursor: the caller passes the highest cursor seen so far to receive only strictly-newer events. Without after_seq the call returns the latest matching events up to limit (default 256), scanning the ledger backwards from latest_cursor.

Errors propagate the typed mob_events::MobEventsQueryError so the JSON-RPC handler can surface StaleEventCursor as code -32010.

Source

pub fn subscribe_mob_events(&self) -> Receiver<MobStructuralEventEnvelope>

Subscribe to live structural mob events. Returns a broadcast receiver that yields each newly-projected envelope. The receiver will report RecvError::Lagged if it falls behind the in-memory channel cap.

Source

pub async fn reserve_identity_interaction( &self, identity: &str, runtime_member_id: Option<&str>, interaction_id: &str, origin: &str, content: Value, ) -> Result<(), &'static str>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,