Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.awaithumans.dev/llms.txt

Use this file to discover all available pages before exploring further.

npm install awaithumans
# or
pnpm add awaithumans
# or
yarn add awaithumans
The base package has a single dep (zod) and works on Node, Bun, Deno, and edge runtimes — no node:* imports.

awaitHuman

The primitive:
import { awaitHuman } from "awaithumans";
import { z } from "zod";

const RefundPayload = z.object({
  amount_usd: z.number(),
  customer_id: z.string(),
});

const RefundDecision = z.object({
  approved: z.boolean(),
  notes: z.string().optional(),
});

const decision = await awaitHuman({
  task: "Approve refund?",
  payloadSchema: RefundPayload,
  payload: { amount_usd: 250, customer_id: "cus_demo" },
  responseSchema: RefundDecision,
  timeoutMs: 15 * 60 * 1000,
});

if (decision.approved) {
  // decision is typed as { approved: boolean, notes?: string }
}

Options

OptionTypeRequiredDescription
taskstringyesHuman-readable task description.
payloadSchemaZodTypeyesDrives the UI the human sees.
payloadmatches payloadSchemayesData sent to the human.
responseSchemaZodTypeyesDrives the response form.
timeoutMsnumberyesMin 60,000 (1 min), max 2,592,000,000 (30 days).
assignToAssignTo | undefinednoRouting target. See Routing.
notifystring[] | undefinednoChannel destinations.
verifierVerifierConfig | undefinednoServer-side LLM verification.
idempotencyKeystring | undefinednoDefault: deterministic from task + payload.
redactPayloadboolean | undefinednoDefault false.
serverUrlstring | undefinednoOverride AWAITHUMANS_URL.
apiKeystring | undefinednoOverride AWAITHUMANS_ADMIN_API_TOKEN.

Returns

Promise<TResponse> — typed against responseSchema. Zod-validated. Validation failure throws SchemaValidationError.

Throws

ErrorWhen
TaskTimeoutErrorTask hit timeout.
TaskCancelledErrorCancelled by agent or operator.
VerificationExhaustedErrorVerifier rejected maxAttempts times.
SchemaValidationErrorResponse didn’t match schema.
TaskNotFoundErrorTask disappeared.
TaskCreateErrorServer rejected create.
PollErrorLong-poll non-200.
ServerUnreachableErrorConnection failure.
MarketplaceNotAvailableErrorReserved for Phase 3.
All extend AwaitHumansError. Use instanceof to discriminate:
import {
  awaitHuman,
  TaskTimeoutError,
  TaskCancelledError,
} from "awaithumans";

try {
  const decision = await awaitHuman({ ... });
} catch (e) {
  if (e instanceof TaskTimeoutError) { ... }
  else if (e instanceof TaskCancelledError) { ... }
  else throw e;
}

Adapters

Temporal

Subpath export:
import { awaitHuman } from "awaithumans/temporal";       // workflow side
import { dispatchSignal } from "awaithumans/temporal";   // web server side
Requires peer deps:
npm install @temporalio/workflow @temporalio/client
See Temporal.

LangGraph

import { awaitHuman } from "awaithumans/langgraph";       // node side
import { driveHumanLoop } from "awaithumans/langgraph";   // driver side
Requires peer dep:
npm install @langchain/langgraph
See LangGraph.

Cross-language parity

The TS SDK and the Python SDK speak the identical wire format and produce identical signed webhook signatures (HKDF parameters locked, asserted in cross-language tests). A Python workflow can hand off webhooks to a TS receiver and vice versa without code changes.

Configuration

Reads in order (first match wins):
  1. Call args (serverUrl, apiKey)
  2. Environment variables — globalThis.process?.env?.AWAITHUMANS_URL / AWAITHUMANS_ADMIN_API_TOKEN
  3. Defaults (http://localhost:3001, no token)
In edge runtimes without process.env, only call args + defaults are read. Set explicitly for production deployments to Cloudflare Workers, Deno Deploy, etc.

Type narrowing

Zod’s z.infer<typeof Schema> gives you the static type:
const Schema = z.object({ approved: z.boolean() });
type Decision = z.infer<typeof Schema>;

const decision: Decision = await awaitHuman({ ... responseSchema: Schema });
//    ^? { approved: boolean }
The function’s generic inference picks this up automatically; you rarely need to write the type by hand.