Skip to main content
The types on this page are the core JSX/runtime types most Smithers users work with directly. They are exported from smithers-orchestrator unless noted otherwise. Additional public type families are also exported for adjacent surfaces:
FamilyExports
Workflow builderCreateSmithersApi
Serve appServeOptions
ObservabilityResolvedSmithersObservabilityOptions, SmithersLogFormat, SmithersObservabilityOptions, SmithersObservabilityService
AgentsAnthropicAgentOptions, OpenAIAgentOptions, PiAgentOptions, PiExtensionUiRequest, PiExtensionUiResponse
ScorersScoreResult, ScorerInput, ScorerFn, Scorer, SamplingConfig, ScorerBinding, ScorersMap, ScoreRow, AggregateScore, ScorerContext, CreateScorerConfig, LlmJudgeConfig, AggregateOptions from smithers-orchestrator/scorers
Renderer / builder internalsHostContainer, SmithersSqliteOptions
VCS helpersRunJjOptions, RunJjResult, JjRevertResult, WorkspaceAddOptions, WorkspaceResult, WorkspaceInfo

Workflow Types

SmithersWorkflow<Schema>

type SmithersWorkflow<Schema> = {
  db: unknown;
  build: (ctx: SmithersCtx<Schema>) => React.ReactElement;
  opts: SmithersWorkflowOptions;
  schemaRegistry?: Map<string, SchemaRegistryEntry>;
};
FieldTypeDescription
dbunknownDrizzle ORM database instance
build(ctx: SmithersCtx<Schema>) => ReactElementRenders the workflow JSX tree
optsSmithersWorkflowOptionsWorkflow-level options
schemaRegistryMap<string, SchemaRegistryEntry>Output table names to schema entries

SmithersWorkflowOptions

type SmithersWorkflowOptions = {
  cache?: boolean;
};
FieldTypeDefaultDescription
cachebooleanundefinedEnable task output caching across runs

SchemaRegistryEntry

type SchemaRegistryEntry = {
  table: any;
  zodSchema: import("zod").ZodObject<any>;
};
FieldTypeDescription
tableanyDrizzle ORM table definition
zodSchemaZodObject<any>Zod schema for output validation

Context Types

SmithersCtx<Schema>

interface SmithersCtx<Schema> {
  runId: string;
  iteration: number;
  iterations?: Record<string, number>;
  input: Schema extends { input: infer T } ? T : any;
  auth: RunAuthContext | null;
  outputs: OutputAccessor<Schema>;

  output<T extends keyof Schema>(
    table: Schema[T],
    key: OutputKey,
  ): InferRow<Schema[T]>;

  outputMaybe<T extends keyof Schema>(
    table: Schema[T],
    key: OutputKey,
  ): InferRow<Schema[T]> | undefined;

  latest(table: any, nodeId: string): any;

  latestArray(value: unknown, schema: import("zod").ZodType): any[];

  iterationCount(table: any, nodeId: string): number;
}
Field / MethodTypeDescription
runIdstringCurrent run ID
iterationnumberCurrent Loop iteration (0 outside loops)
iterationsRecord<string, number>Loop ID to current iteration count
inputInferred from SchemaTyped input data
authRunAuthContext | nullAuthentication context passed via RunOptions.auth. null when no auth context is configured.
outputsOutputAccessor<Schema>Accessor for all output rows
output(table, key)InferRow<T>Get output row. Throws if missing. The table parameter accepts a Zod schema from outputs, a Drizzle table, or a string schema key.
outputMaybe(table, key)InferRow<T> | undefinedGet output row or undefined. Same table resolution as output().
latest(table, nodeId)anyLatest output row (highest iteration). Same table resolution as output().
latestArray(value, schema)any[]JSON-parse value if it is a string, coerce to array, then validate each element against schema (Zod). Invalid items are silently dropped.
iterationCount(table, nodeId)numberDistinct iteration count for a node

OutputKey

type OutputKey = {
  nodeId: string;
  iteration?: number;
};
FieldTypeDefaultDescription
nodeIdstringTask node ID
iterationnumber0Loop iteration

OutputAccessor<Schema>

