Skip to main content

SessionSpec

Struct SessionSpec 

Source
pub struct SessionSpec {
Show 29 fields pub name: String, pub version: String, pub description: String, pub instruction: String, pub greeting: Option<String>, pub modality: SpecModality, pub voice: Option<String>, pub tools: Vec<ToolSpec>, pub mcp: Vec<String>, pub extract: Vec<ExtractSpec>, pub models: ModelsSpec, pub decisions: BTreeMap<String, DecisionSpec>, pub code: Option<CodeSpec>, pub state: BTreeMap<String, StateFieldSpec>, pub computed: Vec<ComputedSpec>, pub memory: Option<MemorySpec>, pub runtime: Option<RuntimeSpec>, pub phases: Vec<PhaseSpec>, pub initial_phase: Option<String>, pub watch: Vec<WatchSpec>, pub patterns: Vec<PatternSpec>, pub fragments: BTreeMap<String, Flow>, pub use_fragments: Vec<UseFragment>, pub flow: Option<Flow>, pub conversation: Option<ConversationSpec>, pub skills: Vec<SkillSpec>, pub task_scenarios: Vec<TaskScenario>, pub scenarios: Vec<Scenario>, pub tests: Vec<SpecTest>,
}
Expand description

A complete Live session as one JSON document. See the module docs.

Fields§

§name: String

App name (display and registry identity).

§version: String

Spec version tag (freeform, e.g. “1” or “2025-08-24”).

§description: String

Human-readable description.

§instruction: String

Base system instruction.

§greeting: Option<String>

Optional greeting prompt — the model speaks first on connect.

§modality: SpecModality

Output modality. Defaults to text.

§voice: Option<String>

Voice name for audio sessions (e.g. “Puck”).

§tools: Vec<ToolSpec>

Declared tools (mock or HTTP-bound).

§mcp: Vec<String>

MCP toolset connection strings — the whole MCP ecosystem as this app’s tool library. Resolved at connect time.

§extract: Vec<ExtractSpec>

Out-of-band extraction pipelines.

§models: ModelsSpec

The models the spec runs on, by role.

§decisions: BTreeMap<String, DecisionSpec>

Questions a decision model (such as Jev) answers about the conversation, by id. Guards name them with the decided atom, and the runtime asks the ones the flow can act on at each decision point. Requires SpecResources::decision_model.

§code: Option<CodeSpec>

A code tool: the model runs a short Python program whose functions are the declared tools, each call governed like a direct call. Use it for reads the model would otherwise add up, sort or join itself.

§state: BTreeMap<String, StateFieldSpec>

Declared state keys — the session’s data dictionary.

§computed: Vec<ComputedSpec>

Computed (derived) state variables.

§memory: Option<MemorySpec>

Durable memory: slots projected into state, remember effects, and the ambient recall/manage tools. Requires a MemoryBinding in SpecResources at apply time.

§runtime: Option<RuntimeSpec>

Control-plane and voice tuning.

§phases: Vec<PhaseSpec>

Conversation phases.

§initial_phase: Option<String>

Initial phase name (required when phases is non-empty).

§watch: Vec<WatchSpec>

State watchers.

§patterns: Vec<PatternSpec>

Temporal patterns (sustained / consecutive-turn conditions).

§fragments: BTreeMap<String, Flow>

Reusable flow fragments, spliced via use_fragments.

§use_fragments: Vec<UseFragment>

Fragment splice directives.

§flow: Option<Flow>

The governed flow DAG (optional — a spec may be phases-only).

§conversation: Option<ConversationSpec>

The conversation: stages, slots, digressions, commits, timing and policies, compiled by the conversation compiler. The higher-level alternative to flow; set one or the other. Stage resolvers bind to the declared tools by name.

§skills: Vec<SkillSpec>

Reusable capabilities, each with task-private state and operations.

§task_scenarios: Vec<TaskScenario>

Model-free journeys through skill activation, approval and cancellation.

§scenarios: Vec<Scenario>

Scenarios run against conversation by SessionSpec::run_scenarios: model-free, deterministic.

§tests: Vec<SpecTest>

Embedded conformance tests, replayed offline by SessionSpec::run_tests.

Implementations§

Source§

impl SessionSpec

Source

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

The code tool’s name, when the spec has one.

Source

pub fn commit_tools(&self) -> BTreeSet<String>

The tools that commit: a conversation stage’s commit (main flow and overlays) and a flow’s commit steps.

Source

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

The tools a program can call: code.functions, or every declared tool except commits and background tools.

Source

pub fn compile_code_mode( &self, sandbox: Option<Arc<dyn CodeSandbox>>, ) -> Option<CodeMode>

The spec’s code tool, running programs in sandbox (in this process when None). None when the spec has no code.

Source§

impl SessionSpec

Source

pub fn to_rust(&self) -> String

The complete main.rs this spec is equivalent to.

Source

pub fn to_cargo_toml(&self) -> String

A Cargo.toml to pair with to_rust.

Source§

impl SessionSpec

Source

pub fn compile_decisions(&self, model: Arc<dyn DecisionModel>) -> Decisions

The decisions bank as the runtime’s Decisions, over model. Questions read outside a flow (phase transitions, patterns) are standing: asked at every caller turn.

Source§

impl SessionSpec

Source

