FlowStack

Struct FlowStack 

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

The main flow plus its digressions, with push-on-trigger and resume-on-completion.

While a digression is active, governance — tool admission, postures and grounds, explain() — delegates to the active layer, and the main flow’s marking is untouched, so Resume::Previous resumes exactly where it left off. Driven by State and guards: model-free and deterministic.

A digression stays the active layer through the turn on which it completes, so that turn’s projection carries its closing instruction (the terminal stage’s posture — “hand off to a human now”), and its Resume policy applies at the next turn boundary. Without that, a digression that completes on its entry turn would never be seen at all.

Implementations§

Source§

impl FlowStack

Source

pub fn new(main: CompiledFlow, mode: Enforcement) -> FlowStack

A stack over a compiled main flow with no digressions yet.

Source

pub fn from_monitor(main: FlowMonitor) -> FlowStack

A stack whose main layer is an existing monitor (keeps its on_enter actions and mode). This is how a bare governed flow becomes the one governance object the control plane drives.

Source

pub fn with_overlay(self, overlay: Overlay) -> FlowStack

Add a digression.

Source

pub fn with_overlays( self, overlays: impl IntoIterator<Item = Overlay>, ) -> FlowStack

Add several digressions, in trigger-priority order.

Source

pub fn with_repair( self, step: impl Into<String>, policy: RepairPolicy, ) -> FlowStack

Attach a repair policy to a main-flow step.

Source

pub fn with_repairs( self, policies: impl IntoIterator<Item = (String, RepairPolicy)>, ) -> FlowStack

Attach repair policies keyed by main-flow step.

Source

pub fn with_correction( self, slot: impl Into<String>, clear: impl IntoIterator<Item = String>, ) -> FlowStack

Watch slot for corrections: when its value changes from one captured value to another, correction_flag(slot) is raised for that turn and clear keys are removed from state.

Raising the flag does nothing by itself. The main flow reacts through a Constraint::Reset gated on it, which un-latches the stages downstream of the slot so they run again with the corrected value. A Conversation lowers exactly that for every collected slot, clearing the confirmation of any commit stage it re-opens.

Source

pub fn with_corrections( self, corrections: impl IntoIterator<Item = (String, Vec<String>)>, ) -> FlowStack

Watch several slots; see with_correction.

Source

pub fn correction_policies(&self) -> &BTreeMap<String, Vec<String>>

The watched slots and the keys each correction clears.

Source

pub fn with_verbatim( self, step: impl Into<String>, text: impl Into<String>, ) -> FlowStack

Require step to say text word for word; see verbatim. The stack publishes the requirement while the step is active. Its completion guard must also require verbatim_flag(step), which a Conversation lowers for you.

Source

pub fn with_verbatims( self, texts: impl IntoIterator<Item = (String, String)>, ) -> FlowStack

Verbatim requirements keyed by step.

Source

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

The verbatim requirements keyed by step.

Source

pub fn with_timing( self, step: impl Into<String>, timing: VoiceTiming, ) -> FlowStack

Attach voice timing to a step (main flow or digression).

Source

pub fn with_timings( self, timings: impl IntoIterator<Item = (String, VoiceTiming)>, ) -> FlowStack

Attach voice timing keyed by step.

Source

pub fn timing_policies(&self) -> &BTreeMap<String, VoiceTiming>

The voice timing keyed by step.

Source

pub fn active_timing(&self, state: &State) -> VoiceTiming

The merged timing of the steps active right now in the driving layer (empty when none of them has timing, or the conversation is over).

Source

pub fn publish_timing(&self, state: &State)

Publish active_timing to VOICE_TIMING_KEY in state, where the runtime’s audio path, timers and turn lifecycle read it. Writes only on change; removes the key when no timing applies. The stack calls this itself after every turn and tool call; call it once when installing the stack.

Source

pub fn into_shared(self) -> Arc<Mutex<RawMutex, FlowStack>>

Wrap in a SharedFlowStack for shared ownership between the control lane (which advances it) and runtime accessors (which snapshot it).

Source

pub fn mode(&self) -> Enforcement

The enforcement mode (shared by every layer).

Source

pub fn overlays(&self) -> &[Overlay]

The digressions this stack can enter, in trigger-priority order.

Source

pub fn overlays_mut(&mut self) -> &mut [Overlay]

Mutable access to the digressions, for connect-time merges.

Source

pub fn repair_policies(&self) -> &BTreeMap<String, RepairPolicy>

The repair policies keyed by main-flow step.

Source

pub fn main(&self) -> &FlowMonitor

