engine

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Agent memory: per-thread conversation transcripts for the ai-agent block, persisted in the runtime KV store. An ai-agent with a memoryThreadId loads the prior transcript before its run and saves the accumulated transcript after, compacting it when it grows past its token budget. The clear-agent-memory leaf block wipes a thread. All memory objects live in the user namespace under a dedicated prefix so they never collide with object-read/write keys.

Caching built on the runtime KV store: the cache-scope composite memoizes the body its wrapped flow produces, and the invalidate-cache leaf evicts an entry. Both key the user namespace (core.NamespaceUser) by the SHA-256 of an evaluated CEL key, so an invalidate-cache with the same key expression targets the same entry a cache-scope wrote.

The KV store has no native TTL, so cache-scope encodes the expiry inside the stored value (cacheEnvelope) and checks it on read; an expired entry is treated as a miss and overwritten on the next run. Only the message body is cached: variables the wrapped flow sets are not restored on a hit.

Package engine assembles and runs message-processing flows. It is the runtime's pipeline implementation: the Flow type, the builder that turns a FlowConfig into a tree of leaf and composite blocks, the composite kinds (scope, fork, if, switch, foreach), and the built-in setter blocks. It is internal — callers wire flows through the public core package and the runtime service.

Built-in flow-ref block: invokes another flow by name. It registers on the process-wide block registry like the other built-ins. A flow-ref calls a flow that has no external source (an implicit-source flow), reached through the flow caller wired into BlockDeps.

Built-in leaf blocks that read and write objects in the runtime KV store: object-read and object-write. They register on the process-wide block registry so they are always available once the engine is linked, and reach the store through the runtime services carried on the context (core.RuntimeServicesFromContext), so no connector is required.

Both confine themselves to the user namespace (core.NamespaceUser): the store isolates keys per namespace, so a user flow's objects never collide with or expose internal runtime state. Each block compiles its CEL expressions once at build time, so a malformed expression fails at startup rather than per message.

Schema-only metadata for composite (control-flow) blocks. Composites are not leaf blocks: they are dispatched by the flow builder (flow.go) and read their typed sub-flow slots off types.BlockConfig, so they have no settings struct to reflect. Instead each declares a schema-only meta struct here — never decoded, only reflected for the editor schema — whose fields carry octo slot tags. A pure sub-flow slot uses a *struct{} placeholder since type=flow overrides inference and no value is read from it.

Built-in leaf blocks that mutate the message: set-payload, set-variable, and delete-variable. They register on the process-wide block registry so they are always available once the engine is linked, without importing the optional processors module. Each compiles its CEL expression once at build time, so a malformed expression fails at startup rather than per message.

The multi-transform leaf block applies an ordered sequence of CEL edits to the message in one pass. Each step either sets the body (setBody) or a variable (setVar/value); the edits are additive, so a later step's expression sees the results of the earlier ones (the activation is rebuilt before every step). It lets a flow compress a chain of set-payload / set-variable blocks into a single block while keeping every expression's surface identical to those blocks.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetErrorVariable

func SetErrorVariable(msg *types.Message, name string, err error)

SetErrorVariable exposes a processing error to a recovery path as the structured message variable vars.error:

{ "message": <err.Error()>, "flow": <name>, "block": <failing block label> }

name is the enclosing flow or handle-errors block name. block is recovered from the error chain via errors.As when the error originated in a leaf block, and is empty otherwise. It is a map[string]any so CEL expressions can read vars.error.message, vars.error.flow, and vars.error.block.

Types

type Flow

type Flow struct {
	Name   string
	Blocks []core.Block
}

Flow is an ordered sequence of blocks. It implements core.MessageProcessor by running a message through each block in order, and is the reusable unit that composite blocks embed. A Flow has no source; the runtime binds the root flow to a source. A nil result from a block drops the message (the chain stops); an error aborts it.

func BuildRoot

func BuildRoot(
	cfg types.FlowConfig,
	blocks *core.BlockRegistry,
	p *pool.Pool,
	processors []types.ProcessorConfig,
	deps core.BlockDeps,
) (*Flow, error)

BuildRoot assembles the root Flow for a top-level flow config, resolving named processor definitions and threading the shared pool and block deps used by leaf and composite blocks.

func (*Flow) Process

func (f *Flow) Process(ctx context.Context, msg *types.Message) (*types.Message, error)

Process runs msg through the flow's blocks in order. It returns the final message, or (nil, nil) if a block dropped it, or an error if a block aborted.

Jump to

Keyboard shortcuts

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