runner

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Overview

Package runner provides the shared dynamic-flow execution pipeline used by both `nexssflow` (standalone binary) and `nexssp flow` (subcommand).

It is deliberately independent of any specific transport: callers supply a flow file path, an initial payload, and optionally a list of assertions; the runner handles DSL sanitization, capability resolution, execution, and assertion evaluation.

The pipeline is:

read manifest
  -> merge @assert: directives with caller assertions
  -> sanitize DSL (strip comments, headers, inline @-annotations)
  -> build static registry (AI bundle + canonical aliases)
  -> parse :remote / :exec / :wasm bindings from the manifest
  -> materialize proxy actions, install into registry
  -> compile + execute the flow
  -> evaluate assertions against the JSON-encoded result

Capability resolution is done by the child package github.com/nexssp/flow/runner/capability.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExecSelf

func ExecSelf(ctx context.Context, binary string, args []string) int

ExecSelf re-executes the runner binary with the given args. The context is threaded through so the child is killed when the parent receives SIGTERM or its context is otherwise cancelled.

func PrintFlowInfo

func PrintFlowInfo(ctx context.Context, out io.Writer, req Request, reg *flow.MapRegistry) int

PrintFlowInfo inspects a .flow file and prints its pipeline topography, entry payload shape, and per-node action metadata.

reg is the registry used to resolve each node name. Pass the same registry the flow will execute against so the info output matches what the flow would actually call. Pass nil to fall back to the domainless standard library.

func ResolveRequires

func ResolveRequires(
	ctx context.Context,
	reqs []flow.Requirement,
	stdout, stderr *os.File,
) (string, error)

ResolveRequires returns the path to a runnable binary that provides the required libraries. When reqs is empty, it returns the current executable so the caller can re-exec itself with no codegen.

When reqs is non-empty, the harness is generated under <cwd>/.nexss/cache/<key>/ and built once. Subsequent calls with the same requirements reuse the cached binary.

func RunAssertions

func RunAssertions(result any, assertions []string, metrics *RunnerObserver) int

func RunWithRegistry

func RunWithRegistry(ctx context.Context, req Request, reg *flow.MapRegistry, observer *RunnerObserver) int

RunWithRegistry executes a flow against the caller-supplied registry. Use this when you already know what actions the flow may call. For the AI-flavoured entry point that builds a standard AI registry, see ai/flow/bootstrap.RunFlow.

Types

type ApprovalMode

type ApprovalMode string
const (
	ApprovalNone   ApprovalMode = "none"
	ApprovalDanger ApprovalMode = "danger"
	ApprovalAll    ApprovalMode = "all"
)

type Checkpoint

type Checkpoint struct {
	RunID       string         `json:"run_id"`
	Flow        string         `json:"flow"`
	FlowHash    string         `json:"flow_hash"`
	Layer       int            `json:"layer"`
	SavedAt     time.Time      `json:"saved_at"`
	SpentMicros int64          `json:"spent_micros"`
	State       map[string]any `json:"state"`
}

type CheckpointStore

type CheckpointStore interface {
	Save(ctx context.Context, cp Checkpoint) error
	Load(ctx context.Context, runID string) (Checkpoint, bool, error)
	Delete(ctx context.Context, runID string) error
}

type Default

type Default struct {
	// Observer is optional. When nil, a fresh observer is created
	// with verbosity resolved from the flow config.
	Observer *RunnerObserver
}

Default is the standard flow.Runner implementation. It builds a registry from the supplied libraries, wires the observer, and delegates to RunWithRegistry.

The zero value is safe to use.

func (Default) RunFlow

func (d Default) RunFlow(
	ctx context.Context,
	path string,
	payload map[string]any,
	args []string,
	libs []flow.Library,
	stdout, stderr io.Writer,
) int

func (Default) RunWithRegistry

func (d Default) RunWithRegistry(
	ctx context.Context,
	req Request,
	reg *flow.MapRegistry,
	obs *RunnerObserver,
) int

type FieldDoc

type FieldDoc struct {
	Name       string `json:"name"`
	Key        string `json:"key"`
	Type       string `json:"type"`
	Required   bool   `json:"required"`
	Validation string `json:"validation,omitempty"`
}

type FileCheckpointStore

type FileCheckpointStore struct {
	// contains filtered or unexported fields
}

func NewFileCheckpointStore

func NewFileCheckpointStore(baseDir string) (*FileCheckpointStore, error)

func (*FileCheckpointStore) Delete

func (s *FileCheckpointStore) Delete(ctx context.Context, runID string) error

func (*FileCheckpointStore) Load

func (s *FileCheckpointStore) Load(ctx context.Context, runID string) (Checkpoint, bool, error)

func (*FileCheckpointStore) Save

type FlowStep

type FlowStep struct {
	Name   string
	Prompt string
}

type MemoryCheckpointStore

type MemoryCheckpointStore struct {
	// contains filtered or unexported fields
}

func NewMemoryCheckpointStore

func NewMemoryCheckpointStore() *MemoryCheckpointStore

func (*MemoryCheckpointStore) Delete

func (s *MemoryCheckpointStore) Delete(ctx context.Context, runID string) error