The main flow’s monitor, whether or not it is currently driving.

Source

pub fn current(&self) -> &FlowMonitor

The monitor currently driving — the active digression if any, else the main flow.

Source

pub fn active_overlay(&self) -> Option<&str>

The name of the driving digression, if one is suspending the main flow.

Source

pub fn overlay_path(&self) -> Vec<&str>

Every active digression, outermost first: a digression can itself be interrupted by another, which then drives until it completes.

Source

pub fn is_complete(&self) -> bool

Whether the conversation is finished (main complete, or a Terminate digression ran).

Source

pub fn is_terminated(&self) -> bool

Whether a Terminate digression ended the conversation. From then on the stack governs nothing: no active steps or postures, every tool denied. The runtime does not close the session by itself; the application reads this (or TERMINATED_STATE_KEY) and hangs up.

Source

pub fn on_interrupted(&mut self, state: &State)

Count a barge-in against every active main step and escalate those whose policy’s escalate_after_interruptions is reached. Called by the control plane when the user interrupts the model.

Source

pub fn on_tool_failed(&mut self, state: &State)

Count a failed (or timed-out) tool call against every active main step and escalate those whose policy’s escalate_after_tool_failures is reached.

Source

pub fn on_turn(&mut self, state: &State)

Advance one turn.

A digression that completed on the previous turn has had its closing turn projected; its resume policy applies now, and the turn then proceeds as if the main flow had been driving all along (a new digression may trigger, or the main flow advances). Otherwise: advance the active digression, enter a triggered one (suspending the main flow), or advance the main flow.

Source

pub fn on_tool_ok(&mut self, tool: &str, state: &State)

Record a successful tool call against the active layer. A no-op once the conversation has been terminated: nothing is governing, so there is no marking for the call to advance. (In Enforce the call is denied before it runs; in Observe it runs but must not move a flow that has ended.)

A tool can itself fire a reset (reset(..).when(called_ok(..))), so the main layer sheds the repair signals of whatever that un-latches, exactly as the main layer does at a turn boundary. Repair is tracked for the main flow only, so a digression just delegates.

Source

pub fn observe_tool(&mut self, tool: &str, ok: bool, state: &State)

Observe a tool call for conformance against the active layer (see FlowMonitor::observe_tool).

After termination nothing is advanced, but in Observe the call is still recorded as a deviation: a tool used after the conversation ended is exactly what that mode exists to catch, and the monitor cannot see it for itself because the denial is the stack’s, not the flow’s.

Source

pub fn admits_tool(&self, tool: &str, state: &State) -> Result<(), String>

Whether tool is admitted right now (delegates to the active layer). Every tool is denied once the conversation has been terminated.

Source

pub fn explain(&self, state: &State) -> FlowExplanation

Explain the active layer’s control-plane state. After termination: nothing active, nothing admitted, every tool blocked with the reason — the conversation is over, so it is waiting for nothing. To ask instead what it never finished, read main(): its marking and unmet_requirements() are kept intact for exactly that audit.

Source

pub fn marking(&self) -> &Marking

The active layer’s marking (the last driving layer’s, after termination — kept for audit).

Source

pub fn active_steps(&self, state: &State) -> Vec<&Step>

Steps of the active layer that are eligible but not yet done. Empty after termination.

Source

pub fn active_postures(&self, state: &State) -> Vec<String>

Postures to project this turn: the active layer’s active steps’, or — on the turn a digression completes — its closing steps’ (see FlowMonitor::closing_postures). Empty after termination.

Source

pub fn active_grounds(&self, state: &State) -> Vec<String>

Grounding lines to project this turn, chosen like active_postures.

Source

pub fn unmet_requirements(&self) -> Vec<String>

The active layer’s unmet requirements. Empty after termination.

Source

pub fn take_newly_active(&mut self, state: &State) -> Vec<String>

Steps of the active layer that became active since the last call.

Source

pub fn enter_action(&self, step: &str) -> Option<&StepAction>

The on_enter action registered for a step of the active layer.

Source

pub fn set_posture(&mut self, step_id: &str, posture: Option<String>) -> bool

Replace a main-flow step’s posture. Returns true when the step exists.

Source

pub fn set_ground(&mut self, step_id: &str, ground: Option<String>) -> bool

Replace a main-flow step’s grounding template. Returns true when the step exists.

Trait Implementations§

Source§

impl Debug for FlowStack

Source§

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

Formats the value using the given formatter. Read more

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.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

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

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

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
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

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
§

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
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

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

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,