invocation

package
v0.2.0-beta.3 Latest Latest
Warning

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

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

Documentation

Overview

Package invocation defines the document the engine assembles for every invocation — the single description of what an invoker receives, what Server.Results returns, and what a choice expression is evaluated against.

It exists because those three consumers previously each restated the same five field names: the engine in an anonymous marshal struct, the rules package in its compile environment, and every embedder in a hand-written mirror decoded with encoding/json. A rename in one place did not fail to compile in the others — it deserialised to a zero value, so an invoker silently saw no previous result and a choice rule silently took its default branch. Declaring the shape once makes that a build error.

The root package re-exports Context as packtrail.InvocationContext.

Index

Constants

View Source
const (
	VarInput      = "input"
	VarResults    = "results"
	VarSignals    = "signals"
	VarBranches   = "branches"
	VarLastNode   = "last_node"
	VarReleasedBy = "released_by"
)

Variable names, as they appear in the JSON document and as the identifiers a choice expression may reference. They are constants so a rename reaches the rules environment and the decoder together.

Variables

This section is empty.

Functions

func Env

func Env() map[string]any

Env returns the variable skeleton a choice expression is compiled against. Derived from the same constants as the document, so a field added to Context is referenceable from a rule only once it is named here too.

Types

type Context

type Context struct {
	// Input is the payload the execution was started with. Always a JSON
	// object; an execution started with no payload gets `{}`.
	Input json.RawMessage `json:"input"`
	// Results holds every settled node's output, keyed by node id. An agent-style
	// invoker that returns a bare JSON string finds it here unwrapped.
	Results map[string]json.RawMessage `json:"results"`
	// Signals holds the payload of every signal received so far, keyed by signal
	// name. A signal that has been consumed by a waiting node stays here.
	Signals map[string]json.RawMessage `json:"signals"`
	// Branches holds the outputs of the fan currently being joined, keyed by
	// branch node id — not every branch the execution has ever run. A flow with
	// two sequential fan-outs sees only the second fan's replies at the second
	// join. Whether the join just happened is `last_node ∈ branches`.
	Branches map[string]json.RawMessage `json:"branches"`
	// LastNode is the id of the most recently settled output, so "the previous
	// step's result" is Results[LastNode]. Signal nodes produce no output and
	// therefore never appear here — see ReleasedBy.
	LastNode string `json:"last_node"`
	// ReleasedBy is the name of the signal that released the wait immediately
	// preceding this invocation, and is empty for every other node. It is what
	// makes a human-in-the-loop payload reachable: the signal's own payload is
	// Signals[ReleasedBy].
	//
	// It is scoped to the node the release advanced to. A later node does not
	// inherit it, so it cannot be mistaken for "some signal arrived at some
	// point" — that question is answered by Signals.
	ReleasedBy string `json:"released_by,omitempty"`
}

Context is the assembled invocation document.

Every field is derived state: the engine rebuilds it from the store for each invocation rather than threading a mutable payload between nodes, so a node can never corrupt what a later node reads.

func Decode

func Decode(doc json.RawMessage) (Context, error)

Decode parses an assembled document, tolerating an empty one (which yields a zero Context rather than an error, since an execution with no input and no settled node is a legitimate state).

Jump to

Keyboard shortcuts

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