Callable object that retrieves output rows. Can be called as a function or accessed as a property.
type OutputAccessor<Schema> = ((table: any) => any[]) & Record<string, any[]>;

InferRow<TTable>

Extracts the select row type from a Drizzle table.
type InferRow<TTable> = TTable extends { $inferSelect: infer R } ? R : never;

Run Types

RunOptions

type RunOptions = {
  runId?: string;
  parentRunId?: string;
  input: Record<string, unknown>;
  maxConcurrency?: number;
  onProgress?: (e: SmithersEvent) => void;
  signal?: AbortSignal;
  resume?: boolean;
  force?: boolean;
  workflowPath?: string;
  rootDir?: string;
  logDir?: string | null;
  allowNetwork?: boolean;
  maxOutputBytes?: number;
  toolTimeoutMs?: number;
  hot?: boolean | HotReloadOptions;
  auth?: RunAuthContext;
  cliAgentToolsDefault?: "all" | "explicit-only";
};
FieldTypeDefaultDescription
runIdstringAuto-generatedCustom run identifier. Falls back to randomUUID() when omitted.
parentRunIdstringundefinedParent run ID for child workflow / subflow tracking.
inputRecord<string, unknown>Input data (required)
maxConcurrencynumber4Max parallel tasks
onProgress(e: SmithersEvent) => voidundefinedLifecycle event callback
signalAbortSignalundefinedCancellation signal
resumebooleanfalseResume from last checkpoint
forcebooleanfalseAllow resume even if the run is still active (overrides liveness check)
workflowPathstringundefinedWorkflow file path (for tool context)
rootDirstringundefinedSandbox root for tools
logDirstring | nullundefinedEvent log directory (null to disable)
allowNetworkbooleanfalseAllow bash network access
maxOutputBytesnumber200000Max output bytes per tool call
toolTimeoutMsnumber60000Tool execution timeout (ms)
hotboolean | HotReloadOptionsundefinedHot-reload mode
authRunAuthContextundefinedAuthentication context. Accessible as ctx.auth inside the workflow.
cliAgentToolsDefault"all" | "explicit-only""all"Default tool access policy for CLI-backed agents. "explicit-only" restricts agents to tools listed in allowTools.

HotReloadOptions

type HotReloadOptions = {
  rootDir?: string;
  outDir?: string;
  maxGenerations?: number;
  cancelUnmounted?: boolean;
  debounceMs?: number;
};
FieldTypeDefaultDescription
rootDirstringAuto-detectDirectory to watch
outDirstring.smithers/hmr/<runId>Generation overlay directory
maxGenerationsnumber3Max overlay generations
cancelUnmountedbooleanfalseCancel unmounted tasks after reload
debounceMsnumber100File change debounce (ms)

RunResult

type RunResult = {
  runId: string;
  status: "finished" | "failed" | "cancelled" | "continued" | "waiting-approval" | "waiting-event" | "waiting-timer";
  output?: unknown;
  error?: unknown;
};
FieldTypeDescription
runIdstringRun identifier
statusstringTerminal status
outputunknownFinal output (if finished)
errorunknownError details (if failed)

RunStatus

type RunStatus =
  | "running"
  | "waiting-approval"
  | "waiting-event"
  | "waiting-timer"
  | "finished"
  | "continued"
  | "failed"
  | "cancelled";
ValueDescription
"running"Actively executing
"waiting-approval"Awaiting human approval
"waiting-event"Awaiting an external signal or event
"waiting-timer"Suspended until a durable timer fires
"finished"All tasks completed
"continued"Run ended via <ContinueAsNew> and a fresh run has started
"failed"Unrecoverable task failure
"cancelled"Cancelled via AbortSignal or API

Task Types

TaskDescriptor

