Skip to main content

Block options

Every block takes a config object. Shared fields live on every kind. Generators, handlers, sequencers, and routers add their own.

Narrative: Blocks, Sequencers, Generator context.

Shared fields

These appear on handlers, generators, routers, and (where noted) sequencers.

FieldTypeDefaultWhat it does
namestringrequiredBlock id. Used in traces, DevTool, and item provenance.
descriptionstringHuman description.
inputSchema / outputSchemaZod schemaTyped input and output.
stateSchemaZod schemaThis block's own request-scoped state (ctx.self).
transientbooleanDrops this block's framework bookkeeping (its auto-emitted block_trace) from the persisted log; the traces still stream live to the DevTool and in-flight clients. Items the block emits itself with ctx.emit.message() / ctx.emit.component() are unaffected and still persist — pass a per-call { transient: true } for those. See Default transience and the block flag.
connectInput(input, ctx) => nextInputidentityMap the previous step's output into this block's input.
activeStatusMessagestring or (input, ctx) => stringEmits ctx.emit.status() when the block starts.
container{ component?, label?, metadata? }UI container metadata.
retryRetryPolicy{ maxAttempts?, baseDelayMs?, maxDelayMs?, retryableErrors? }.
rescueRescueHandlerSpec[]Per-block recovery. The first matching when runs and its output replaces the throw. Sequencers use .rescue() on the chain instead.
requireOrgbooleanThe flow rejects requests whose session has no orgId.
cacheabletrue or BlockCacheableConfigoffMemoize this block's result when it is installed as a generator tool. No effect as a sequencer step.
onCompleted / onErroredhookAfter success or failure.
usescapability listInstall capabilities (resources, context, tools, maybe a model).

cacheable

Only applies when the block is a tool on a generator. Errors are never cached.

Caching also needs a tool-cache store in scope. A task board installs one for its workers; on an ordinary generator you add it yourself with createToolCacheCapability() in uses. Without a store the field is inert — the tool runs on every call, and identical in-flight calls do not share one execution. With a store in scope, they do.

FieldTypeDefaultWhat it does
ttlnumber (ms)5 minutes0 disables caching.
scope"run" | "request" | "session""run"How widely a cached result may be reused.
keyFn(args) => stringJSON canonicalizeCustom cache key.
cacheIfpredicateall successesGate writes.

Generator

generator({ ... }) calls a model, assembles the prompt, runs the tool loop, and streams items.

import { generator } from "@flow-state-dev/core";
import { z } from "zod";

const chat = generator({
name: "chat",
model: "intent/chat",
prompt: "You are a helpful assistant.",
inputSchema: z.object({ message: z.string() }),
history: true,
user: (input) => input.message,
itemVisibility: { client: true, history: true },
maxTokens: 2048,
});
FieldTypeDefaultWhat it does
promptstring, fn, slot, or PromptFilerequiredSystem prompt. A PromptFile can also supply user, caching, maxTokens, and related siblings; an explicit sibling on this config wins.
modelmodel id, intent, or resolverrequired unless a capability supplies oneWhat to call. Block-level always wins over a capability.
userstring, fn, or slotThe user message for this turn.
contextslotExtra system/context material.
historytrue, query, or slotoffPrior turns. true loads the session window.
toolstool list or (input, ctx) => toolsTools the model may call.
usescapability listMay contribute model, tools, context, and resources.
itemVisibility{ client, history }unset = no auto-emissionWho sees auto-emitted messages. See Visibility.
agentNamestringblock name when visibility is setProvenance stamp. Shared names collaborate; distinct names stay isolated.
searchtrue or search configoffProvider-native web search, resolved from the model at run time.
providerToolsProviderTool[]AI SDK provider-defined tools, passed through as-is.
loop{ maxIterations?, runTools?, stopWhen? }Tool-loop policy.
maxIterationsnumberLegacy loop cap. Prefer loop.maxIterations.
maxTokensnumberOutput token cap.
repairGeneratorRepairConfigStructured-output repair.
repairOutputfnCustom repair of a failed structured parse.
cachingcaching config or resolver{ enabled: true, breakpoints: "auto", ttl: "5m" }Prompt caching. { enabled: false } turns it off.
describeToolsbooleantrueInject tool name + description into the system context.
providerOptionsoptions or resolverPassed through to the AI SDK provider.
flowToolsToolsConfigflow toolsOverride flow-level tool defaults for this generator.
retryRetryPolicyRetry the model call.

Scope schemas (requestStateSchema, sessionStateSchema, userStateSchema, orgStateSchema, sequencerStateSchema, parentStateSchema), resources, and targetStateSchemas work the same as on a handler.

itemVisibility

Unset means the generator does not auto-emit conversational items. Only typed block_trace output flows to parents. Pattern factories set visibility on the generators they create.

ValueClient UINext-turn history
{ client: true, history: true }yesyes — primary user-facing agent
{ client: true, history: false }yesno — observable sub-agent work
{ client: false, history: true }noyes — private injected context
{ client: false, history: false }nono — DevTool / trace only

repair

FieldTypeDefaultWhat it does
mode"auto" | "rescue" | "fail"How a structured-output failure is handled.
maxAttemptsnumberRepair attempts.
coerceboolean or { model? }enabledLLM coercion pass.

loop

FieldTypeDefaultWhat it does
maxIterationsnumberStop the tool loop after this many rounds.
runToolsbooleanWhen false, the model may propose tools but they are not executed.
stopWhen(state, ctx) => booleanEarly exit.

Handler

handler({ execute }) is deterministic compute: validate, transform, mutate state, implement a tool.

FieldTypeDefaultWhat it does
execute(input, ctx) => outputrequiredThe body.
usescapability listInstall capabilities.
resourcesresource mapResources this handler declares.
requestStateSchema / sessionStateSchema / userStateSchema / orgStateSchema / sequencerStateSchemaZod schemaScope slices this handler reads or writes.
parentInputSchema / parentStateSchemaZod schemaWhat this handler expects from its parent.
targetStateSchemasmapNamed sibling/ancestor state handles (ctx.targets).

Plus the shared fields.

Sequencer

sequencer({ name }) is the pipeline. Methods (.step, .parallel, .rescue, …) live on the returned builder; they are not config fields. See Control flow.

FieldTypeDefaultWhat it does
namestringrequiredSequencer id.
descriptionstringHuman description.
inputSchema / outputSchemaZod schemaPipeline I/O. Declare outputSchema when callers need a typed result.
stateSchemaZod schemaSequencer state (ctx.sequencer and ctx.self in its own callbacks).
usescapability listCapabilities installed on the sequencer.
durablebooleantrueCheckpoint at step boundaries. Set false for ephemeral or test pipelines.
transientbooleanOmit items from the persisted log.
activeStatusMessagestring or fnStatus when the sequencer starts.
containerobjectUI container metadata.

durable: true on the sequencer writes checkpoints. Crash recovery and ctx.suspend() also need durable: true on createFlowState and durable: true on the action. See Durable execution.

Router

router({ routes, execute }) picks one child block at runtime. execute returns the block to run; the framework then runs that block with the router's input.

FieldTypeDefaultWhat it does
routesBlockDefinition[]requiredThe candidates execute may return.
execute(input, ctx) => BlockDefinitionrequiredSelector. stateSchema is read-only here.
uses / scope schemas / resourcessame as handlerSame declaration surface as a handler.

Plus the shared fields.

See also