1#![cfg_attr(
18 test,
19 allow(
20 dead_code,
21 unused_imports,
22 clippy::expect_used,
23 clippy::large_futures,
24 clippy::needless_borrow,
25 clippy::panic,
26 clippy::redundant_closure_for_method_calls,
27 clippy::redundant_clone,
28 clippy::type_complexity,
29 clippy::unnecessary_to_owned,
30 clippy::unwrap_used
31 )
32)]
33
34#[cfg(target_arch = "wasm32")]
35pub mod tokio {
36 pub use tokio_with_wasm::alias::*;
37}
38
39#[cfg(not(target_arch = "wasm32"))]
40pub use ::tokio;
41
42pub mod accept;
43pub mod auth_machine;
44pub mod coalescing;
45pub mod comms_bridge;
46pub mod comms_drain;
47pub mod comms_trust_reconcile;
48pub mod completion;
49pub mod composition;
50pub(crate) mod control_plane;
51pub mod driver;
52pub(crate) mod effect;
53#[doc(hidden)]
54pub mod generated;
55pub mod handles;
56pub mod identifiers;
57pub mod ingress_types;
58pub mod input;
59pub mod input_ledger;
60pub mod input_scope;
61pub mod input_state;
62pub mod interrupt_public_result;
63pub mod meerkat_machine;
64pub(crate) mod meerkat_machine_types;
65pub mod mob_adapter;
66pub mod mob_operator_authority;
67pub mod ops_lifecycle;
68pub mod peer_handling_mode;
69pub mod policy;
70pub mod policy_table;
71#[allow(unused_imports)]
72#[path = "generated/protocol_auth_lease_lifecycle_publication.rs"]
73pub mod protocol_auth_lease_lifecycle_publication;
74#[allow(unused_imports)]
75#[path = "generated/protocol_auth_release_oauth_flow_drain.rs"]
76pub mod protocol_auth_release_oauth_flow_drain;
77#[allow(unused_imports)]
78#[path = "generated/protocol_comms_trust_reconcile.rs"]
79pub mod protocol_comms_trust_reconcile;
80#[allow(unused_imports)]
81#[path = "generated/protocol_supervisor_trust_publish.rs"]
82pub mod protocol_supervisor_trust_publish;
83#[allow(unused_imports)]
84#[path = "generated/protocol_supervisor_trust_revoke.rs"]
85pub mod protocol_supervisor_trust_revoke;
86pub mod queue;
87pub mod runtime_event;
88pub(crate) mod runtime_loop;
89pub mod runtime_state;
90pub mod service_ext;
91pub(crate) mod silent_intent;
92pub mod store;
93pub mod traits;
94
95use meerkat_core::lifecycle::run_primitive::RuntimeTurnMetadata as RuntimeStampedTurnMetadata;
96use std::any::Any;
97use std::sync::Arc;
98
99struct SessionRuntimeBindingsAuthority;
100
101pub(crate) fn session_runtime_bindings_authority() -> Arc<dyn Any + Send + Sync> {
102 Arc::new(SessionRuntimeBindingsAuthority)
103}
104
105pub(crate) fn local_session_runtime_bindings_authority() -> Arc<dyn Any + Send + Sync> {
106 session_runtime_bindings_authority()
107}
108
109pub fn session_runtime_bindings_have_machine_authority(
110 bindings: &meerkat_core::SessionRuntimeBindings,
111) -> bool {
112 bindings
113 .__runtime_authority()
114 .is::<SessionRuntimeBindingsAuthority>()
115}
116
117pub use accept::{AcceptOutcome, RejectReason};
119pub use coalescing::{
120 AggregateDescriptor, CoalescingResult, SupersessionScope, check_supersession,
121 create_aggregate_input, is_coalescing_eligible,
122};
123pub use completion::{
124 CompletionCleanupObservation, CompletionHandle, CompletionOutcome, CompletionWaitError,
125};
126pub use driver::{EphemeralRuntimeDriver, PersistentRuntimeDriver, PostAdmissionSignal};
127pub use handles::{
128 HandleDslAuthority, RuntimeAuthLeaseHandle, RuntimeCommsDrainHandle,
129 RuntimeExternalToolSurfaceHandle, RuntimeInteractionStreamHandle,
130 RuntimeMcpServerLifecycleHandle, RuntimeModelRoutingHandle, RuntimePeerCommsHandle,
131 RuntimePeerInteractionHandle, RuntimeSessionAdmissionHandle, RuntimeSessionContextHandle,
132 RuntimeTurnStateHandle,
133};
134pub use identifiers::{
135 CausationId, ConversationId, CorrelationId, EventCodeId, IdempotencyKey, InputKind, KindId,
136 LogicalRuntimeId, PolicyVersion, ProjectionRuleId, RuntimeEventId, SchemaId, SupersessionKey,
137};
138pub use ingress_types::{ContentShape, RequestId, ReservationKey};
139pub use input::{
140 ContinuationInput, ContinuationKind, ExternalEventInput, FlowStepInput, Input, InputDurability,
141 InputHeader, InputOrigin, InputVisibility, OperationInput, PeerConvention, PeerInput,
142 PromptInput, ResponseProgressPhase, ResponseTerminalStatus, peer_response_terminal_input,
143 response_terminal_status_from_wire,
144};
145pub use input_ledger::InputLedger;
146pub use input_scope::InputScope;
147pub use input_state::{
148 InputAbandonReason, InputLifecycleState, InputState, InputStateEvent, InputStateHistoryEntry,
149 InputTerminalOutcome, PolicySnapshot, ReconstructionSource,
150};
151pub use meerkat_core::types::HandlingMode;
152pub use meerkat_machine::{
153 CommsDrainMode, CommsDrainPhase, DrainExitReason, MachineSessionControlAuthority,
154 MeerkatConsumerSurface, MeerkatMachine, PeerIngressOwner, RuntimeBindingsError,
155 RuntimeLifecycleFacts, RuntimeLoopQueueAdmissionPlan, classify_runtime_lifecycle_state,
156 classify_runtime_loop_queue_admission, standalone_tool_visibility_owner,
157};
158pub use meerkat_machine_types::{
159 HydratedSessionLlmState, ImageOperationRoutingRequest, ImageOperationRoutingResult,
160 ModelRoutingApprovalDisposition, ModelRoutingRealtimePolicy, ResolvedSessionLlmReconfigure,
161 SessionLlmCapabilitySurface, SessionLlmCapabilitySurfaceStatus, SessionLlmReconfigureHost,
162 SessionLlmReconfigureReport, SessionLlmReconfigureRequest, SessionToolVisibilityDelta,
163};
164#[doc(hidden)]
165pub use meerkat_machine_types::{
166 MeerkatAdmittedInputSnapshot, MeerkatArchiveSnapshot, MeerkatBindingSnapshot,
167 MeerkatCompletionWaiterSnapshot, MeerkatCompletionWaitersSnapshot, MeerkatControlSnapshot,
168 MeerkatCursorSnapshot, MeerkatDrainSnapshot, MeerkatDriverKind, MeerkatInputsSnapshot,
169 MeerkatMachineCatalogInput, MeerkatMachineCommandClassification,
170 MeerkatMachineCommandClassificationRecord, MeerkatMachineCommandVariant,
171 MeerkatMachineFieldlessRuntimeInternalInput, MeerkatMachineRuntimeInternalClassificationRecord,
172 MeerkatMachineRuntimeInternalInput, MeerkatMachineRuntimeInternalReason,
173 MeerkatMachineShellMechanicReason, MeerkatMachineSpineSnapshot, MeerkatOpsSnapshot,
174 canonical_meerkat_machine_command_classifications,
175 canonical_meerkat_machine_command_input_variant_manifest,
176 canonical_meerkat_machine_command_manifest,
177 canonical_meerkat_machine_runtime_internal_classifications,
178 canonical_meerkat_machine_runtime_internal_fieldless_input_variant_manifest,
179 canonical_meerkat_machine_runtime_internal_input_variant_manifest,
180 canonical_meerkat_machine_runtime_internal_manifest,
181};
182pub use ops_lifecycle::{
183 OpsLifecycleConfig, OpsLifecyclePersistenceRequest, PersistedOpsSnapshot,
184 RuntimeOpsLifecycleRegistry,
185};
186
187#[cfg(all(not(target_arch = "wasm32"), any(test, feature = "test-support")))]
188#[doc(hidden)]
189pub fn test_peer_comms_handle() -> Arc<dyn meerkat_core::handles::PeerCommsHandle> {
190 test_peer_comms_handle_with_silent(std::iter::empty::<String>())
191}
192
193#[cfg(all(not(target_arch = "wasm32"), any(test, feature = "test-support")))]
194#[doc(hidden)]
195#[allow(clippy::expect_used)]
196pub fn test_peer_comms_handle_with_silent<I, S>(
197 silent_intents: I,
198) -> Arc<dyn meerkat_core::handles::PeerCommsHandle>
199where
200 I: IntoIterator<Item = S>,
201 S: Into<String>,
202{
203 let silent_intents = silent_intents
204 .into_iter()
205 .map(Into::into)
206 .collect::<Vec<_>>();
207 std::thread::spawn(move || {
208 let runtime = tokio::runtime::Builder::new_current_thread()
209 .enable_all()
210 .build()
211 .expect("test peer-comms runtime should build");
212 runtime.block_on(async move {
213 let machine = MeerkatMachine::ephemeral();
214 let session_id = meerkat_core::SessionId::new();
215 let bindings = machine
216 .prepare_bindings(session_id.clone())
217 .await
218 .expect("generated MeerkatMachine should prepare test peer-comms bindings");
219 if !silent_intents.is_empty() {
220 machine
221 .set_session_silent_intents(&session_id, silent_intents)
222 .await
223 .expect("set silent intents");
224 }
225 Arc::clone(bindings.peer_comms())
226 })
227 })
228 .join()
229 .expect("test peer-comms authority thread should finish")
230}
231
232#[cfg(all(not(target_arch = "wasm32"), any(test, feature = "test-support")))]
233#[doc(hidden)]
234#[allow(clippy::expect_used)]
235pub fn test_peer_input_candidate_from_interaction(
236 interaction: meerkat_core::interaction::InboxInteraction,
237 peer_id: meerkat_core::comms::PeerId,
238) -> meerkat_core::interaction::PeerInputCandidate {
239 use meerkat_core::interaction::{
240 InteractionContent, InteractionId, PeerIngressEnvelopeFacts, PeerIngressEnvelopeKind,
241 PeerIngressFact, PeerIngressIdentity,
242 };
243
244 let handle = test_peer_comms_handle();
245 let facts = PeerIngressEnvelopeFacts {
246 item_id: interaction.id.to_string(),
247 from_peer: interaction.from.clone(),
248 from_peer_id: peer_id,
249 kind: match &interaction.content {
250 InteractionContent::Message { body, .. } => {
251 PeerIngressEnvelopeKind::Message { body: body.clone() }
252 }
253 InteractionContent::Request { intent, params, .. } => {
254 PeerIngressEnvelopeKind::Request {
255 intent: intent.clone(),
256 params: params.clone(),
257 }
258 }
259 InteractionContent::Response {
260 in_reply_to,
261 status,
262 result,
263 ..
264 } => PeerIngressEnvelopeKind::Response {
265 in_reply_to: in_reply_to.to_string(),
266 status: *status,
267 result: result.clone(),
268 },
269 },
270 };
271 let admission = handle
272 .classify_external_envelope(facts)
273 .expect("generated peer-comms authority should classify test interaction");
274 let canonical_from_peer_id = admission
277 .from_peer_id
278 .expect("generated envelope classification should echo the canonical sender peer id");
279 let classification = admission.classification;
280 let convention = match &interaction.content {
281 InteractionContent::Message { .. } => meerkat_core::PeerIngressConvention::Message,
282 InteractionContent::Request { intent, .. } => {
283 if let Some(kind) = classification.lifecycle_kind {
284 let peer = admission
285 .lifecycle_peer
286 .clone()
287 .expect("generated lifecycle classification should include a peer subject");
288 meerkat_core::PeerIngressConvention::Lifecycle { kind, peer }
289 } else {
290 let request_id = admission
291 .request_id
292 .clone()
293 .expect("generated request classification should include request id");
294 meerkat_core::PeerIngressConvention::Request {
295 request_id,
296 intent: intent.clone(),
297 }
298 }
299 }
300 InteractionContent::Response { status, .. } => {
301 let in_reply_to = admission
302 .request_id
303 .as_deref()
304 .and_then(|id| uuid::Uuid::parse_str(id).ok())
305 .map(InteractionId)
306 .expect("generated response classification should include in-reply-to id");
307 meerkat_core::PeerIngressConvention::Response {
308 in_reply_to,
309 status: *status,
310 }
311 }
312 };
313 let ingress = PeerIngressFact::peer(
314 interaction.id,
315 classification.class,
316 classification.kind,
317 Some(classification.auth),
318 PeerIngressIdentity::new(canonical_from_peer_id, interaction.from.clone(), convention),
319 );
320 let mut candidate = meerkat_core::interaction::PeerInputCandidate::new(
321 interaction,
322 ingress,
323 admission.lifecycle_peer,
324 );
325 candidate.response_terminality = classification.response_terminality;
326 candidate
327}
328
329pub fn runtime_stamped_prompt_turn_metadata(
336 metadata: Option<RuntimeStampedTurnMetadata>,
337) -> RuntimeStampedTurnMetadata {
338 let input = Input::Prompt(PromptInput::from_content_input(
339 meerkat_core::ContentInput::Text(String::new()),
340 metadata,
341 ));
342 let semantics = runtime_prompt_semantics_from_machine(&input);
343 runtime_loop::for_input(&input, semantics)
344}
345
346#[allow(clippy::expect_used)]
347fn runtime_prompt_semantics_from_machine(input: &Input) -> ingress_types::RuntimeInputSemantics {
348 let mut authority = meerkat_machine::dsl_authority::new_initialized_authority(
349 "generated runtime prompt machine authority must initialize",
350 );
351 let transition = meerkat_machine::dsl::MeerkatMachineMutator::apply(
352 &mut authority,
353 meerkat_machine::dsl::MeerkatMachineInput::ResolveAdmissionPlan {
354 input_id: input.id().to_string(),
355 input_kind: meerkat_machine::dsl::AdmissionInputKind::from(input.kind()),
356 requested_lane: input
357 .handling_mode()
358 .map(meerkat_machine::dsl::InputLane::from),
359 continuation_kind: meerkat_machine::dsl::AdmissionContinuationKind::from(
360 input.continuation_kind(),
361 ),
362 silent_intent_match: false,
363 existing_superseded_input_id: None,
364 runtime_running: false,
365 active_turn_boundary_available: false,
366 without_wake: false,
367 },
368 )
369 .expect("generated admission authority must accept runtime prompt metadata");
370
371 transition
372 .into_effects()
373 .into_iter()
374 .find_map(|effect| match effect {
375 meerkat_machine::dsl::MeerkatMachineEffect::AdmissionResolved {
376 runtime_boundary,
377 runtime_execution_kind,
378 runtime_peer_response_terminal_apply_intent,
379 live_interrupt_required,
380 ..
381 } => Some(ingress_types::RuntimeInputSemantics {
382 boundary: runtime_boundary.into(),
383 execution_kind: runtime_execution_kind.into(),
384 execution_handling_mode: None,
385 peer_response_terminal_apply_intent: runtime_peer_response_terminal_apply_intent
386 .map(Into::into),
387 live_interrupt_required,
388 }),
389 _ => None,
390 })
391 .expect("generated admission authority must emit prompt runtime semantics")
392}
393
394#[cfg(test)]
395mod runtime_prompt_metadata_tests {
396 #[test]
397 fn runtime_stamped_prompt_turn_metadata_uses_generated_prompt_semantics() {
398 let metadata = super::runtime_stamped_prompt_turn_metadata(None);
399 assert_eq!(
400 metadata.execution_kind,
401 Some(meerkat_core::lifecycle::RuntimeExecutionKind::ContentTurn)
402 );
403 assert!(metadata.peer_response_terminal_apply_intent.is_none());
404 }
405}
406
407#[doc(hidden)]
408pub mod machine_schema_exports {
409 pub fn meerkat_machine_schema() -> meerkat_machine_schema::MachineSchema {
410 meerkat_machine_schema::catalog::dsl::meerkat_machine_schema_metadata()
411 .attach_to(crate::meerkat_machine::dsl::MeerkatMachineState::schema())
412 }
413
414 pub fn auth_machine_schema() -> meerkat_machine_schema::MachineSchema {
415 meerkat_machine_schema::catalog::dsl::auth_machine_schema_metadata()
416 .attach_to(crate::auth_machine::dsl::AuthMachineState::schema())
417 }
418}
419pub use interrupt_public_result::{
420 UserInterruptObservation, UserInterruptPublicResult, resolve_user_interrupt_public_result,
421};
422pub use peer_handling_mode::{PeerHandlingModeError, validate_peer_handling_mode};
423pub use policy::{
424 ApplyMode, ConsumePoint, DrainPolicy, PolicyDecision, QueueMode, RoutingDisposition, WakeMode,
425};
426pub use policy_table::{DefaultPolicyTable, generated_default_policy_version};
427pub use queue::InputQueue;
428pub use runtime_event::{
429 InputLifecycleEvent, RunLifecycleEvent, RuntimeEvent, RuntimeEventEnvelope,
430 RuntimeProjectionEvent, RuntimeStateChangeEvent, RuntimeTopologyEvent,
431};
432pub use runtime_state::{RuntimeState, RuntimeStateTransitionError};
433pub use service_ext::SessionServiceRuntimeExt;
434pub use store::{InMemoryRuntimeStore, RuntimeStore, RuntimeStoreError, SessionDelta};
435pub use traits::{
436 DestroyReport, RecoveryReport, RecycleReport, ResetReport, RetireReport, RuntimeControlPlane,
437 RuntimeControlPlaneError, RuntimeDriver, RuntimeDriverError,
438};