Internal representation of a task extracted from the JSX tree. Scheduled and executed by the engine.
type TaskDescriptor = {
  nodeId: string;
  ordinal: number;
  iteration: number;
  ralphId?: string;
  dependsOn?: string[];
  needs?: Record<string, string>;
  worktreeId?: string;
  worktreePath?: string;
  worktreeBranch?: string;

  outputTable: Table | null;
  outputTableName: string;
  outputRef?: import("zod").ZodObject<any>;
  outputSchema?: import("zod").ZodObject<any>;

  parallelGroupId?: string;
  parallelMaxConcurrency?: number;

  needsApproval: boolean;
  approvalMode?: "gate" | "decision";
  approvalOnDeny?: "fail" | "continue" | "skip";
  skipIf: boolean;
  retries: number;
  retryPolicy?: RetryPolicy;
  timeoutMs: number | null;
  continueOnFail: boolean;
  cachePolicy?: CachePolicy;

  agent?: AgentLike | AgentLike[];
  prompt?: string;
  staticPayload?: unknown;
  computeFn?: () => unknown | Promise<unknown>;

  label?: string;
  meta?: Record<string, unknown>;
};
FieldTypeDescription
nodeIdstringUnique task identifier (from id prop)
ordinalnumberExecution order position (depth-first)
iterationnumberCurrent Loop iteration
ralphIdstringParent Loop ID
dependsOnstring[]Explicit dependency node IDs
needsRecord<string, string>Named dependencies (keys = context keys, values = node IDs)
worktreeIdstringAssigned git worktree ID
worktreePathstringWorktree filesystem path
worktreeBranchstringWorktree branch name
outputTableTable | nullDrizzle table for output persistence
outputTableNamestringOutput table name
outputRefZodObject<any>Zod schema reference from output prop
outputSchemaZodObject<any>Zod schema for validating agent output
parallelGroupIdstringParent <Parallel> group ID
parallelMaxConcurrencynumberConcurrency limit from parent <Parallel>
needsApprovalbooleanRequires human approval
approvalMode"gate" | "decision""gate" pauses before execution; "decision" records a decision
approvalOnDeny"fail" | "continue" | "skip"Behavior on denial
skipIfbooleanSkip this task
retriesnumberRetry attempts on failure
retryPolicyRetryPolicyBackoff configuration
timeoutMsnumber | nullTask timeout (ms)
continueOnFailbooleanContinue workflow on failure
cachePolicyCachePolicyCache configuration
agentAgentLike | AgentLike[]Agent or fallback chain
promptstringPrompt text (from children)
staticPayloadunknownPre-computed payload (non-agent tasks)
computeFn() => unknown | Promise<unknown>Compute callback
labelstringDisplay label
metaRecord<string, unknown>Arbitrary metadata

AgentLike

type AgentLike = Agent<any, any, any>;

RetryPolicy

type RetryBackoff = "fixed" | "linear" | "exponential";

type RetryPolicy = {
  backoff?: RetryBackoff;
  initialDelayMs?: number;
};
FieldTypeDefaultDescription
backoff"fixed" | "linear" | "exponential""fixed"Backoff strategy. "fixed": constant delay. "linear": delay increases by initialDelayMs each attempt. "exponential": delay doubles each attempt.
initialDelayMsnumber0Base delay in milliseconds. When 0, retries execute immediately with no schedule.
Backoff delay formulas (attempt 1-indexed):
StrategyDelay formula
"fixed"initialDelayMs every attempt
"linear"initialDelayMs * attempt
"exponential"initialDelayMs * 2^(attempt - 1)
When retries is set on a <Task> without a retryPolicy, the task retries immediately (no delay).

RetryTaskOptions

Options for the programmatic retryTask() function, which resets a task and its dependents for re-execution.
type RetryTaskOptions = {
  runId: string;
  nodeId: string;
  iteration?: number;
  resetDependents?: boolean;
  force?: boolean;
  onProgress?: (event: SmithersEvent) => void;
};
FieldTypeDefaultDescription
runIdstringRun ID containing the task to retry
nodeIdstringNode ID of the task to retry
iterationnumber0Loop iteration to retry
resetDependentsbooleantrueAlso reset downstream tasks that depend on this node
forcebooleanfalseAllow retry even if the run is still active
onProgress(event: SmithersEvent) => voidundefinedEvent callback for RetryTaskStarted and RetryTaskFinished events

RetryTaskResult

type RetryTaskResult = {
  success: boolean;
  resetNodes: string[];
  error?: string;
};
FieldTypeDescription
successbooleanWhether the retry operation succeeded
resetNodesstring[]Node IDs that were reset to "pending"
errorstringError message if the retry operation failed

