Expand description
Per-step runtime state for @step-annotated persona functions.
The compiler emits a call to the __register_step builtin after each
@step declaration so the runtime can dispatch on the step’s metadata
when its function is invoked. While a step’s frame is on the call
stack, an ActiveStep entry tracks per-step LLM usage, defaults
llm_call’s model when the call site doesn’t override it, and bounds
cumulative token and cost spend against the step’s budget.
This module owns three thread-locals (a per-program registry, a stack
of currently-active steps, and a log of completed step summaries) but
exposes only narrow helpers — current_active_step_* /
record_step_llm_usage / etc. — so the call sites in
crates/harn-vm/src/llm/, crates/harn-vm/src/vm/, and the compiler
stay focused.
Structs§
- Active
Context Snapshot - Active
Persona - Active
Step - Tracks one in-flight step. The
frame_depthisVm::frames.len()captured immediately afterpush_closure_framereturns, so anActiveStepis “alive” whileVm::frames.len() >= frame_depth. - Completed
Step - Snapshot persisted into [
COMPLETED_STEPS] when the step’s frame unwinds. Receipts andharn persona inspect-style downstream consumers read it back viadrain_completed_steps. - Persona
Definition - Persona
Hook Invocation - Persona
Hook Registration - Step
Definition - Static metadata captured from a
@step(...)attribute.
Enums§
Functions§
- active_
step_ frame_ depth - Frame depth of the topmost active step, or
Nonewhen no step is active. Used byhandle_errorto detect “this throw is exiting a step’s frame”. - active_
step_ model_ default - Default model the topmost active step should impose on
llm_callinvocations whose options dict didn’t pin a model. - clear_
persona_ hooks - completed_
step_ to_ json - Lower a
CompletedStepinto JSON for embedding in receipts / inspect output. - current_
persona_ name - drain_
completed_ steps - Drain the completed-step log. Used by receipt builders that want a per-step model + token + cost breakdown for the just-finished run.
- finish_
active_ step - is_
step_ budget_ exhausted - Returns true if the thrown value looks like a budget-exhausted
error — either our typed step-budget dict or the existing
crates/harn-vm/src/llm/cost.rs::budget_exceeded_errorshape. Either form is treated identically byerror_boundarybecause the per-step budget machinery layers onto the existing envelope; a step whose budget the preflight projection rejects is still a budget exhaustion the step authored. - is_
tracked_ function - mark_
escalated - Annotate an existing budget-exhausted error with
escalated: trueand the step’s identity so the persona body / handoff receiver can route on it. Returns the original error if it isn’t a thrown dict. Ensuresstepandfunctionkeys reflect the just-finished step even when the underlying error was raised by the preflight budget machinery (which doesn’t know which step it’s running under). - matching_
hooks - maybe_
push_ active_ persona - maybe_
push_ active_ step - Push an active step onto the stack iff
function_namehas metadata registered. Returnstruewhen a frame was pushed so the call site can record that fact. Called fromVm::push_closure_frameafter the new frame has been added. - peek_
completed_ steps - Read the completed-step log without clearing it. Use when callers want a peek without disturbing the global record stream.
- pop_
and_ record - Pop the topmost active step (if its frame is the current one) and record an explicit completion status. Used when an error boundary rewrites or absorbs an in-flight error so the receipt log reflects the outcome the persona actually saw.
- prune_
below_ frame - Drop any step entries whose owning frame has already been unwound,
recording a
CompletedStepsummary for each. Thecurrent_frame_depthisVm::frames.len()at the call site — entries withframe_depth > current_frame_depthare stale. - record_
step_ llm_ usage - Record that
llm_callconsumedinput_tokens/output_tokensforcost_usd. Updates the active step’s running totals and returns a budget-exhaustion error if the step’s ceiling is now breached. - register_
persona - register_
persona_ from_ dict - register_
persona_ hook - register_
step - Bind a
@stepfunction name to its declared metadata. Idempotent: a second call replaces the prior definition (matches re-evaluation semantics ofharn runand the conformance harness). - register_
step_ builtins - Register the
__register_stephost builtin. Compiler-emitted bytecode after every@stepdeclaration calls it with(function_name, metadata_dict)so the runtime can later dispatch on the step’s metadata when its function is invoked. - register_
step_ from_ dict - Builtin entry point invoked by compiler-emitted bytecode after every
@stepfunction declaration. Accepts a dict mirroringharn_modules::PersonaStepMetadata. - register_
step_ hook - reset_
thread_ local_ state - Reset every thread-local owned by this module. Called between test runs and at the start of each top-level program execution so leftover registrations don’t leak across runs.
- restore_
active_ context - step_
definition_ for_ function - take_
active_ context - take_
active_ step - with_
active_ step - Get a snapshot of the topmost active step, if any. Used by the llm_call path to fill in defaults — never for mutation.
- with_
active_ step_ mut - Mutate the topmost active step (typically to attribute LLM usage).