Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sub Agents

Use subagent helpers when a script needs specialized worker-style reasoning.

Use runSubagent(...) for lightweight in-process work. Use durable child-task helpers when work must survive parent task suspension, process restarts, or longer-running parallel execution.

Run A Lightweight Subagent

Run one in-process subagent and await its result without suspending the parent task:

const result = await flo.task.runSubagent({
  worker_kind: "classifier",
  title: "Classify request",
  objective: "Classify the request into one supported category",
  input: { text: input.text },
  selected_skill_ids: ["skill.request-classifier"],
});

if (result.status === "completed") {
  return result.output;
}

runSubagent(...) creates no durable child task or child batch. If the parent script invocation fails or agentd exits while the subagent is running, the subagent work is lost with that invocation.

Each request defines:

  • worker_kind
  • title
  • objective
  • input
  • optional selected_skill_ids

Each response includes:

  • subagent_task_id
  • worker_kind
  • status
  • output
  • output_text
  • optional error
  • optional suspension

Spawn Children

Create a child batch with flo.task.spawnChildren(...):

const spawned = await flo.task.spawnChildren({
  children: [
    {
      worker_kind: "extractor",
      title: "Extract invoice fields",
      objective: "Extract invoice number and total from the document",
      input: { document_id: input.document_id },
      selected_skill_ids: ["skill.ocr", "skill.invoice-parser"],
    },
    {
      worker_kind: "classifier",
      title: "Classify invoice type",
      objective: "Classify the invoice into the supported categories",
      input: { document_id: input.document_id },
    },
  ],
});

Each child defines:

  • worker_kind
  • title
  • objective
  • input
  • optional selected_skill_ids

Omit selected_skill_ids to keep the child task’s selected skill list empty.

Wait For Completion

Use flo.task.waitForBatch(...) when the parent should suspend until all child tasks are terminal:

await flo.task.putToolState({
  key: "batch_checkpoint",
  value: { batch_id: spawned.batch.batch_id },
});

const results = await flo.task.waitForBatch({
  batch_id: spawned.batch.batch_id,
});

Important: Suspension Restarts The Script

Important: after suspension, the runtime re-enters the script from the entrypoint. Persist the progress you need before waiting.

What this means in practice:

  • local variables do not survive suspension
  • the JavaScript call stack is not restored
  • code after waitForBatch(...) only runs when the script reaches that point again on the resumed invocation

Treat waitForBatch(...) like a durable checkpoint boundary:

  • write the child batch id before waiting
  • write any progress markers you need to decide what to do on resume
  • on the next entrypoint run, read that state back and branch accordingly

Typical pattern:

const checkpoint = await flo.task.getToolState<{ batch_id?: string }>({
  key: "batch_checkpoint",
});

if (!checkpoint?.batch_id) {
  const spawned = await flo.task.spawnChildren({ children });
  await flo.task.putToolState({
    key: "batch_checkpoint",
    value: { batch_id: spawned.batch.batch_id },
  });
  await flo.task.waitForBatch({
    batch_id: spawned.batch.batch_id,
  });
}

const resumed = await flo.task.getToolState<{ batch_id: string }>({
  key: "batch_checkpoint",
});
const results = await flo.task.getBatchResults({
  batch_id: resumed.batch_id,
});

Use Task State for these checkpoints. Prefer tool-partitioned task state by default, and switch to shared task state only when later tools in the same task need the same checkpoint.

Read Results Without Suspending

Use flo.task.getBatchResults(...) only when the batch is already terminal:

const results = await flo.task.getBatchResults({
  batch_id: batchId,
});

If the batch is still pending, this call fails non-retryably.

Result Shape

Each child result includes:

  • child_task_id
  • worker_kind
  • status
  • output
  • optional error
  • optional completed_at

Authoring Guidance

  • Use runSubagent(...) for lightweight local branching.
  • Use child tasks for durable parallelism.
  • Persist checkpoints with Task State before waiting.
  • Keep child inputs compact and JSON-serializable.
  • Handle partial failures explicitly; one child can fail while others succeed.

Next: Other APIs