pub fn to_project(&self, language: ProjectLanguage) -> Vec<ProjectFile>

A project in language that runs this spec. See the module docs for what each language generates.

Source

pub fn to_project_with( &self, language: ProjectLanguage, options: &ProjectOptions, ) -> Vec<ProjectFile>

to_project with options.

Source§

impl SessionSpec

Source

pub fn compile_tasks( &self, resources: &SpecResources, ) -> Result<TaskRuntime, String>

Compile local skill definitions into the runtime used by Live.

Source

pub async fn trace_tasks( &self, steps: &[TaskStep], ) -> Result<(Vec<TaskTraceSnapshot>, TaskSessionSnapshot), Vec<String>>

Replay commands with declared mock tools only. Attached implementations, HTTP bindings and MCP servers never execute in this path.

Source

pub async fn trace_tasks_with_resources( &self, steps: &[TaskStep], resources: &SpecResources, ) -> Result<(Vec<TaskTraceSnapshot>, TaskSessionSnapshot), Vec<String>>

Replay with explicitly supplied controlled memory services. Tool implementations and extraction providers remain disabled; a supplied memory binding executes its project/ingest/remember methods and must be an operator-controlled fixture.

Source

pub async fn run_task_scenarios(&self) -> Vec<ScenarioReport>

Run every declared task journey through the shared offline runtime.

Source§

impl SessionSpec

Source

pub fn uses_default_extraction_model(&self) -> bool

Whether some extraction (the spec’s or a skill’s extract entries) names no model, so it runs on the host’s extraction_llm.

Source

pub fn requires_extraction(&self) -> bool

Whether root or task definitions need an out-of-band extraction model.

Source

pub fn requires_memory(&self) -> bool

Whether root or task definitions use the contextual memory binding.

Source

pub fn from_value(value: Value) -> Result<Self, String>

Parse a spec from a JSON value. Accepts a full document or a bare flow ({"steps": [...]}), which is wrapped in a default spec.

Source

pub fn json_schema() -> Value

The JSON Schema of the spec document itself — for editor autocomplete and for validating machine-authored specs at generation time.

Source

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

Declared tool names (mock/HTTP; MCP names resolve at connect).

Source

pub fn effective_flow(&self) -> Result<Flow, Vec<String>>

The flow with every use_fragments directive spliced in.

Source

pub fn state_keys_written(&self) -> BTreeSet<String>

Every state key the session declares a writer for: tool set_state and save_response_as, extraction names and promotion targets, phase and watcher set effects.

Source

pub async fn run_scenarios(&self) -> Vec<ScenarioReport>

Run scenarios against the conversation, in order. Resolvers are stubbed: a scenario supplies their values with set steps.

Source

pub fn validate(&self) -> SpecValidation

Validate the whole document: flow compilation (with the declared tool registry), fragment splicing, phase-guard restrictions, HTTP-binding support, and the read/write state-key diff.

Source

pub fn validate_for_replay(&self) -> SpecValidation

Validate for scripted offline replay, where declared tools use mock effects and never open HTTP or MCP connections.

Checks the original document, including conflicting tool bindings. Only the requirement to compile HTTP transport support is omitted.

Source

pub fn build_dispatcher(&self, state: &State) -> ToolDispatcher

Build the dispatcher of declared tools bound to state.

Source

pub fn build_dispatcher_with( &self, state: &State, resources: &SpecResources, ) -> ToolDispatcher

Build the dispatcher of declared tools bound to state, calling the in-process implementations in resources where it has them. Tools bound to the same MCP server share one connection.

Source

pub fn run_tests(&self) -> Vec<TestReport>

Run the embedded test suite offline (no model, no network) — scripted events replayed through the real FlowStack. Includes installed skill workflow tests, named skill/test.

Source

pub fn sandboxed(&self, allow: &BindingAllowlist) -> (SessionSpec, Vec<String>)

A copy of this spec that reaches only what allow permits, and one note per binding it disabled.

mcp entries not in the allowlist are removed. A tool whose http binding is not allowed becomes a mock: it returns its canned response and still writes set_state, so the flow behaves the same way offline. Use this before apply on any spec you did not write, such as one posted by a browser.

Source

pub fn apply( &self, live: Live, state: &State, resources: &SpecResources, ) -> Result<Live, String>

Configure a Live builder from this spec.

state is the session state the declared tools bind to — pass the same one via .state (this method does). Returns an error when the spec fails validation or requires a resource resources lacks. Everything code-only (callbacks, custom guards, middleware) is added on the returned builder afterwards.

Tool bindings run as written. For a spec you did not write, call sandboxed first.

Trait Implementations§

Source§

impl Clone for SessionSpec

Source§

fn clone(&self) -> SessionSpec

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SessionSpec

Source§

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

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

impl Default for SessionSpec

Source§

fn default() -> SessionSpec

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

impl<'de> Deserialize<'de> for SessionSpec

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl JsonSchema for SessionSpec

Source§

fn schema_name() -> String

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
§

fn is_referenceable() -> bool

Whether JSON Schemas generated for this type should be re-used where possible using the $ref keyword. Read more
Source§

impl Serialize for SessionSpec

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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
§

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<T> CloneAny for T
where T: Any + Clone,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

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

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

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> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

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: Sized + 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: Sized + 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
§

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

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

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

§

fn to_sample_(self) -> U

§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
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