Documentation
¶
Overview ¶
Package workflow compiles versioned, declarative workflow definitions into immutable in-process execution plans.
Workflow is independent of the ai and agent packages. Applications provide behavior through explicitly registered Actions; definitions contain data, bindings, and control edges, never executable code.
Built-in composition remains fixed-flow and synchronous: Selector chooses one ordered route, SubWorkflow executes an exact resolved revision, Batch maps an inline child Definition over an array with bounded workers, and Loop sequentially executes a bounded inline body with transactional local variables. Batch and Loop are distinct and cannot contain each other. Merge v1 preserves exactly-one-present branch aggregation; Merge v2 uses ordered first-non-null selection for route-relevant upstream candidates. Both versions keep parallel Merge as direct wait-all fan-in.
Runs can stop at compile-time before/after boundaries, at dynamic Interrupt calls, or on a host signal. A CheckpointStore persists one opaque snapshot per Run ID so a new Runner can validate the same Plan and Resume the exact root and composite frontier. Checkpoints are process-runtime state, not part of the Definition wire contract.
During a real node invocation, Actions and custom NodeTypes can call GetExecutionContext to read the current Run, Definition, scoped node address, and cumulative one-based attempt. The returned address is detached runtime correlation metadata; hosts remain responsible for defining idempotency at their own side-effect boundaries.
Exhausted node failures either stop execution, select a dedicated error route, or continue with compile-validated default outputs. Error-route consumers use BindingNodeError to read the bounded error_message and error_type ports; normal outputs remain unavailable on that path. Handled nodes have NodeStatusException, and a completed root execution that observed one has RunStatusPartialSucceeded. Error messages are sensitive Workflow data and never lifecycle Event payloads.
RunPartial executes the root dependency slice ending at one destination. Hosts may supply detached successful data from a prior Partial Run, current pinned outputs, and directly changed node IDs; the runtime validates routes and schemas, invalidates dirty descendants, and executes every remaining boundary through the ordinary scheduler. Composite nodes remain atomic. ResumePartial uses the same opaque CheckpointStore protocol, while Run and Resume never consult Partial Run data.
PrepareNodeDebug derives a Coze-style isolated trial plan for one eligible node. DebugNode executes that selected node without executing its upstream graph; outside bindings become explicit final-schema inputs while literals and selected composite child Plans remain internal. Results contain sensitive resolved values and Action error text, so hosts own authorization, redaction, encryption, and retention. ResumeNodeDebug uses the same opaque CheckpointStore boundary as Resume. Node Debug invokes real Actions and is distinct from partial graph replay or pinned-data execution.
SchemaV1Alpha1 preserves required schema-only Workflow inputs. V1Alpha2 adds required, optional, and non-null default input contracts while retaining strict version-directed decoding. Defaults normalize only at a Workflow boundary, never as generic Action or NodeType port behavior. Events are process-local observations and intentionally have no JSON wire format.
Compile reports Definition diagnostics as a *CompileError containing stable issue codes and Definition, node, or control-path locations. Diagnostics are phase-gated: Compile returns all safely independent issues in the earliest failed compiler phase, not every hypothetical downstream problem. Nested SubWorkflow, Batch, and Loop issues retain full NodePath locations. Issues are process-local values with no prescribed JSON or persistence format; hosts own localization and versioned API, database, or editor projections.
WithNodeExecutionRecorder exposes detached running and effective outcome snapshots for ordinary Run and Resume operations. The callback is a synchronous, process-local upsert boundary keyed by RunID and NodeAddress; the host owns persistence failures, timeouts, redaction, retention, and any stable transport schema. Node Debug and Partial Run do not call it.
Index ¶
- Constants
- Variables
- func CompositeInterrupt(ctx context.Context, info Value, state Value, causes ...error) error
- func DecodeValue[T any](v Value) (T, error)
- func Interrupt(ctx context.Context, info Value) error
- func StatefulInterrupt(ctx context.Context, info, state Value) error
- func WithRunInterrupt(parent context.Context) (context.Context, func(...RunInterruptOption))
- type Action
- type ActionConfig
- type ActionInput
- type ActionKey
- type ActionNode
- type ActionOutput
- type ActionSpec
- type BatchConfig
- type BatchErrorMode
- type BatchMode
- type BatchNode
- type Binding
- type BindingSource
- type BreakNode
- type CheckpointStore
- type CompileContext
- type CompileControlPath
- type CompileError
- type CompileIssue
- type CompileIssueCode
- type CompileIssueLocation
- type CompileOption
- type CompiledNode
- type ConditionConfig
- type ConditionNode
- type ContinueNode
- type ControlEdge
- type Definition
- type DefinitionID
- type DefinitionRef
- type DefinitionResolver
- type DefinitionResolverFunc
- type EndNode
- type ErrorAction
- type Event
- type EventPayload
- type EventSink
- type EventType
- type ExecutionContext
- type FailureKind
- type InterruptContext
- type InterruptError
- type InterruptInfo
- type Limits
- type LoopConfig
- type LoopMode
- type LoopNode
- type LoopOutput
- type LoopOutputSource
- type LoopVariable
- type MergeConfig
- type MergeMode
- type MergeNode
- type MergeOutputConfig
- type NodeAddress
- type NodeCompleted
- type NodeDebugExecution
- type NodeDebugPlan
- type NodeDebugResult
- type NodeDebugSpec
- type NodeDefinition
- type NodeExecution
- type NodeExecutionRecorder
- type NodeFailed
- type NodeID
- type NodeInput
- type NodeInterrupted
- type NodeOutput
- type NodePath
- type NodePolicy
- type NodeReady
- type NodeRetrying
- type NodeRoute
- type NodeRun
- type NodeSkipped
- type NodeSpec
- type NodeStarted
- type NodeStatus
- type NodeType
- type NodeTypeKey
- type NodeTypeSpec
- type OutputBinding
- type PartialDataOrigin
- type PartialNodeData
- type PartialNodeRun
- type PartialRunData
- type PartialRunInput
- type PartialRunResult
- type PinData
- type Plan
- type PortSchema
- func (s PortSchema) Equal(other PortSchema) bool
- func (s PortSchema) Fingerprint() string
- func (s PortSchema) IsValid() bool
- func (s PortSchema) MarshalJSON() ([]byte, error)
- func (s PortSchema) RawJSON() []byte
- func (s *PortSchema) UnmarshalJSON(data []byte) error
- func (s PortSchema) Validate(value Value) (returnErr error)
- type Predicate
- type PredicateOp
- type Registry
- type ResumeTarget
- type RetryPolicy
- type Revision
- type RunCanceled
- type RunCompleted
- type RunError
- type RunFailed
- type RunIDSource
- type RunInterruptOption
- type RunInterrupted
- type RunResult
- type RunResumed
- type RunStarted
- type RunStatus
- type Runner
- func (r *Runner) DebugNode(ctx context.Context, debugPlan *NodeDebugPlan, inputs map[string]Value) (NodeDebugResult, error)
- func (r *Runner) Resume(ctx context.Context, plan *Plan, runID string, targets []ResumeTarget) (RunResult, error)
- func (r *Runner) ResumeNodeDebug(ctx context.Context, debugPlan *NodeDebugPlan, runID string, ...) (NodeDebugResult, error)
- func (r *Runner) ResumePartial(ctx context.Context, source *Plan, destination NodeID, runID string, ...) (PartialRunResult, error)
- func (r *Runner) Run(ctx context.Context, plan *Plan, inputs map[string]Value) (RunResult, error)
- func (r *Runner) RunPartial(ctx context.Context, source *Plan, destination NodeID, input PartialRunInput) (PartialRunResult, error)
- type RunnerOption
- type ScopeFrame
- type ScopeKind
- type SelectorCase
- type SelectorConfig
- type SelectorNode
- type SetVariableAssignment
- type SetVariableConfig
- type SetVariableNode
- type StartNode
- type SubWorkflowConfig
- type SubWorkflowNode
- type Value
- func GetInterruptState(ctx context.Context) (wasInterrupted bool, hasState bool, state Value)
- func GetResumeContext(ctx context.Context) (isResumeTarget bool, hasData bool, data Value)
- func MustValueOf(value any) Value
- func ParseValue(data []byte) (Value, error)
- func ValueOf(value any) (Value, error)
- func (v Value) Any() (any, error)
- func (v Value) Equal(other Value) bool
- func (v Value) IsValid() bool
- func (v Value) Kind() ValueKind
- func (v Value) Lookup(path ...string) (Value, bool)
- func (v Value) MarshalJSON() ([]byte, error)
- func (v Value) RawJSON() []byte
- func (v Value) String() string
- func (v *Value) UnmarshalJSON(data []byte) error
- type ValueKind
- type WorkflowInput
Examples ¶
Constants ¶
const ( // SchemaV1Alpha1 identifies the first Workflow Definition wire format. SchemaV1Alpha1 = "pips.workflow/v1alpha1" // SchemaV1Alpha2 adds required, optional, and default Workflow inputs. SchemaV1Alpha2 = "pips.workflow/v1alpha2" )
const ( // NodeErrorMessagePort contains the terminal error text after retry exhaustion. NodeErrorMessagePort = "error_message" // NodeErrorTypePort contains the stable [FailureKind] classification. NodeErrorTypePort = "error_type" )
Variables ¶
var ( // ErrInvalidValue classifies malformed or unsupported JSON values. ErrInvalidValue = errors.New("workflow: invalid value") // ErrInvalidSchema classifies malformed or unsupported port schemas. ErrInvalidSchema = errors.New("workflow: invalid schema") // ErrSchemaViolation means a Value does not satisfy a PortSchema. ErrSchemaViolation = errors.New("workflow: schema violation") // ErrInvalidDefinition classifies malformed workflow definitions. ErrInvalidDefinition = errors.New("workflow: invalid definition") // ErrInvalidRegistry classifies invalid node type or Action registrations. ErrInvalidRegistry = errors.New("workflow: invalid registry") // ErrCompile classifies a definition that cannot produce an execution plan. ErrCompile = errors.New("workflow: compile failed") // ErrRun classifies a workflow execution failure. ErrRun = errors.New("workflow: run failed") // ErrInterrupted classifies a successfully checkpointed, resumable Run. ErrInterrupted = errors.New("workflow: interrupted") // ErrEventWireFormat reports an attempt to serialize a process-local Event. ErrEventWireFormat = errors.New("workflow: event has no wire format") // ErrNodeExecutionWireFormat reports an attempt to serialize a sensitive, // process-local NodeExecution snapshot. ErrNodeExecutionWireFormat = errors.New("workflow: node execution has no wire format") )
Workflow validation and execution errors. Match them with errors.Is.
Functions ¶
func CompositeInterrupt ¶
CompositeInterrupt propagates descendant interruption errors while saving local composite state. Ordinary errors are rejected.
func DecodeValue ¶
DecodeValue decodes v into T using encoding/json rules.
func StatefulInterrupt ¶
StatefulInterrupt suspends the current invocation and persists private local state for GetInterruptState on a targeted resume.
func WithRunInterrupt ¶
func WithRunInterrupt( parent context.Context, ) (context.Context, func(...RunInterruptOption))
WithRunInterrupt enables a resumable host interruption signal without canceling the parent context. The returned function is safe to call more than once; only its first call takes effect.
Types ¶
type Action ¶
type Action interface {
Spec() ActionSpec
Run(context.Context, ActionInput) (ActionOutput, error)
}
Action is trusted host behavior referenced by key and exact version from an ActionNode Definition. Implementations must be safe for concurrent Runs, honor context cancellation, and avoid retaining or mutating ActionInput.
type ActionConfig ¶
type ActionConfig struct {
Action ActionKey `json:"action"`
Version string `json:"version"`
Parameters *Value `json:"parameters,omitempty"`
}
ActionConfig selects one exact Action and carries optional immutable parameters that are separate from data bindings.
type ActionInput ¶
ActionInput carries resolved values and optional immutable node parameters.
type ActionNode ¶
type ActionNode struct{}
ActionNode invokes one host-registered Action.
func (ActionNode) Compile ¶
func (ActionNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type ActionOutput ¶
ActionOutput contains values produced by an Action.
type ActionSpec ¶
type ActionSpec struct {
Key ActionKey
Version string
Inputs map[string]PortSchema
Outputs map[string]PortSchema
}
ActionSpec identifies one host Action and its data contract.
type BatchConfig ¶
type BatchConfig struct {
Body Definition `json:"body"`
ResultOutput string `json:"result_output"`
Mode BatchMode `json:"mode"`
MaxConcurrency int `json:"max_concurrency,omitempty"`
ErrorMode BatchErrorMode `json:"error_mode"`
MaxItems int `json:"max_items,omitempty"`
}
BatchConfig defines an inline item Workflow and its bounded map behavior.
Example ¶
package main
import (
"fmt"
"github.com/rsbin1178/pips/workflow"
)
func main() {
config := workflow.BatchConfig{
Mode: workflow.BatchParallel,
MaxConcurrency: 4,
ErrorMode: workflow.BatchContinueWithNull,
MaxItems: 100,
}
fmt.Println(config.Mode, config.MaxConcurrency, config.ErrorMode)
}
Output: parallel 4 continue_with_null
type BatchErrorMode ¶
type BatchErrorMode string
BatchErrorMode controls failed item aggregation.
const ( BatchTerminate BatchErrorMode = "terminate" BatchContinueWithNull BatchErrorMode = "continue_with_null" BatchRemoveFailed BatchErrorMode = "remove_failed" )
Batch item error modes.
type BatchNode ¶
type BatchNode struct{}
BatchNode maps an inline Workflow over an input array.
func (BatchNode) Compile ¶
func (BatchNode) Compile( ctx context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type Binding ¶
type Binding struct {
Source BindingSource `json:"source"`
Node NodeID `json:"node,omitempty"`
Port string `json:"port,omitempty"`
Path []string `json:"path,omitempty"`
Value *Value `json:"value,omitempty"`
}
Binding selects a literal, Workflow input, prior node output, typed node failure data, or direct Loop variable. Path walks object keys or decimal array indexes after resolving the source value.
type BindingSource ¶
type BindingSource string
BindingSource identifies where an input value comes from.
const ( BindingLiteral BindingSource = "literal" BindingWorkflowInput BindingSource = "workflow_input" BindingNodeOutput BindingSource = "node_output" BindingNodeError BindingSource = "node_error" BindingLoopVariable BindingSource = "loop_variable" )
Binding sources.
type BreakNode ¶
type BreakNode struct{}
BreakNode terminates the owning Loop after the current iteration commits.
func (BreakNode) Compile ¶
func (BreakNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type CheckpointStore ¶
type CheckpointStore interface {
Get(context.Context, string) ([]byte, bool, error)
Set(context.Context, string, []byte) error
}
CheckpointStore persists one opaque, versioned Workflow checkpoint by Run ID. Implementations must replace a key atomically and detach returned buffers.
type CompileContext ¶
type CompileContext interface {
WorkflowInputs() map[string]PortSchema
WorkflowOutputs() map[string]PortSchema
Action(ActionKey, string) (Action, bool)
}
CompileContext exposes Definition contracts and registered Actions during NodeType.Compile without exposing mutable Registry internals. NodeTypes must not retain a CompileContext after Compile returns.
type CompileControlPath ¶
CompileControlPath identifies one control connection in a root or nested Definition. From and To are complete paths through composite boundaries.
type CompileError ¶
type CompileError struct {
// contains filtered or unexported fields
}
CompileError reports one or more ordered issues that prevented Plan construction. Compile aggregates only the earliest failed dependency phase; later phases are not evaluated after their prerequisites fail.
func (*CompileError) Error ¶
func (e *CompileError) Error() string
Error returns a deterministic summary of every issue.
func (*CompileError) Issues ¶
func (e *CompileError) Issues() []CompileIssue
Issues returns an independent snapshot of the ordered diagnostics.
func (*CompileError) Unwrap ¶
func (e *CompileError) Unwrap() []error
Unwrap preserves ErrCompile and any underlying Definition, resolver, or NodeType causes for errors.Is and errors.As.
type CompileIssue ¶
type CompileIssue struct {
// contains filtered or unexported fields
}
CompileIssue is one immutable, process-local compiler diagnostic. It has no prescribed JSON or persistence format; hosts own versioned projections.
func (CompileIssue) Code ¶
func (i CompileIssue) Code() CompileIssueCode
Code returns the stable category of i.
func (CompileIssue) ControlPath ¶
func (i CompileIssue) ControlPath() (CompileControlPath, bool)
ControlPath returns the complete control path when i is path-located.
func (CompileIssue) Location ¶
func (i CompileIssue) Location() CompileIssueLocation
Location returns the location kind of i.
func (CompileIssue) Message ¶
func (i CompileIssue) Message() string
Message returns the human-readable detail of i.
func (CompileIssue) NodePath ¶
func (i CompileIssue) NodePath() (NodePath, bool)
NodePath returns the complete node path when i is node-located.
type CompileIssueCode ¶
type CompileIssueCode string
CompileIssueCode identifies a stable compile failure category. Messages may become more specific over time; callers should branch on Code instead.
const ( CompileIssueInvalidDefinition CompileIssueCode = "invalid_definition" CompileIssueInvalidInterrupt CompileIssueCode = "invalid_interrupt" CompileIssueInvalidReference CompileIssueCode = "invalid_reference" CompileIssueUnknownNodeType CompileIssueCode = "unknown_node_type" CompileIssueInvalidNodeConfig CompileIssueCode = "invalid_node_config" CompileIssueInvalidNodeSpec CompileIssueCode = "invalid_node_spec" CompileIssueInvalidControlPath CompileIssueCode = "invalid_control_path" CompileIssueInvalidGraph CompileIssueCode = "invalid_graph" CompileIssueInvalidBinding CompileIssueCode = "invalid_binding" )
Compile issue codes.
type CompileIssueLocation ¶
type CompileIssueLocation string
CompileIssueLocation identifies which location accessor is available on a CompileIssue.
const ( CompileLocationDefinition CompileIssueLocation = "definition" CompileLocationNode CompileIssueLocation = "node" CompileLocationPath CompileIssueLocation = "path" )
Compile issue locations.
type CompileOption ¶
type CompileOption func(*compileConfig) error
CompileOption configures child Workflow resolution during compilation.
func WithDefinitionResolver ¶
func WithDefinitionResolver(resolver DefinitionResolver) CompileOption
WithDefinitionResolver configures exact referenced Workflow resolution.
func WithInterruptAfterNodes ¶
func WithInterruptAfterNodes(paths ...NodePath) CompileOption
WithInterruptAfterNodes pauses a Run after any addressed node succeeds.
func WithInterruptBeforeNodes ¶
func WithInterruptBeforeNodes(paths ...NodePath) CompileOption
WithInterruptBeforeNodes pauses a Run before any addressed node is invoked.
type CompiledNode ¶
type CompiledNode interface {
Spec() NodeSpec
Invoke(context.Context, NodeInput) (NodeOutput, error)
}
CompiledNode is an immutable, concurrent-safe node executor. Invoke must not retain or mutate NodeInput.Values.
type ConditionConfig ¶
type ConditionConfig struct {
Predicate Predicate `json:"predicate"`
TrueRoute string `json:"true_route"`
FalseRoute string `json:"false_route"`
}
ConditionConfig selects named routes for a boolean Predicate result.
type ConditionNode ¶
type ConditionNode struct{}
ConditionNode chooses one named route using a structured Predicate.
func (ConditionNode) Compile ¶
func (ConditionNode) Compile( _ context.Context, _ CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type ContinueNode ¶
type ContinueNode struct{}
ContinueNode terminates the current Loop iteration without exiting the Loop.
func (ContinueNode) Compile ¶
func (ContinueNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type ControlEdge ¶
ControlEdge connects one named source route to a target node. It carries no data; values move only through explicit Bindings.
type Definition ¶
type Definition struct {
Schema string `json:"schema"`
ID DefinitionID `json:"id"`
Revision Revision `json:"revision"`
Name string `json:"name"`
Inputs map[string]WorkflowInput `json:"inputs"`
Outputs map[string]OutputBinding `json:"outputs"`
Nodes []NodeDefinition `json:"nodes"`
Edges []ControlEdge `json:"edges"`
Limits Limits `json:"limits"`
}
Definition is a versioned, serializable Workflow contract.
func DecodeDefinition ¶
func DecodeDefinition(data []byte) (Definition, error)
DecodeDefinition strictly decodes and validates one Definition snapshot.
func (Definition) Fingerprint ¶
func (d Definition) Fingerprint() (string, error)
Fingerprint returns a SHA-256 digest of execution-semantic fields. ID, Revision, and Name do not affect it.
func (Definition) MarshalJSON ¶
func (d Definition) MarshalJSON() ([]byte, error)
MarshalJSON writes the exact wire shape selected by Definition.Schema.
func (*Definition) UnmarshalJSON ¶
func (d *Definition) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes only the exact wire shape selected by the schema field.
type DefinitionID ¶
type DefinitionID string
DefinitionID identifies a logical workflow across revisions.
type DefinitionRef ¶
type DefinitionRef struct {
ID DefinitionID `json:"id"`
Revision Revision `json:"revision"`
Fingerprint string `json:"fingerprint"`
}
DefinitionRef pins one exact immutable Workflow definition.
Example ¶
package main
import (
"fmt"
"github.com/rsbin1178/pips/workflow"
)
func main() {
reference := workflow.DefinitionRef{
ID: "thumbnail-flow",
Revision: "v3",
Fingerprint: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
}
fmt.Println(reference.ID, reference.Revision)
}
Output: thumbnail-flow v3
type DefinitionResolver ¶
type DefinitionResolver interface {
ResolveDefinition(context.Context, DefinitionID, Revision) (Definition, error)
}
DefinitionResolver resolves exact Workflow revisions for compilation. Implementations must be safe for concurrent calls and return detached Definition snapshots.
type DefinitionResolverFunc ¶
type DefinitionResolverFunc func(context.Context, DefinitionID, Revision) (Definition, error)
DefinitionResolverFunc adapts a function to DefinitionResolver.
func (DefinitionResolverFunc) ResolveDefinition ¶
func (f DefinitionResolverFunc) ResolveDefinition( ctx context.Context, id DefinitionID, revision Revision, ) (Definition, error)
ResolveDefinition implements DefinitionResolver.
type EndNode ¶
type EndNode struct{}
EndNode validates and returns Workflow outputs.
func (EndNode) Compile ¶
func (EndNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type ErrorAction ¶
type ErrorAction string
ErrorAction controls a node failure after retries are exhausted.
const ( ErrorStop ErrorAction = "stop" ErrorRoute ErrorAction = "route_error" ErrorContinueWithDefault ErrorAction = "continue_with_default" )
Node failure actions. The zero value is equivalent to ErrorStop.
type Event ¶
type Event struct {
DefinitionID DefinitionID
Revision Revision
DefinitionFingerprint string
PlanFingerprint string
RunID string
NodeID NodeID
NodeType NodeTypeKey
Attempt int
Time time.Time
// contains filtered or unexported fields
}
Event is one immutable, process-local Workflow lifecycle increment. It has no JSON wire format; durable consumers must define a versioned projection.
func (Event) MarshalJSON ¶
MarshalJSON prevents Event from being mistaken for a stable wire protocol.
func (Event) Payload ¶
func (e Event) Payload() EventPayload
Payload returns e's sealed semantic payload.
func (Event) Scope ¶
func (e Event) Scope() []ScopeFrame
Scope returns an independent snapshot of nested execution frames. Root events have an empty scope.
func (*Event) UnmarshalJSON ¶
UnmarshalJSON rejects an unspecified Event wire representation.
type EventPayload ¶
type EventPayload interface {
// contains filtered or unexported methods
}
EventPayload is the sealed union of Workflow Event variants.
type EventSink ¶
type EventSink func(Event)
EventSink synchronously observes process-local events. A Runner serializes calls to one sink for each Run and applies backpressure. The same sink may be called concurrently by concurrent Runs and must synchronize shared state.
type EventType ¶
type EventType string
EventType identifies one process-local Workflow event variant.
const ( EventRunStarted EventType = "run_started" EventRunCompleted EventType = "run_completed" EventRunFailed EventType = "run_failed" EventRunCanceled EventType = "run_canceled" EventRunInterrupted EventType = "run_interrupted" EventRunResumed EventType = "run_resumed" EventNodeReady EventType = "node_ready" EventNodeStarted EventType = "node_started" EventNodeCompleted EventType = "node_completed" EventNodeFailed EventType = "node_failed" EventNodeSkipped EventType = "node_skipped" EventNodeRetrying EventType = "node_retrying" EventNodeInterrupted EventType = "node_interrupted" )
Event types.
type ExecutionContext ¶
type ExecutionContext struct {
RunID string
DefinitionID DefinitionID
Revision Revision
Address NodeAddress
Attempt int
}
ExecutionContext identifies one concrete node invocation. Attempt is the one-based cumulative attempt for Address within the Run, including attempts restored from a checkpoint.
ExecutionContext is correlation metadata, not an external idempotency key. Hosts define idempotency according to their own side-effect boundaries.
func GetExecutionContext ¶
func GetExecutionContext(ctx context.Context) (ExecutionContext, bool)
GetExecutionContext returns the scheduler-owned identity of the current node invocation. It returns false outside an invocation. The returned Address is detached and may be modified without affecting runtime state or later reads.
type FailureKind ¶
type FailureKind string
FailureKind is a bounded, payload-free node failure classification.
const ( FailureError FailureKind = "error" FailureTimeout FailureKind = "timeout" FailurePanic FailureKind = "panic" FailureCanceled FailureKind = "canceled" FailureLimit FailureKind = "limit" )
Failure kinds. Action error text is deliberately absent from Events.
type InterruptContext ¶
type InterruptContext struct {
ID string
Address NodeAddress
Info Value
}
InterruptContext describes one targetable dynamic interruption.
type InterruptError ¶
type InterruptError struct {
RunID string
Info InterruptInfo
}
InterruptError reports a successfully checkpointed, resumable Run.
func (*InterruptError) Unwrap ¶
func (e *InterruptError) Unwrap() error
Unwrap exposes ErrInterrupted for errors.Is.
type InterruptInfo ¶
type InterruptInfo struct {
Contexts []InterruptContext
BeforeNodes []NodeAddress
AfterNodes []NodeAddress
RerunNodes []NodeAddress
}
InterruptInfo aggregates every interruption observed at the settled scheduler frontier. Only Contexts are targetable with ResumeTarget.
type Limits ¶
Limits bounds one Run. Both fields must be positive.
func DefaultLimits ¶
func DefaultLimits() Limits
DefaultLimits returns conservative in-process Run limits.
type LoopConfig ¶
type LoopConfig struct {
Body Definition `json:"body"`
Mode LoopMode `json:"mode"`
Arrays []string `json:"arrays,omitempty"`
Variables []LoopVariable `json:"variables,omitempty"`
Outputs []LoopOutput `json:"outputs,omitempty"`
MaxIterations int `json:"max_iterations,omitempty"`
}
LoopConfig defines an inline sequential Loop body.
type LoopNode ¶
type LoopNode struct{}
LoopNode repeatedly executes an inline Workflow with transactional local variables.
Example ¶
integerSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"integer"}`))
countSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"integer","minimum":1}`))
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
ready := workflow.MustValueOf("ready")
conditionConfig, _ := json.Marshal(workflow.ConditionConfig{
Predicate: workflow.Predicate{
Op: workflow.PredicateEqual, Input: "state", Value: &ready,
},
TrueRoute: "stop", FalseRoute: "next",
})
setConfig, _ := json.Marshal(workflow.SetVariableConfig{
Assignments: []workflow.SetVariableAssignment{{Target: "state", Input: "next"}},
})
body := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "feedback-body", Revision: "v1", Name: "Feedback Body",
Inputs: map[string]workflow.WorkflowInput{"index": {Schema: integerSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "condition", Type: workflow.NodeTypeCondition, Version: workflow.BuiltinNodeVersion,
Config: conditionConfig,
Inputs: map[string]workflow.Binding{
"state": {Source: workflow.BindingLoopVariable, Port: "state"},
},
},
{
ID: "set", Type: workflow.NodeTypeSetVariable, Version: workflow.BuiltinNodeVersion,
Config: setConfig,
Inputs: map[string]workflow.Binding{
"next": {Source: workflow.BindingLiteral, Value: &ready},
},
},
{ID: "break", Type: workflow.NodeTypeBreak, Version: workflow.BuiltinNodeVersion},
{ID: "continue", Type: workflow.NodeTypeContinue, Version: workflow.BuiltinNodeVersion},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "condition"),
edge("condition", "stop", "break"),
edge("condition", "next", "set"),
edge("set", workflow.RouteSuccess, "continue"),
edge("break", workflow.RouteSuccess, "end"),
edge("continue", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
loopConfig, _ := json.Marshal(workflow.LoopConfig{
Body: body, Mode: workflow.LoopCount,
Variables: []workflow.LoopVariable{{Name: "state", Schema: stringSchema}},
Outputs: []workflow.LoopOutput{
{Name: "final", Source: workflow.LoopOutputVariable, Port: "state"},
},
MaxIterations: 10,
})
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "feedback", Revision: "v1", Name: "Feedback",
Inputs: map[string]workflow.WorkflowInput{
"count": {Schema: countSchema, Required: true}, "state": {Schema: stringSchema, Required: true},
},
Outputs: map[string]workflow.OutputBinding{
"final": nodeOutput(stringSchema, "loop", "final"),
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "loop", Type: workflow.NodeTypeLoop, Version: workflow.BuiltinNodeVersion,
Config: loopConfig,
Inputs: map[string]workflow.Binding{
"count": workflowInput("count"), "state": workflowInput("state"),
},
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "loop"),
edge("loop", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
registry, _ := workflow.NewDefaultRegistry()
plan, _ := workflow.Compile(context.Background(), definition, registry)
runner, _ := workflow.NewRunner()
result, _ := runner.Run(context.Background(), plan, map[string]workflow.Value{
"count": workflow.MustValueOf(5), "state": workflow.MustValueOf("pending"),
})
fmt.Println(result.Outputs["final"].String())
Output: "ready"
func (LoopNode) Compile ¶
func (LoopNode) Compile( ctx context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type LoopOutput ¶
type LoopOutput struct {
Name string `json:"name"`
Source LoopOutputSource `json:"source"`
Port string `json:"port"`
}
LoopOutput projects a body output or final Loop variable onto the Loop node.
type LoopOutputSource ¶
type LoopOutputSource string
LoopOutputSource identifies the value projected by a Loop output.
const ( LoopOutputBody LoopOutputSource = "body_output" LoopOutputVariable LoopOutputSource = "loop_variable" )
Loop output sources.
type LoopVariable ¶
type LoopVariable struct {
Name string `json:"name"`
Schema PortSchema `json:"schema"`
}
LoopVariable declares one Loop-local mutable value and its schema.
type MergeConfig ¶
type MergeConfig struct {
Mode MergeMode `json:"mode"`
Outputs map[string]MergeOutputConfig `json:"outputs"`
}
MergeConfig defines explicit output mappings for one Merge mode.
type MergeMode ¶
type MergeMode string
MergeMode selects mutually exclusive or parallel fan-in behavior.
type MergeNode ¶
type MergeNode struct{}
MergeNode joins mutually exclusive branches or wait-all parallel inputs.
func (MergeNode) Compile ¶
func (MergeNode) Compile( _ context.Context, _ CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type MergeOutputConfig ¶
type MergeOutputConfig struct {
Schema PortSchema `json:"schema"`
Sources []string `json:"sources"`
}
MergeOutputConfig maps one output to explicitly named node input candidates.
type NodeAddress ¶
type NodeAddress struct {
NodeID NodeID
Scope []ScopeFrame
}
NodeAddress identifies one node invocation inside its composite scope.
type NodeCompleted ¶
type NodeCompleted struct{}
NodeCompleted closes a successful invocation attempt.
type NodeDebugExecution ¶
type NodeDebugExecution struct {
Address NodeAddress
NodeRun NodeRun
Inputs map[string]Value
Outputs map[string]Value
Route string
ErrorMessage string
}
NodeDebugExecution is one detached node execution record. ErrorMessage may contain sensitive Action error text and must not be treated as an Event.
type NodeDebugPlan ¶
type NodeDebugPlan struct {
// contains filtered or unexported fields
}
NodeDebugPlan is an immutable, concurrent-safe isolated node execution plan.
func PrepareNodeDebug ¶
func PrepareNodeDebug(source *Plan, target NodePath) (*NodeDebugPlan, error)
PrepareNodeDebug derives an immutable isolated executable for target without invoking a node or mutating source.
func (*NodeDebugPlan) Fingerprint ¶
func (p *NodeDebugPlan) Fingerprint() string
Fingerprint returns the derived isolated executable identity.
func (*NodeDebugPlan) SourcePlanFingerprint ¶
func (p *NodeDebugPlan) SourcePlanFingerprint() string
SourcePlanFingerprint returns the exact source Plan identity.
func (*NodeDebugPlan) Spec ¶
func (p *NodeDebugPlan) Spec() NodeDebugSpec
Spec returns a detached explicit input and selected output/route contract.
func (*NodeDebugPlan) Target ¶
func (p *NodeDebugPlan) Target() NodePath
Target returns the original static path of the selected node.
type NodeDebugResult ¶
type NodeDebugResult struct {
RunID string
Target NodePath
Status RunStatus
Execution NodeDebugExecution
InnerExecutions []NodeDebugExecution
StartedAt time.Time
EndedAt time.Time
Interruption *InterruptInfo
}
NodeDebugResult is the detached result of one isolated node trial. Inputs, outputs, and ErrorMessage may contain sensitive application data.
Example (Composite) ¶
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
integerSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"integer"}`))
itemsSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"array","items":{"type":"string"}}`))
action := &fakeAction{
spec: actionSpec("map-item", map[string]workflow.PortSchema{
"item": stringSchema, "index": integerSchema,
}, map[string]workflow.PortSchema{"result": stringSchema}),
run: func(_ context.Context, input workflow.ActionInput) (workflow.ActionOutput, error) {
return workflow.ActionOutput{Values: map[string]workflow.Value{
"result": input.Values["item"],
}}, nil
},
}
body := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "map-body", Revision: "v1", Name: "Map Body",
Inputs: map[string]workflow.WorkflowInput{"item": {Schema: stringSchema, Required: true}, "index": {Schema: integerSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{
"result": nodeOutput(stringSchema, "map", "result"),
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "map", Type: workflow.NodeTypeAction, Version: workflow.BuiltinNodeVersion,
Config: json.RawMessage(`{"action":"map-item","version":"v1"}`),
Inputs: map[string]workflow.Binding{
"item": workflowInput("item"), "index": workflowInput("index"),
},
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "map"),
edge("map", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
config, _ := json.Marshal(workflow.BatchConfig{
Body: body, ResultOutput: "result", Mode: workflow.BatchParallel,
ErrorMode: workflow.BatchTerminate, MaxItems: 10, MaxConcurrency: 2,
})
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "batch-preview", Revision: "v1", Name: "Batch Preview",
Inputs: map[string]workflow.WorkflowInput{"items": {Schema: itemsSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{
"results": nodeOutput(itemsSchema, "batch", "results"),
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "batch", Type: workflow.NodeTypeBatch, Version: workflow.BuiltinNodeVersion,
Config: config, Inputs: map[string]workflow.Binding{"items": workflowInput("items")},
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "batch"),
edge("batch", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
registry, _ := workflow.NewDefaultRegistry(action)
plan, _ := workflow.Compile(context.Background(), definition, registry)
debugPlan, _ := workflow.PrepareNodeDebug(plan, workflow.NewNodePath("batch"))
runner, _ := workflow.NewRunner()
result, _ := runner.DebugNode(context.Background(), debugPlan, map[string]workflow.Value{
"items": workflow.MustValueOf([]string{"a", "b"}),
})
fmt.Println(result.Execution.Outputs["results"].String())
for _, inner := range result.InnerExecutions {
fmt.Println(inner.Address.NodeID, inner.Address.Scope[0].Index)
}
Output: ["a","b"] map 0 map 1
type NodeDebugSpec ¶
type NodeDebugSpec struct {
Inputs map[string]PortSchema
OptionalInputs []string
Outputs map[string]PortSchema
Routes []string
}
NodeDebugSpec is the explicit caller contract for one isolated node trial. Literal-bound inputs are retained by the prepared plan and are not exposed.
type NodeDefinition ¶
type NodeDefinition struct {
ID NodeID `json:"id"`
Name string `json:"name,omitempty"`
Type NodeTypeKey `json:"type"`
Version string `json:"version"`
Config json.RawMessage `json:"config,omitempty"`
Inputs map[string]Binding `json:"inputs,omitempty"`
Policy NodePolicy `json:"policy,omitzero"`
}
NodeDefinition is one version-pinned node instance.
type NodeExecution ¶
type NodeExecution struct {
DefinitionID DefinitionID
Revision Revision
DefinitionFingerprint string
PlanFingerprint string
RunID string
Address NodeAddress
NodeRun NodeRun
Inputs map[string]Value
Outputs map[string]Value
Route string
ErrorMessage string
}
NodeExecution is one detached, storage-neutral snapshot of an actual node invocation. RunID and Address form its logical upsert identity. Inputs, outputs, and error text may contain sensitive application data; hosts own persistence, redaction, encryption, retention, and transport schemas.
func (NodeExecution) MarshalJSON ¶
func (NodeExecution) MarshalJSON() ([]byte, error)
MarshalJSON rejects an accidental unversioned wire format for sensitive process-local execution data.
func (*NodeExecution) UnmarshalJSON ¶
func (*NodeExecution) UnmarshalJSON([]byte) error
UnmarshalJSON rejects an accidental unversioned wire format for sensitive process-local execution data.
type NodeExecutionRecorder ¶
type NodeExecutionRecorder func(context.Context, NodeExecution)
NodeExecutionRecorder synchronously receives running and effective outcome snapshots for ordinary Run and Resume operations. Implementations handle their own persistence errors and timeouts and must not panic.
Calls are serialized within one Run. The same recorder may be called concurrently by separate Runs.
type NodeFailed ¶
type NodeFailed struct {
Kind FailureKind
}
NodeFailed closes a failed invocation attempt without retaining error text.
type NodeInterrupted ¶
type NodeInterrupted struct{}
NodeInterrupted reports an invocation suspended by a dynamic or descendant interruption.
type NodeOutput ¶
NodeOutput contains immutable output values and the selected control route.
type NodePath ¶
type NodePath struct {
// contains filtered or unexported fields
}
NodePath identifies one node through zero or more composite node boundaries. NewNodePath and Nodes detach their slices so a path is safe to reuse.
func NewNodePath ¶
NewNodePath creates an immutable node path. Compile rejects an empty path or an invalid or unresolved segment.
type NodePolicy ¶
type NodePolicy struct {
TimeoutMilli int64 `json:"timeout_ms,omitempty"`
Retry RetryPolicy `json:"retry,omitzero"`
Error ErrorAction `json:"error,omitempty"`
DefaultOutputs map[string]Value `json:"default_outputs,omitempty"`
}
NodePolicy bounds one node invocation and defines its explicit error path.
type NodeReady ¶
type NodeReady struct{}
NodeReady reports that every incoming control edge has resolved and at least one was taken.
type NodeRetrying ¶
type NodeRetrying struct {
NextAttempt int
}
NodeRetrying reports that another bounded attempt will start.
type NodeRun ¶
type NodeRun struct {
ID NodeID
Type NodeTypeKey
Status NodeStatus
Attempts int
Failure FailureKind
StartedAt time.Time
EndedAt time.Time
}
NodeRun is an immutable node execution summary.
type NodeSkipped ¶
type NodeSkipped struct{}
NodeSkipped reports that every incoming control edge was skipped.
type NodeSpec ¶
type NodeSpec struct {
Inputs map[string]PortSchema
Outputs map[string]PortSchema
Routes []string
}
NodeSpec is the immutable input, output, and route contract produced while compiling one node instance.
type NodeStatus ¶
type NodeStatus string
NodeStatus identifies one node lifecycle state.
const ( NodeStatusPending NodeStatus = "pending" NodeStatusReady NodeStatus = "ready" NodeStatusRunning NodeStatus = "running" NodeStatusSucceeded NodeStatus = "succeeded" NodeStatusException NodeStatus = "exception" NodeStatusFailed NodeStatus = "failed" NodeStatusSkipped NodeStatus = "skipped" NodeStatusInterrupted NodeStatus = "interrupted" )
Node states.
type NodeType ¶
type NodeType interface {
Spec() NodeTypeSpec
Compile(context.Context, CompileContext, NodeDefinition) (CompiledNode, error)
}
NodeType compiles one trusted, application-linked node implementation.
func BuiltinNodeTypes ¶
func BuiltinNodeTypes() []NodeType
BuiltinNodeTypes returns independent registrations for the built-in Workflow nodes.
type NodeTypeKey ¶
type NodeTypeKey string
NodeTypeKey identifies a registered node implementation family.
const ( // BuiltinNodeVersion is the exact version of all first-version built-ins. BuiltinNodeVersion = "v1" // MergeNodeVersionV2 selects the first non-null candidate in source order. MergeNodeVersionV2 = "v2" // NodeTypeStart identifies [StartNode]. NodeTypeStart NodeTypeKey = "start" // NodeTypeEnd identifies [EndNode]. NodeTypeEnd NodeTypeKey = "end" // NodeTypeAction identifies [ActionNode]. NodeTypeAction NodeTypeKey = "action" // NodeTypeCondition identifies [ConditionNode]. NodeTypeCondition NodeTypeKey = "condition" // NodeTypeMerge identifies [MergeNode]. NodeTypeMerge NodeTypeKey = "merge" // NodeTypeSelector identifies [SelectorNode]. NodeTypeSelector NodeTypeKey = "selector" // NodeTypeSubWorkflow identifies [SubWorkflowNode]. NodeTypeSubWorkflow NodeTypeKey = "sub_workflow" // NodeTypeBatch identifies [BatchNode]. NodeTypeBatch NodeTypeKey = "batch" // NodeTypeLoop identifies [LoopNode]. NodeTypeLoop NodeTypeKey = "loop" // NodeTypeBreak identifies [BreakNode]. NodeTypeBreak NodeTypeKey = "break" // NodeTypeContinue identifies [ContinueNode]. NodeTypeContinue NodeTypeKey = "continue" // NodeTypeSetVariable identifies [SetVariableNode]. NodeTypeSetVariable NodeTypeKey = "set_variable" // RouteSuccess is the normal completion route. RouteSuccess = "success" // RouteError is selected by ErrorRoute after invocation failure. RouteError = "error" )
type NodeTypeSpec ¶
type NodeTypeSpec struct {
Key NodeTypeKey
Version string
DisplayName string
}
NodeTypeSpec identifies one registered node implementation.
type OutputBinding ¶
type OutputBinding struct {
Schema PortSchema `json:"schema"`
Binding Binding `json:"binding"`
}
OutputBinding declares one Workflow output contract and its value source.
type PartialDataOrigin ¶
type PartialDataOrigin string
PartialDataOrigin identifies how one node obtained its effective result in a Partial Run. Its zero value means no result was materialized or executed.
const ( PartialDataExecuted PartialDataOrigin = "executed" PartialDataPinned PartialDataOrigin = "pinned" PartialDataReused PartialDataOrigin = "reused" )
Partial Run data origins.
type PartialNodeData ¶
PartialNodeData is one reusable successful node result.
type PartialNodeRun ¶
type PartialNodeRun struct {
NodeRun NodeRun
Origin PartialDataOrigin
}
PartialNodeRun combines one node summary with its Partial Run data origin.
type PartialRunData ¶
type PartialRunData struct {
RunID string
DefinitionID DefinitionID
Revision Revision
SourcePlanFingerprint string
Nodes map[NodeID]PartialNodeData
}
PartialRunData is a detached, host-persistable snapshot produced by a Partial Run. It is prior execution data, not a resumable checkpoint.
type PartialRunInput ¶
type PartialRunInput struct {
Inputs map[string]Value
Previous *PartialRunData
Pins PinData
Dirty []NodeID
}
PartialRunInput supplies Workflow inputs and optional host-owned development data for Runner.RunPartial.
type PartialRunResult ¶
type PartialRunResult struct {
RunID string
Destination NodeID
SourcePlanFingerprint string
PlanFingerprint string
Status RunStatus
Outputs map[string]Value
Nodes map[NodeID]PartialNodeRun
Data PartialRunData
StartedAt time.Time
EndedAt time.Time
Interruption *InterruptInfo
}
PartialRunResult is a detached snapshot of one terminal or interrupted Partial Run. Data can be persisted by the host and supplied as Previous to a later Partial Run.
type PinData ¶
PinData maps root node IDs to explicit successful output snapshots used by Runner.RunPartial. Pins are development data and are never consulted by Runner.Run or Runner.Resume.
type Plan ¶
type Plan struct {
// contains filtered or unexported fields
}
Plan is an immutable, concurrent-safe compiled Workflow execution plan.
func Compile ¶
func Compile( ctx context.Context, definition Definition, registry *Registry, options ...CompileOption, ) (*Plan, error)
Compile validates definition against registry and returns an immutable Plan.
func (*Plan) DefinitionFingerprint ¶
DefinitionFingerprint returns the semantic Definition fingerprint.
func (*Plan) DefinitionID ¶
func (p *Plan) DefinitionID() DefinitionID
DefinitionID returns the logical Workflow identity pinned by p.
func (*Plan) Fingerprint ¶
Fingerprint returns the Definition and referenced execution-contract identity.
func (*Plan) RegistryFingerprint ¶
RegistryFingerprint returns the complete source Registry contract fingerprint.
type PortSchema ¶
type PortSchema struct {
// contains filtered or unexported fields
}
PortSchema is an immutable JSON Schema draft 2020-12 contract. External references are rejected because schemas are resolved without a loader.
func ParsePortSchema ¶
func ParsePortSchema(data []byte) (PortSchema, error)
ParsePortSchema validates, resolves, and snapshots a JSON Schema.
func SchemaFor ¶
func SchemaFor[T any]() (PortSchema, error)
SchemaFor derives a PortSchema from T using encoding/json field names.
func (PortSchema) Equal ¶
func (s PortSchema) Equal(other PortSchema) bool
Equal reports whether two schemas have the same canonical representation.
func (PortSchema) Fingerprint ¶
func (s PortSchema) Fingerprint() string
Fingerprint returns the SHA-256 digest of the canonical schema.
func (PortSchema) IsValid ¶
func (s PortSchema) IsValid() bool
IsValid reports whether s contains a resolved schema.
func (PortSchema) MarshalJSON ¶
func (s PortSchema) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
func (PortSchema) RawJSON ¶
func (s PortSchema) RawJSON() []byte
RawJSON returns an independent canonical JSON representation.
func (*PortSchema) UnmarshalJSON ¶
func (s *PortSchema) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler.
func (PortSchema) Validate ¶
func (s PortSchema) Validate(value Value) (returnErr error)
Validate checks value against s.
type Predicate ¶
type Predicate struct {
Op PredicateOp `json:"op"`
Input string `json:"input,omitempty"`
Path []string `json:"path,omitempty"`
Value *Value `json:"value,omitempty"`
Values []Value `json:"values,omitempty"`
Args []Predicate `json:"args,omitempty"`
}
Predicate is a bounded, serializable Condition expression. Leaf operations read Input and Path; boolean operations contain Args.
type PredicateOp ¶
type PredicateOp string
PredicateOp identifies one safe Condition predicate operation.
const ( PredicateExists PredicateOp = "exists" PredicateEqual PredicateOp = "eq" PredicateNotEqual PredicateOp = "ne" PredicateGreater PredicateOp = "gt" PredicateGreaterOrEqual PredicateOp = "gte" PredicateLess PredicateOp = "lt" PredicateLessOrEqual PredicateOp = "lte" PredicateIn PredicateOp = "in" PredicateAll PredicateOp = "all" PredicateAny PredicateOp = "any" PredicateNot PredicateOp = "not" )
Condition predicate operations.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is an immutable, concurrent-safe snapshot of NodeTypes and Actions.
func NewDefaultRegistry ¶
NewDefaultRegistry creates a Registry containing the built-in node types and the supplied Actions.
func NewRegistry ¶
NewRegistry validates and freezes explicitly supplied NodeTypes and Actions.
func (*Registry) Fingerprint ¶
Fingerprint identifies the complete NodeType and Action contract catalog.
type ResumeTarget ¶
ResumeTarget supplies optional data to one dynamic interruption ID.
type RetryPolicy ¶
type RetryPolicy struct {
MaxAttempts int `json:"max_attempts,omitempty"`
BackoffMilli int64 `json:"backoff_ms,omitempty"`
}
RetryPolicy bounds retries for one node. Zero MaxAttempts means one attempt and therefore no retry.
type RunCompleted ¶
type RunCompleted struct{}
RunCompleted closes a succeeded or partial-succeeded Run.
type RunIDSource ¶
RunIDSource creates one Run ID from the Run start time.
type RunInterruptOption ¶
type RunInterruptOption func(*runInterruptOptions)
RunInterruptOption configures one external host interruption request.
func WithRunInterruptTimeout ¶
func WithRunInterruptTimeout(timeout time.Duration) RunInterruptOption
WithRunInterruptTimeout bounds how long the scheduler waits for in-flight invocations to settle. Zero and negative durations request immediate cooperative cancellation of unfinished leaf invocations.
type RunInterrupted ¶
type RunInterrupted struct{}
RunInterrupted reports that a resumable checkpoint was saved.
type RunResult ¶
type RunResult struct {
RunID string
Status RunStatus
Outputs map[string]Value
Nodes map[NodeID]NodeRun
StartedAt time.Time
EndedAt time.Time
Interruption *InterruptInfo
}
RunResult is a detached snapshot of one terminal or interrupted Run. An interrupted result keeps EndedAt zero and exposes its resumable frontier in Interruption. Callers may mutate its maps without affecting runtime state.
type RunResumed ¶
type RunResumed struct{}
RunResumed reports that a checkpoint was validated and execution continued.
type RunStatus ¶
type RunStatus string
RunStatus identifies one Run lifecycle state.
const ( RunStatusPending RunStatus = "pending" RunStatusRunning RunStatus = "running" RunStatusSucceeded RunStatus = "succeeded" RunStatusPartialSucceeded RunStatus = "partial-succeeded" RunStatusFailed RunStatus = "failed" RunStatusCanceled RunStatus = "canceled" RunStatusInterrupted RunStatus = "interrupted" )
Run states.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner synchronously executes immutable Plans in process.
func NewRunner ¶
func NewRunner(options ...RunnerOption) (*Runner, error)
NewRunner creates a Runner with cryptographically random Run IDs.
func (*Runner) DebugNode ¶
func (r *Runner) DebugNode( ctx context.Context, debugPlan *NodeDebugPlan, inputs map[string]Value, ) (NodeDebugResult, error)
DebugNode executes only the selected node boundary through the ordinary Workflow scheduler. Registered Actions are real and may have side effects.
Example ¶
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
action := &fakeAction{
spec: actionSpec("preview", map[string]workflow.PortSchema{
"prompt": stringSchema,
}, map[string]workflow.PortSchema{"result": stringSchema}),
run: func(_ context.Context, input workflow.ActionInput) (workflow.ActionOutput, error) {
return workflow.ActionOutput{Values: map[string]workflow.Value{
"result": input.Values["prompt"],
}}, nil
},
}
registry, _ := workflow.NewDefaultRegistry(action)
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "preview-flow", Revision: "v1", Name: "Preview Flow",
Inputs: map[string]workflow.WorkflowInput{"prompt": {Schema: stringSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{
"result": nodeOutput(stringSchema, "preview", "result"),
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "preview", Type: workflow.NodeTypeAction, Version: workflow.BuiltinNodeVersion,
Config: json.RawMessage(`{"action":"preview","version":"v1"}`),
Inputs: map[string]workflow.Binding{"prompt": workflowInput("prompt")},
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "preview"),
edge("preview", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
plan, _ := workflow.Compile(context.Background(), definition, registry)
debugPlan, _ := workflow.PrepareNodeDebug(plan, workflow.NewNodePath("preview"))
runner, _ := workflow.NewRunner(
workflow.WithRunIDSource(func(time.Time) (string, error) { return "preview-run", nil }),
)
result, _ := runner.DebugNode(context.Background(), debugPlan, map[string]workflow.Value{
"prompt": workflow.MustValueOf("paper city"),
})
fmt.Println(result.RunID, result.Status, result.Execution.Route)
fmt.Println(result.Execution.Outputs["result"].String())
Output: preview-run succeeded success "paper city"
func (*Runner) Resume ¶
func (r *Runner) Resume( ctx context.Context, plan *Plan, runID string, targets []ResumeTarget, ) (RunResult, error)
Resume validates and restores one interrupted Run from its CheckpointStore. Dynamic targets are validated as one set before any node is invoked.
func (*Runner) ResumeNodeDebug ¶
func (r *Runner) ResumeNodeDebug( ctx context.Context, debugPlan *NodeDebugPlan, runID string, targets []ResumeTarget, ) (NodeDebugResult, error)
ResumeNodeDebug resumes one interrupted isolated node trial. The exact same NodeDebugPlan and Run ID are required before any node can be invoked.
Example ¶
action := &fakeAction{
spec: actionSpec("resume-preview", map[string]workflow.PortSchema{}, map[string]workflow.PortSchema{}),
}
registry, _ := workflow.NewDefaultRegistry(action)
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "resume-preview", Revision: "v1", Name: "Resume Preview",
Inputs: map[string]workflow.WorkflowInput{}, Outputs: map[string]workflow.OutputBinding{},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "work", Type: workflow.NodeTypeAction, Version: workflow.BuiltinNodeVersion,
Config: json.RawMessage(`{"action":"resume-preview","version":"v1"}`),
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "work"),
edge("work", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
plan, _ := workflow.Compile(
context.Background(), definition, registry,
workflow.WithInterruptBeforeNodes(workflow.NewNodePath("work")),
)
debugPlan, _ := workflow.PrepareNodeDebug(plan, workflow.NewNodePath("work"))
store := &memoryCheckpointStore{}
runner, _ := workflow.NewRunner(
workflow.WithCheckpointStore(store),
workflow.WithRunIDSource(func(time.Time) (string, error) { return "resume-preview-run", nil }),
)
paused, _ := runner.DebugNode(context.Background(), debugPlan, map[string]workflow.Value{})
completed, _ := runner.ResumeNodeDebug(
context.Background(), debugPlan, paused.RunID, nil,
)
fmt.Println(paused.Status, completed.Status, completed.RunID)
Output: interrupted succeeded resume-preview-run
func (*Runner) ResumePartial ¶
func (r *Runner) ResumePartial( ctx context.Context, source *Plan, destination NodeID, runID string, targets []ResumeTarget, ) (PartialRunResult, error)
ResumePartial resumes one interrupted Partial Run. The exact same source Plan, destination, Run ID, and outstanding dynamic targets are required before any node can be invoked.
func (*Runner) Run ¶
func (r *Runner) Run( ctx context.Context, plan *Plan, inputs map[string]Value, ) (RunResult, error)
Run validates inputs, executes plan, and waits for every Runner-owned goroutine before returning. Timeouts and cancellation are cooperative: Actions must return when their context is done.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/rsbin1178/pips/workflow"
)
func edge(from workflow.NodeID, route string, to workflow.NodeID) workflow.ControlEdge {
return workflow.ControlEdge{From: workflow.NodeRoute{Node: from, Route: route}, To: to}
}
func main() {
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1,
ID: "example",
Revision: "v1",
Name: "Example",
Inputs: map[string]workflow.WorkflowInput{"input": {Schema: stringSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{
"result": {
Schema: stringSchema,
Binding: workflow.Binding{
Source: workflow.BindingWorkflowInput,
Port: "input",
},
},
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
edge("start", workflow.RouteSuccess, "end"),
},
Limits: workflow.DefaultLimits(),
}
registry, _ := workflow.NewDefaultRegistry()
plan, _ := workflow.Compile(context.Background(), definition, registry)
runner, _ := workflow.NewRunner(
workflow.WithRunIDSource(func(time.Time) (string, error) { return "example-run", nil }),
)
result, _ := runner.Run(
context.Background(),
plan,
map[string]workflow.Value{"input": workflow.MustValueOf("hello")},
)
fmt.Println(result.Status, result.Outputs["result"].String())
}
Output: succeeded "hello"
func (*Runner) RunPartial ¶
func (r *Runner) RunPartial( ctx context.Context, source *Plan, destination NodeID, input PartialRunInput, ) (PartialRunResult, error)
RunPartial executes only the root dependency slice needed to settle destination. Previous results and Pins are development data boundaries; registered Actions that do execute are real and may have side effects.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/rsbin1178/pips/workflow"
)
type partialRunExampleAction struct {
schema workflow.PortSchema
}
func (a partialRunExampleAction) Spec() workflow.ActionSpec {
return workflow.ActionSpec{
Key: "render-preview", Version: "v1",
Inputs: map[string]workflow.PortSchema{"prompt": a.schema},
Outputs: map[string]workflow.PortSchema{"image": a.schema},
}
}
func (a partialRunExampleAction) Run(
_ context.Context,
input workflow.ActionInput,
) (workflow.ActionOutput, error) {
prompt, err := workflow.DecodeValue[string](input.Values["prompt"])
if err != nil {
return workflow.ActionOutput{}, err
}
return workflow.ActionOutput{Values: map[string]workflow.Value{
"image": workflow.MustValueOf("preview:" + prompt),
}}, nil
}
func main() {
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
config, _ := json.Marshal(workflow.ActionConfig{Action: "render-preview", Version: "v1"})
registry, _ := workflow.NewDefaultRegistry(partialRunExampleAction{schema: stringSchema})
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "preview", Revision: "v1", Name: "Preview",
Inputs: map[string]workflow.WorkflowInput{"prompt": {Schema: stringSchema, Required: true}},
Outputs: map[string]workflow.OutputBinding{
"image": {
Schema: stringSchema,
Binding: workflow.Binding{
Source: workflow.BindingNodeOutput, Node: "render", Port: "image",
},
},
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "render", Type: workflow.NodeTypeAction, Version: workflow.BuiltinNodeVersion,
Config: config,
Inputs: map[string]workflow.Binding{
"prompt": {
Source: workflow.BindingNodeOutput, Node: "start", Port: "prompt",
},
},
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
{From: workflow.NodeRoute{Node: "start", Route: workflow.RouteSuccess}, To: "render"},
{From: workflow.NodeRoute{Node: "render", Route: workflow.RouteSuccess}, To: "end"},
},
Limits: workflow.DefaultLimits(),
}
plan, _ := workflow.Compile(context.Background(), definition, registry)
runner, _ := workflow.NewRunner()
first, _ := runner.RunPartial(context.Background(), plan, "render", workflow.PartialRunInput{
Inputs: map[string]workflow.Value{"prompt": workflow.MustValueOf("paper city")},
})
second, _ := runner.RunPartial(context.Background(), plan, "render", workflow.PartialRunInput{
Inputs: map[string]workflow.Value{},
Previous: &first.Data,
})
fmt.Println(second.Outputs["image"].String())
fmt.Println(second.Nodes["start"].Origin, second.Nodes["render"].Origin)
}
Output: "preview:paper city" reused executed
type RunnerOption ¶
type RunnerOption func(*runnerConfig) error
RunnerOption configures a Runner.
func WithCheckpointStore ¶
func WithCheckpointStore(store CheckpointStore) RunnerOption
WithCheckpointStore configures opaque checkpoint persistence for interrupted Runs and later Resume calls.
func WithClock ¶
func WithClock(clock func() time.Time) RunnerOption
WithClock replaces the Runner clock, primarily for deterministic tests.
func WithEventSink ¶
func WithEventSink(sink EventSink) RunnerOption
WithEventSink observes lifecycle metadata without input, output, config, or Action error payloads.
func WithNodeExecutionRecorder ¶
func WithNodeExecutionRecorder(recorder NodeExecutionRecorder) RunnerOption
WithNodeExecutionRecorder observes sensitive, storage-neutral node execution snapshots from ordinary Run and Resume operations.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/rsbin1178/pips/workflow"
)
type nodeExecutionExampleAction struct {
schema workflow.PortSchema
}
func (a nodeExecutionExampleAction) Spec() workflow.ActionSpec {
return workflow.ActionSpec{
Key: "record-example", Version: "v1",
Inputs: map[string]workflow.PortSchema{},
Outputs: map[string]workflow.PortSchema{"result": a.schema},
}
}
func (nodeExecutionExampleAction) Run(
context.Context,
workflow.ActionInput,
) (workflow.ActionOutput, error) {
return workflow.ActionOutput{Values: map[string]workflow.Value{
"result": workflow.MustValueOf("stored"),
}}, nil
}
func main() {
stringSchema, _ := workflow.ParsePortSchema([]byte(`{"type":"string"}`))
definition := workflow.Definition{
Schema: workflow.SchemaV1Alpha1, ID: "record-example", Revision: "v1", Name: "Record example",
Inputs: map[string]workflow.WorkflowInput{},
Outputs: map[string]workflow.OutputBinding{
"result": {
Schema: stringSchema,
Binding: workflow.Binding{
Source: workflow.BindingNodeOutput, Node: "action", Port: "result",
},
},
},
Nodes: []workflow.NodeDefinition{
{ID: "start", Type: workflow.NodeTypeStart, Version: workflow.BuiltinNodeVersion},
{
ID: "action", Type: workflow.NodeTypeAction, Version: workflow.BuiltinNodeVersion,
Config: json.RawMessage(`{"action":"record-example","version":"v1"}`),
},
{ID: "end", Type: workflow.NodeTypeEnd, Version: workflow.BuiltinNodeVersion},
},
Edges: []workflow.ControlEdge{
{From: workflow.NodeRoute{Node: "start", Route: workflow.RouteSuccess}, To: "action"},
{From: workflow.NodeRoute{Node: "action", Route: workflow.RouteSuccess}, To: "end"},
},
Limits: workflow.DefaultLimits(),
}
registry, _ := workflow.NewDefaultRegistry(nodeExecutionExampleAction{schema: stringSchema})
plan, _ := workflow.Compile(context.Background(), definition, registry)
// The host's recorder can upsert by RunID + Address. It handles its own
// storage timeout and persistence errors without returning them to Runner.
runner, _ := workflow.NewRunner(
workflow.WithRunIDSource(func(time.Time) (string, error) { return "history-run", nil }),
workflow.WithNodeExecutionRecorder(func(ctx context.Context, record workflow.NodeExecution) {
storeCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
if record.Address.NodeID != "action" || record.NodeRun.Status == workflow.NodeStatusRunning {
return
}
// A real application would call its repository here and log any error.
_ = storeCtx
fmt.Println(record.RunID, record.Address.NodeID, record.NodeRun.Status, record.Route)
}),
)
_, _ = runner.Run(context.Background(), plan, map[string]workflow.Value{})
}
Output: history-run action succeeded success
func WithRunIDSource ¶
func WithRunIDSource(source RunIDSource) RunnerOption
WithRunIDSource replaces Run ID generation, primarily for deterministic tests and host correlation policies.
type ScopeFrame ¶
ScopeFrame identifies the composite node that owns one child execution. Index is -1 for SubWorkflow and the input index for Batch or Loop.
type SelectorCase ¶
SelectorCase maps one structured predicate to a control route.
type SelectorConfig ¶
type SelectorConfig struct {
Cases []SelectorCase `json:"cases"`
DefaultRoute string `json:"default_route"`
}
SelectorConfig defines ordered cases and one fallback route.
type SelectorNode ¶
type SelectorNode struct{}
SelectorNode chooses the first matching route or its default route.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/rsbin1178/pips/workflow"
)
func main() {
trueValue := workflow.MustValueOf(true)
config, _ := json.Marshal(workflow.SelectorConfig{
Cases: []workflow.SelectorCase{
{
Route: "approved",
Predicate: workflow.Predicate{
Op: workflow.PredicateEqual, Input: "value", Value: &trueValue,
},
},
},
DefaultRoute: "rejected",
})
executor, _ := (workflow.SelectorNode{}).Compile(
context.Background(),
nil,
workflow.NodeDefinition{
ID: "selector",
Config: config,
Inputs: map[string]workflow.Binding{
"value": {
Source: workflow.BindingLiteral,
Value: &trueValue,
},
},
},
)
output, _ := executor.Invoke(context.Background(), workflow.NodeInput{
Values: map[string]workflow.Value{"value": trueValue},
})
fmt.Println(output.Route)
}
Output: approved
func (SelectorNode) Compile ¶
func (SelectorNode) Compile( _ context.Context, _ CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type SetVariableAssignment ¶
SetVariableAssignment maps one node input to one Loop variable.
type SetVariableConfig ¶
type SetVariableConfig struct {
Assignments []SetVariableAssignment `json:"assignments"`
}
SetVariableConfig declares an atomic group of Loop-variable assignments.
type SetVariableNode ¶
type SetVariableNode struct{}
SetVariableNode atomically assigns values to Loop-local variables.
func (SetVariableNode) Compile ¶
func (SetVariableNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type StartNode ¶
type StartNode struct{}
StartNode declares Workflow inputs and starts control flow.
func (StartNode) Compile ¶
func (StartNode) Compile( _ context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type SubWorkflowConfig ¶
type SubWorkflowConfig struct {
Workflow DefinitionRef `json:"workflow"`
}
SubWorkflowConfig pins the child Workflow executed by a SubWorkflow node.
type SubWorkflowNode ¶
type SubWorkflowNode struct{}
SubWorkflowNode synchronously executes one exact referenced Workflow.
func (SubWorkflowNode) Compile ¶
func (SubWorkflowNode) Compile( ctx context.Context, compileContext CompileContext, definition NodeDefinition, ) (CompiledNode, error)
Compile implements NodeType.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is an immutable, canonical JSON value. Its zero value is invalid; construct values with ParseValue or ValueOf.
func GetInterruptState ¶
GetInterruptState reports state saved by the previously interrupted direct invocation.
func GetResumeContext ¶
GetResumeContext reports whether the current invocation is a direct target or an ancestor of one. Only a direct target receives data.
func MustValueOf ¶
MustValueOf is like ValueOf but panics when value is not JSON-compatible. It is intended for package-level declarations and tests.
func ParseValue ¶
ParseValue validates and snapshots one JSON value.
func (Value) Equal ¶
Equal reports equality of the canonical, number-preserving JSON snapshots. Object key order does not affect the result.
func (Value) Lookup ¶
Lookup resolves an object key or array index path without exposing mutable storage. It returns false when any path segment is absent or incompatible.
func (Value) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (Value) String ¶
String returns v's canonical JSON representation. Invalid values render as an empty string.
func (*Value) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type WorkflowInput ¶
type WorkflowInput struct {
Schema PortSchema `json:"schema"`
Required bool `json:"required,omitempty"`
Default *Value `json:"default,omitempty"`
}
WorkflowInput declares one Workflow-boundary input contract. A non-null Default applies to a missing optional input and to a supplied empty string, array, or object of the same kind.
Source Files
¶
- batch.go
- checkpoint.go
- checkpoint_composite.go
- compile_error.go
- compiler.go
- compiler_binding.go
- compiler_fingerprint.go
- compiler_graph.go
- compiler_node.go
- composite.go
- definition.go
- definition_wire.go
- doc.go
- errors.go
- event.go
- execution_context.go
- failure.go
- input.go
- interrupt.go
- interrupt_compile.go
- interrupt_dynamic.go
- interrupt_host.go
- json.go
- loop.go
- loop_control.go
- node.go
- node_debug.go
- node_debug_plan.go
- node_debug_record.go
- node_debug_run.go
- node_execution.go
- partial_run.go
- partial_run_checkpoint.go
- partial_run_data.go
- partial_run_execute.go
- partial_run_plan.go
- registry.go
- runner.go
- runner_binding.go
- runner_checkpoint.go
- runner_child.go
- runner_event.go
- runner_execution.go
- runner_invoke.go
- schema.go
- selector.go
- subworkflow.go
- value.go