---
title: <HumanTask>
description: Suspend until a human submits JSON matching the output schema.
---

```ts
import { HumanTask } from "smithers-orchestrator";

type HumanTaskProps = {
  id: string;
  output: z.ZodObject | Table | string;
  outputSchema?: z.ZodObject; // inferred when output is a Zod schema
  prompt: string | ReactNode;
  maxAttempts?: number; // default 10
  async?: boolean; // unrelated downstream may continue while pending
  skipIf?: boolean;
  timeoutMs?: number;
  continueOnFail?: boolean;
  dependsOn?: string[];
  needs?: Record<string, string>;
  label?: string;
  meta?: Record<string, unknown>;
  key?: string;
};
```

```tsx
import { Workflow, Sequence, Task, HumanTask, createSmithers } from "smithers-orchestrator";
import { z } from "zod";

const { smithers, outputs } = createSmithers({
  review: z.object({
    approved: z.boolean(),
    comments: z.string(),
    severity: z.enum(["low", "medium", "high"]),
  }),
  summary: z.object({ status: z.string() }),
});

export default smithers((ctx) => {
  const review = ctx.outputMaybe(outputs.review, { nodeId: "human-review" });
  return (
    <Workflow name="review-flow">
      <Sequence>
        <HumanTask
          id="human-review"
          output={outputs.review}
          prompt="Review the PR. Provide approved (boolean), comments (string), severity (low|medium|high)."
          maxAttempts={5}
          timeoutMs={86_400_000}
        />
        {review ? (
          <Task id="record" output={outputs.summary}>
            {{ status: review.approved ? "approved" : "changes-requested" }}
          </Task>
        ) : null}
      </Sequence>
    </Workflow>
  );
});
```

## Notes

- The operating agent submits the answer via `bunx smithers-orchestrator human answer <requestId> --value '<json>'`: relay the prompt to the human in conversation, collect their answer, and run the command yourself; never ask the human to run it. Find the requestId with `bunx smithers-orchestrator human inbox`. The `bunx smithers-orchestrator approve` command is for `<Approval>` components, not `<HumanTask>`.
- Failed JSON re-prompts up to `maxAttempts` with zero backoff.
- Same durable deferred mechanism as `<Approval>`; survives restarts.
