Skip to main content

Engine

Struct Engine 

Source
pub struct Engine { /* private fields */ }
Expand description

The Keel kernel, Tier 1 scope. One per process; &self-concurrent.

A journal and/or discovery store are optional attachments: the engine is fully functional without either, and neither can change a call’s outcome — their I/O failures degrade to a warn! (resilience first, honest reporting).

Implementations§

Source§

impl Engine

Source

pub fn new() -> Self

Source

pub fn attach_journal(&mut self, journal: impl Journal + 'static) -> &mut Self

Attach a journal at construction time, enabling the persistent cache scope. Optional; set at setup, before the engine is shared for concurrent execute. A later configure whose policy carries a journal key replaces this attachment — the effective policy is authoritative (spec §4.2).

Source

pub fn journal(&self) -> Option<Arc<dyn Journal>>

The attached journal, if any — shared (Arc) so a FlowManager can run its Tier 2 steps over the same store the engine caches through. None for an in-memory engine (Tier 2 requires a durable journal). Live: a configure whose policy selects a journal location changes what this returns, so Tier 2 wiring should read it after the engine is configured.

Source

pub fn attach_discovery( &mut self, discovery: impl DiscoveryRecorder + 'static, ) -> &mut Self

Attach a discovery store; each execute then records one observation. Optional and failure-isolated — recording never affects an outcome.

Source

pub fn attach_events(&mut self, sink: EventSink) -> &mut Self

Attach (or replace) a live event sink. Engine::new already resolves one from the environment (see crate::events); this override exists for tests and embedders that place the feed elsewhere.

Source

pub fn events(&self) -> Option<&EventSink>

The active event sink, if any — its run id anchors this engine’s trace refs, and flush() makes the feed current for a same-process reader.

Source

pub fn configure(&self, policy_json: &Value) -> Result<(), KeelError>

Apply a policy document (keel.toml as JSON, per contracts/policy.schema.json), replacing the previous one atomically. Rejections are KEEL-E001 with the exact offending field path; a valid policy naming a journal backend this build cannot provide is KEEL-E005 (and the previous policy stays in force).

Source

pub fn telemetry_otlp_endpoint(&self) -> Option<String>

The effective telemetry.otlp_endpoint (None if [telemetry] is absent or the key unset), read live so a reconfigure is honored. Native front ends built with the otel feature read this after configure and pass it to [crate::otel::export_enabled] / [crate::otel::resolve_endpoint] to decide whether/where to export (env vars still take precedence).

Source

pub fn idempotency_header(&self, target: &str) -> Option<String>

The target’s resolved idempotency = { header } knob, read live so a reconfigure is honored. This is the engine surface of the injection contract (contracts/adapter-pack.md “Idempotency-key injection”): adapters/bindings consult it to mint and inject an idempotency key on unsafe-method calls — the engine itself never injects, and the flipped judgment reaches it as Request.idempotent = true.

Source

pub fn resolve_target( &self, method: &str, host: &str, scheme: Option<&str>, port: Option<u16>, path: Option<&str>, ) -> String

Resolve the policy target key for one outbound request — the engine surface of Policy::resolve_target (SP-1: LLM host map, exact bare-host [target] key, most-specific pattern match, then the bare host). Read live so a reconfigure is honored.

Source

pub fn layer(&self, target: &str, key: &str) -> Value

One resolved layer value as JSON (null when unset) — the front ends’ backend.layer(target, key) reader. Walks the RAW configured JSON (never a typed re-serialization) with the same precedence as Policy::resolve/the stubs’ _layer: an exact [target] entry for target, else (for llm:* targets) defaults.llm, else defaults.outbound, else null. Resolving over the raw document (rather than serializing the typed ResolvedPolicy) preserves the original config literal verbatim — e.g. "120s", not a re-serialized DurationMs number — which is what callers actually need; see DurationMs’s Deserialize-only impl (policy.rs).

Source

pub fn known_llm_hosts() -> Vec<(&'static str, &'static str)>

Every host the LLM host map knows about, as (host, provider) pairs — the engine surface of Policy::known_llm_hosts. Not read from self: the map is a hardcoded constant, identical regardless of which policy is configured, so this needs no live lock (issue #49).

Source

pub fn nondeterminism_response(&self) -> NondeterminismResponse

The configured Tier 2 flows.on_nondeterminism response (default NondeterminismResponse::Fail), read live so a reconfigure is honored. The flow manager consults this when a replay (seq, step_key) diverges.

Source

pub async fn execute<F>(&self, request: &Request, effect: F) -> Outcome

Run one intercepted call through the target’s layer chain, then record it for discovery. effect performs a single attempt (1-based attempt numbers). Always returns an Outcome — policy failures are outcomes, not panics, and neither journal nor discovery I/O can change what’s returned.

Source

pub fn report(&self) -> Value

Deterministic metrics/discovery report (sorted keys, no wall-clock timestamps): the same shape keel_report freezes in core-ffi.h.

Trait Implementations§

Source§

impl Debug for Engine

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Engine

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Engine

§

impl !RefUnwindSafe for Engine

§

impl !UnwindSafe for Engine

§

impl Send for Engine

§

impl Sync for Engine

§

impl Unpin for Engine

§

impl UnsafeUnpin for Engine

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> 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<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