CachePolicy

type CachePolicy<Ctx = any> = {
  by?: (ctx: Ctx) => unknown;
  version?: string;
};
FieldTypeDefaultDescription
by(ctx: Ctx) => unknownundefinedCache key function. Same key reuses cached output.
versionstringundefinedCache version. Changing it invalidates cached outputs.

Graph Types

GraphSnapshot

type GraphSnapshot = {
  runId: string;
  frameNo: number;
  xml: XmlNode | null;
  tasks: TaskDescriptor[];
};
FieldTypeDescription
runIdstringRun identifier
frameNonumberRender frame number (monotonically increasing)
xmlXmlNode | nullRendered XML tree
tasksTaskDescriptor[]Ordered task list

XmlNode

type XmlNode = XmlElement | XmlText;

XmlElement

type XmlElement = {
  kind: "element";
  tag: string;
  props: Record<string, string>;
  children: XmlNode[];
};
FieldTypeDescription
kind"element"Discriminant
tagstringTag name ("Workflow", "Task", "Parallel", etc.)
propsRecord<string, string>Attributes
childrenXmlNode[]Child nodes

XmlText

type XmlText = {
  kind: "text";
  text: string;
};
FieldTypeDescription
kind"text"Discriminant
textstringContent

Event Types

SmithersEvent

Discriminated union of all lifecycle events. Every event includes runId and timestampMs.
type SmithersEvent =
  | RunStarted
  | RunStatusChanged
  | RunFinished
  | RunFailed
  | RunCancelled
  | RunContinuedAsNew
  | RunHijackRequested
  | RunHijacked
  | FrameCommitted
  | NodePending
  | NodeStarted
  | NodeFinished
  | NodeFailed
  | NodeCancelled
  | NodeSkipped
  | NodeRetrying
  | NodeWaitingApproval
  | ApprovalRequested
  | ApprovalGranted
  | ApprovalDenied
  | ToolCallStarted
  | ToolCallFinished
  | NodeOutput
  | AgentEvent
  | RevertStarted
  | RevertFinished
  | WorkflowReloadDetected
  | WorkflowReloaded
  | WorkflowReloadFailed
  | WorkflowReloadUnsafe
  | ScorerStarted
  | ScorerFinished
  | ScorerFailed
  | TokenUsageReported;

Run Events

EventFieldsDescription
RunStartedrunId, timestampMsExecution began
RunStatusChangedrunId, status: RunStatus, timestampMsStatus transition
RunFinishedrunId, timestampMsAll tasks completed
RunFailedrunId, error: unknown, timestampMsFailed
RunCancelledrunId, timestampMsCancelled
RunContinuedAsNewrunId, newRunId, iteration, carriedStateSize, ancestryDepth?, timestampMsContinued as new run
RunHijackRequestedrunId, target?, timestampMsHijack requested
RunHijackedrunId, nodeId, iteration, attempt, engine, mode, resume?, cwd, timestampMsHijack completed

Frame Events

EventFieldsDescription
FrameCommittedrunId, frameNo, xmlHash, timestampMsFrame persisted

Node Events

EventFieldsDescription
NodePendingrunId, nodeId, iteration, timestampMsQueued
NodeStartedrunId, nodeId, iteration, attempt, timestampMsExecution began
NodeFinishedrunId, nodeId, iteration, attempt, timestampMsCompleted
NodeFailedrunId, nodeId, iteration, attempt, error, timestampMsFailed
NodeCancelledrunId, nodeId, iteration, attempt?, reason?, timestampMsCancelled
NodeSkippedrunId, nodeId, iteration, timestampMsSkipped
NodeRetryingrunId, nodeId, iteration, attempt, timestampMsRetrying

Approval Events

EventFieldsDescription
NodeWaitingApprovalrunId, nodeId, iteration, timestampMsAwaiting approval
ApprovalRequestedrunId, nodeId, iteration, timestampMsApproval requested
ApprovalGrantedrunId, nodeId, iteration, timestampMsApproved
ApprovalDeniedrunId, nodeId, iteration, timestampMsDenied

Tool Events