func (*MemoryCheckpointStore) Load

func (*MemoryCheckpointStore) Save

type MetricRecord

type MetricRecord struct {
	ExecutionID   string
	Action        string
	Duration      time.Duration
	PromptSnippet string
	PromptTokens  int
	CompTokens    int
	CostMicros    int64
	Currency      cost.Currency
	CostKnown     bool
	Success       bool
}

MetricRecord is one row in the metrics table printed at the end of a run, or at exit on failure.

type ObserverHooks

type ObserverHooks struct {
	// KnownModel reports whether model is in the local price catalog.
	KnownModel func(model string) bool

	// TokensAndCost extracts (prompt, completion, cost_micros, currency,
	// known) from an arbitrary action result.
	TokensAndCost func(res any) (int, int, int64, cost.Currency, bool)

	// ResultSummary renders a short human-readable summary of a result.
	ResultSummary func(res any) string

	// PromptFromRequest extracts a display prompt from a request. When
	// nil, only maps with "prompt" or "goal" are recognized.
	PromptFromRequest func(req any) string
}

ObserverHooks lets a domain layer teach the observer how to render results it understands. Every hook is optional: nil functions fall through to the domainless defaults in observer_extract.go.

type Request

type Request struct {
	Path    string
	Payload map[string]any
	Args    []string

	Verbosity    int
	Info         bool
	Assertions   []string
	Metrics      bool
	OutFormat    string
	OutDir       string
	BenchNode    string
	BenchRuns    int
	CacheDir     string
	ApprovalMode ApprovalMode

	Resume string
	Store  CheckpointStore

	Stdout io.Writer
	Stderr io.Writer
}

type RunnerObserver

type RunnerObserver struct {
	// contains filtered or unexported fields
}

RunnerObserver is the flow runner's terminal reporter. It receives lifecycle events from two sources:

  • the observe.Hook attached to every action by the compiler, which feeds the end-of-run metrics table;
  • the live hook returned by Hook(), which prints the per-action trace lines while the flow is running.

Domain-specific rendering (LLM token counts, evaluator verdicts, price catalog lookups) is delegated to ObserverHooks. A nil hook falls back to a domainless default, so the observer works for any flow — AI-flavoured or not.

func NewRunnerObserver

func NewRunnerObserver(out io.Writer, verbosity int) *RunnerObserver

NewRunnerObserver creates an observer with no domain-specific hooks. Use this for flows that carry no AI/LLM actions.

func NewRunnerObserverWithHooks

func NewRunnerObserverWithHooks(out io.Writer, verbosity int, hooks ObserverHooks) *RunnerObserver

NewRunnerObserverWithHooks creates an observer that delegates domain-specific rendering to the supplied hooks. Nil hook functions are safe: the observer falls back to domainless defaults.

func (*RunnerObserver) AddSpend

func (o *RunnerObserver) AddSpend(micros int64)

func (*RunnerObserver) Emit

func (o *RunnerObserver) Emit(_ context.Context, ev observe.Event)

func (*RunnerObserver) Hook

func (o *RunnerObserver) Hook() action.AnyHook

func (*RunnerObserver) Out

func (o *RunnerObserver) Out() io.Writer

func (*RunnerObserver) PrintSummary

func (o *RunnerObserver) PrintSummary(out io.Writer)

PrintSummary renders the end-of-run metrics table. Callers pass the writer they want the table on (usually the same stdout the live log went to). Safe to call after the flow has failed.

func (*RunnerObserver) ProviderTrace

func (o *RunnerObserver) ProviderTrace(
	kind, provider, model string,
	in, out int,
	costMicro int64,
	dur time.Duration,
	err error,
)

ProviderTrace is the callback installed on the LLM provider wrapper. It receives one event per Complete call (start / finish / warn / error) and renders it to the live log at verbosity >= 1.

func (*RunnerObserver) SetVerbosity

func (o *RunnerObserver) SetVerbosity(n int)

func (*RunnerObserver) TotalSpentMicros

func (o *RunnerObserver) TotalSpentMicros() int64

func (*RunnerObserver) TotalTokens

func (o *RunnerObserver) TotalTokens() int

func (*RunnerObserver) Verbosity

func (o *RunnerObserver) Verbosity() int

type TerminalApprovalGate

type TerminalApprovalGate struct {
	// contains filtered or unexported fields
}

func NewApprovalGate

func NewApprovalGate(mode ApprovalMode) *TerminalApprovalGate

func (*TerminalApprovalGate) Check

func (g *TerminalApprovalGate) Check(ctx context.Context, actionName, argsJSON, token string) error

Directories

Path Synopsis
Assembly is the single composition pipeline for a nexss binary.
Assembly is the single composition pipeline for a nexss binary.
console
Package console exposes a small, generic, self-contained web UI for any Nexss binary.
Package console exposes a small, generic, self-contained web UI for any Nexss binary.
Package capability resolves flow-node names into runnable action.AnyAction values at flow-execution time.
Package capability resolves flow-node names into runnable action.AnyAction values at flow-execution time.
Package testkit provides flow-runner-specific test helpers.
Package testkit provides flow-runner-specific test helpers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL