Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Define a Loop

Describe loop.Define, loop.Definition, and immutable loop configuration.

developer

loop.Define is the only constructor for a public loop.Definition:

func Define(opts ...Option) (Definition, error)

The zero value of Definition is invalid. A successful result owns copies of models, modes, tool-definition slices, delegates, context transports, and the optional output schema. Reusing the same options to create a second definition does not make the definitions share those mutable containers.

Definition options

Option is declared as type Option func(*definitionOptions) error; callers normally use the exported option functions below.

OptionEffect and validation
WithName(identity.AgentName)required nonblank registration name
WithInference(inference.Client, model.Model)required client and structurally valid model/key/effort
WithSystem(string)base system instructions
WithDisplayName(string), WithDescription(string)presentation metadata; description participates in Rig topology identity
WithOutputSchema(inference.OutputSchema)clones and validates a final structured-output policy
WithTools(...tool.Definition)additive declared factories; names must be nonblank and not reserved
WithAccessGate(AccessGate)fail-closed prepared-request gate; requires policy revision
WithToolMiddlewares(...tool.ToolMiddleware)additive middleware; nil entries are rejected and require policy revision
WithToolLimits(ToolLimits)singleton base limits; zero fields receive defaults
WithDrainTimeout(time.Duration)singleton nonnegative shutdown drain timeout; zero becomes five seconds
WithEngine(Engine)native or foreign engine marker; EngineAdapter is bind-time only and rejected here
WithRuntimeContext(RuntimeContextProvider)per-turn volatile blocks; nil is rejected and requires policy revision
WithPolicyRevision(string)stable identity for opaque policy collaborators
WithDelegates(...identity.AgentName)additive allowed child names
WithDelegation(Delegation)DelegationSyncOnly or DelegationManaged
WithModes(...Mode) and WithInitialMode(ModeName)declare named alternatives and choose the initial one
WithContextCounter(contextcount.ContextCounter)fixed complete-request counter
WithInferenceCapability(contextcount.InferenceCapability)fixed transport posture; required with a counter
WithContextTransports(...ContextTransport)complete admitted transport set; omitted means the base model’s one transport
WithContextObservation(ContextObservationPolicy)hard admission policy without compaction
WithCompaction(CompactionPolicy)manual and optional automatic compaction policy

Options are not all interchangeable. Duplicate singleton options return *loop.DefinitionError{Kind: loop.DefinitionDuplicateOption}. Context options are checked as a group after all options have run, so option order cannot turn an incomplete counter/capability/policy set into a valid definition.

Immutable result

The useful design-time accessors are:

func (d Definition) Name() identity.AgentName
func (d Definition) Description() string
func (d Definition) Engine() Engine
func (d Definition) Delegates() []identity.AgentName
func (d Definition) Modes() []Mode
func (d Definition) ToolRequirements() tool.Requirements
func (d Definition) InitialMode() ModeName
func (d Definition) FingerprintInitial() InitialFingerprint
func (d Definition) Delegation() Delegation
func (d Definition) PolicyRevision() string
func (d Definition) Bind(context.Context, tool.Bindings) (BoundDefinition, error)

Delegates and Modes are fresh slices. PolicyRevision is a deterministic SHA-256 projection of execution behavior and opaque revisions. FingerprintInitial resolves the initial model, effective system, and produced tool names without building tool instances. Bind is where factories run and IDs are checked.

Validation order

%%{init: {"theme":"dark"}}%%
flowchart TD
    A[Apply options] --> B[Required name, client, model]
    B --> C[Tools, limits, engine, policy revision]
    C --> D[Delegates and modes]
    D --> E[Counter, capability, transport set]
    E --> F[Observation or compaction policy]
    F --> G[Output schema]
    G --> H[Clone owned state]
    H --> I[Return Definition]

Typical failures include DefinitionMissingName, DefinitionInvalidClient, DefinitionInvalidModel, DefinitionInvalidTool, DefinitionMissingPolicyRevision, DefinitionMissingInitialMode, DefinitionInvalidModeBinding, DefinitionConflictingContextPolicy, and DefinitionInvalidOutputSchema. Use errors.As instead of parsing error strings:

var de *loop.DefinitionError
if errors.As(err, &de) {
	log.Printf("field=%s kind=%s", de.Field, de.Kind)
}

Source and proof

← back to documentation