EventFieldsDescription
ToolCallStartedrunId, nodeId, iteration, attempt, toolName, seq, timestampMsTool call began
ToolCallFinishedrunId, nodeId, iteration, attempt, toolName, seq, status, timestampMsTool call completed

Output Events

EventFieldsDescription
NodeOutputrunId, nodeId, iteration, attempt, text, stream, timestampMsAgent output text

Revert Events

EventFieldsDescription
RevertStartedrunId, nodeId, iteration, attempt, jjPointer, timestampMsVCS revert started
RevertFinishedrunId, nodeId, iteration, attempt, jjPointer, success, error?, timestampMsVCS revert completed

Component Props

WorkflowProps

type WorkflowProps = {
  name: string;
  cache?: boolean;
  children?: React.ReactNode;
};
PropTypeRequiredDescription
namestringYesWorkflow name for logging and database
cachebooleanNoEnable output caching
childrenReactNodeNoChild components

TaskProps<Row, D>

type TaskProps<Row, Output, D extends DepsSpec = {}> = {
  key?: string;
  id: string;
  output: Output;
  outputSchema?: import("zod").ZodObject<any>;
  agent?: AgentLike | AgentLike[];
  fallbackAgent?: AgentLike;
  dependsOn?: string[];
  needs?: Record<string, string>;
  deps?: D;
  skipIf?: boolean;
  needsApproval?: boolean;
  timeoutMs?: number;
  retries?: number;
  retryPolicy?: RetryPolicy;
  continueOnFail?: boolean;
  cache?: CachePolicy;
  scorers?: ScorersMap;
  label?: string;
  meta?: Record<string, unknown>;
  children: string | Row | (() => Row | Promise<Row>) | React.ReactNode | ((deps: InferDeps<D>) => Row | React.ReactNode);
};
PropTypeRequiredDescription
idstringYesUnique task identifier
outputZodObject<any> | Table | stringYesOutput target: Zod schema from outputs (recommended), Drizzle table, or string key
outputSchemaZodObject<any>NoZod schema for agent output validation
agentAgentLike | AgentLike[]NoAgent or fallback chain
fallbackAgentAgentLikeNoAppend one fallback agent
dependsOnstring[]NoExplicit dependency node IDs
needsRecord<string, string>NoNamed dependencies (keys = context keys, values = node IDs)
depsRecord<string, OutputTarget>NoTyped render-time dependencies. Keys resolve from task ids or needs entries.
skipIfbooleanNoSkip when true
needsApprovalbooleanNoPause for human approval
timeoutMsnumberNoTimeout (ms)
retriesnumberNoRetry attempts (default: 0)
retryPolicyRetryPolicyNoRetry timing
continueOnFailbooleanNoContinue workflow on failure
cacheCachePolicyNoCache configuration
scorersScorersMapNoScorers to evaluate task output after completion
labelstringNoDisplay label
metaRecord<string, unknown>NoArbitrary metadata
childrenstring | Row | (() => Row) | ReactNode | ((deps) => Row | ReactNode)YesPrompt, compute callback, static payload, deps function, or nested elements

SequenceProps

type SequenceProps = {
  skipIf?: boolean;
  children?: React.ReactNode;
};
PropTypeRequiredDescription
skipIfbooleanNoSkip entire sequence when true
childrenReactNodeNoChild tasks

ParallelProps

type ParallelProps = {
  id?: string;
  maxConcurrency?: number;
  skipIf?: boolean;
  children?: React.ReactNode;
};
PropTypeRequiredDescription
idstringNoGroup identifier
maxConcurrencynumberNoMax concurrent tasks
skipIfbooleanNoSkip entire group when true
childrenReactNodeNoChild tasks

BranchProps

type BranchProps = {
  if: boolean;
  then: React.ReactElement;
  else?: React.ReactElement;
  skipIf?: boolean;
};
PropTypeRequiredDescription
ifbooleanYesCondition
thenReactElementYesRendered when true
elseReactElementNoRendered when false
skipIfbooleanNoSkip entirely when true

LoopProps

