Skip to main content
import { Kanban } from "smithers-orchestrator";

Props

PropTypeDefaultDescription
idstring"kanban"ID prefix for all generated task and loop elements.
columnsColumnDef[](required)Column definitions in order. Items flow left to right through each column.
useTickets() => Array<{ id: string }>(required)Function that returns ticket items to process. Each item must have an id field.
agentsRecord<string, AgentLike>undefinedRecord mapping column names to agents. Overrides column-level agents.
maxConcurrencynumberInfinityMax items processed in parallel per column.
onCompleteOutputTargetundefinedOutput schema for the completion task when items reach the final column.
untilbooleanfalseLoop exit condition. When true, the board loop stops.
maxIterationsnumber5Max iterations through the column pipeline.
skipIfbooleanfalseSkip the entire board. Returns null.
childrenReactNodeundefinedContent passed to the onComplete task, if present.

ColumnDef

FieldTypeDescription
namestringColumn name (e.g., "backlog", "review").
agentAgentLikeAgent that processes items in this column.
outputOutputTargetOutput schema for tasks in this column.
prompt(ctx: { item, column }) => stringOptional prompt template. Receives the item and column name.
taskPartial<TaskProps>Optional task overrides applied to each generated item task in the column. Use this to set retries, timeoutMs, heartbeatTimeoutMs, or override continueOnFail.

Basic usage

const columns = [
  { name: "triage", agent: triageAgent, output: outputs.triage },
  { name: "work", agent: workerAgent, output: outputs.work },
  { name: "review", agent: reviewAgent, output: outputs.review },
];

<Workflow name="ticket-board">
  <Kanban
    columns={columns}
    useTickets={() => tickets}
    until={allDone}
    maxIterations={3}
  />
</Workflow>

With concurrency limits

<Kanban
  id="pr-queue"
  columns={columns}
  useTickets={() => pullRequests}
  maxConcurrency={2}
  until={queueEmpty}
/>
At most two items are processed simultaneously within each column.

Overriding agents per column

The agents prop overrides column-level agents:
<Kanban
  columns={columns}
  useTickets={() => tickets}
  agents={{
    review: seniorReviewAgent,
    work: juniorDevAgent,
  }}
  until={done}
/>

With completion handler

When onComplete is provided, a final task runs after the loop exits:
<Kanban
  columns={columns}
  useTickets={() => tickets}
  onComplete={outputs.boardSummary}
  until={allDone}
>
  Summarize the board results.
</Kanban>

Custom prompts per column

const columns = [
  {
    name: "triage",
    agent: triageAgent,
    output: outputs.triage,
    prompt: ({ item }) => `Triage ticket: ${item.title}\n${item.description}`,
  },
  {
    name: "implement",
    agent: codeAgent,
    output: outputs.impl,
    prompt: ({ item }) => `Implement the fix for: ${item.title}`,
  },
];

Per-column task policy

Use task when a lane needs explicit retries or different runtime limits:
const columns = [
  { name: "triage", agent: triageAgent, output: outputs.triage },
  {
    name: "work",
    agent: workerAgent,
    output: outputs.work,
    task: {
      retries: 2,
      timeoutMs: 30_000,
    },
  },
];

Structure

<Kanban> composes existing primitives. It does not create a new host element type. The rendered tree looks like:
Loop (until / maxIterations)
  Sequence
    Parallel (column 1 — all items)
    Parallel (column 2 — all items)
    ...
    Task (onComplete, if provided)

Notes

  • <Kanban> is a composite component. It renders a tree of <Loop>, <Sequence>, <Parallel>, and <Task> elements.
  • Each column creates a <Parallel> block where all ticket items are processed concurrently (bounded by maxConcurrency).
  • Generated item tasks default to continueOnFail={true} so one item does not block the rest of the board. Use column.task to add retries or override that behavior.
  • The useTickets function is called at render time. Return different items each iteration to implement dynamic ticket sources.
  • Use until with ctx.outputMaybe() to exit the loop when all items reach the final column.