type LoopProps = {
  id?: string;
  until: boolean;
  maxIterations?: number;
  onMaxReached?: "fail" | "return-last";
  skipIf?: boolean;
  children?: React.ReactNode;
};
PropTypeRequiredDescription
idstringNoLoop identifier (auto-generated if omitted)
untilbooleanYesExit when true
maxIterationsnumberNoMax iterations
onMaxReached"fail" | "return-last"NoBehavior on limit: fail or return last output
skipIfbooleanNoSkip loop when true
childrenReactNodeNoTasks per iteration

RalphProps

Deprecated: Use LoopProps.
type RalphProps = LoopProps;

ApprovalProps<Row>

type ApprovalProps<Row = ApprovalDecision> = {
  id: string;
  output: ZodObject<any> | Table | string;
  outputSchema?: import("zod").ZodObject<any>;
  request: ApprovalRequest;
  onDeny?: "fail" | "continue" | "skip";
  dependsOn?: string[];
  needs?: Record<string, string>;
  skipIf?: boolean;
  timeoutMs?: number;
  retries?: number;
  retryPolicy?: RetryPolicy;
  continueOnFail?: boolean;
  cache?: CachePolicy;
  label?: string;
  meta?: Record<string, unknown>;
  key?: string;
  children?: React.ReactNode;
};

type ApprovalRequest = {
  title: string;
  summary?: string;
  metadata?: Record<string, unknown>;
};

type ApprovalDecision = {
  approved: boolean;
  note: string | null;
  decidedBy: string | null;
  decidedAt: string | null;
};
PropTypeRequiredDescription
idstringYesApproval node identifier
outputZodObject<any> | Table | stringYesPersistence target for decision
outputSchemaZodObject<any>NoDecision output validation
requestApprovalRequestYesTitle, summary, metadata
onDeny"fail" | "continue" | "skip"NoBehavior on denial
dependsOnstring[]NoDependency node IDs
needsRecord<string, string>NoNamed dependencies
skipIfbooleanNoSkip when true
timeoutMsnumberNoTimeout (ms)
retriesnumberNoRetry attempts
retryPolicyRetryPolicyNoRetry backoff
continueOnFailbooleanNoContinue on failure
cacheCachePolicyNoCache configuration
labelstringNoDisplay label (defaults to request.title)
metaRecord<string, unknown>NoArbitrary metadata
childrenReactNodeNoChild elements

Error Types

SmithersError

type SmithersError = {
  code: SmithersErrorCode;
  message: string;
  summary: string;
  docsUrl: string;
  details?: Record<string, unknown>;
  cause?: unknown;
};
FieldTypeDescription
codeSmithersErrorCodeMachine-readable error code
messagestringError description
summarystringShort error summary without docs URL suffixing
docsUrlstringDocumentation URL for the error reference
detailsRecord<string, unknown>Additional context
causeunknownOriginal nested cause when one is preserved

SmithersErrorCode

type SmithersErrorCode =
  | KnownSmithersErrorCode
  | (string & {});
Use KnownSmithersErrorCode when you want exhaustive switching over built-in Smithers failures. See Error Reference for the full built-in list.

KnownSmithersErrorCode

type KnownSmithersErrorCode =
  | "INVALID_INPUT"
  | "MISSING_INPUT"
  | "MISSING_INPUT_TABLE"
  // ... all built-in Smithers runtime codes
This union excludes the custom string escape hatch and is the right type for exhaustive switch statements over built-in Smithers errors.

Server Types

ServerOptions

See HTTP Server for details.
type ServerOptions = {
  port?: number;
  db?: BunSQLiteDatabase<any>;
  authToken?: string;
  maxBodyBytes?: number;
  rootDir?: string;
  allowNetwork?: boolean;
};

ServeOptions

Options for createServeApp(...), the single-run Hono app exported from the root package.
type ServeOptions = {
  workflow: SmithersWorkflow<any>;
  adapter: SmithersDb;
  runId: string;
  abort: AbortController;
  authToken?: string;
  metrics?: boolean;
};

Tool Context Types

ToolContext

Internal context provided to tools via AsyncLocalStorage. Not typically used directly.
type ToolContext = {
  db: SmithersDb;
  runId: string;
  nodeId: string;
  iteration: number;
  attempt: number;
  rootDir: string;
  allowNetwork: boolean;
  maxOutputBytes: number;
  timeoutMs: number;
  seq: number;
};