Every framework eventually faces a fork: do we let users customize anything they want, or do we constrain them to a small set of well-defined extension points? awaithumans takes the second path. Customization goes through one of four buckets. Anything that doesn’t fit one of these is by design unsupported — you write a wrapper around the SDK, not a fork of the core.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.
| Bucket | Where it runs | What it customizes |
|---|---|---|
| Channel | Server-side | How a task is delivered to humans (Slack, email, SMS, …) |
| Verifier | Server-side | Quality-check the human’s response before committing |
| Router | Server-side | Resolve assign_to to a specific user / pool / role |
| Task-type handler | Dashboard + server | Render the human-facing UI from a schema |
Channel
A channel is “how does the human find out about the task and respond?” Built-in channels:- Dashboard (always on) — operators log in via
/login, see their queue, click in to fill the response form - Slack — Block Kit message with a Review button, opens a modal with the form
- Email — Resend / SMTP, action buttons for boolean / single-select fields, magic-link confirmation page
- Subscribes to
notify=[...]strings with your prefix (sms:,pagerduty:, …) - Builds a delivery message from the task’s
form_definition - Receives the human’s reply (webhook from your provider) and calls
complete_task()on the awaithumans server
Verifier
A verifier is an LLM-backed quality check that runs server-side after the human submits. Two jobs in one call:- Quality: was the response acceptable per the operator’s
instructions? - NL parsing: if the human replied in free text (Slack thread, email body), extract structured data into the response schema.
claude(Anthropic) — uses tool-use for structured outputopenai— usesresponse_format: json_schemastrict modegemini(Google) — usesresponse_schemaazure(Azure OpenAI) — same shape as openai, deployment-name addressing
server/verification/providers/ exporting an async verify(config, ctx) -> VerifierResult. See Verifier.
Router
A router resolves theassign_to= field on a task to a specific human (or a list, or a pool). Built-in resolution:
assign_to="alice@acme.com"→ that userassign_to=["a@b.com", "c@d.com"]→ first to claimassign_to={"role": "kyc-reviewer"}→ pool of users with that roleassign_to={"pool": "ops", "access_level": "senior"}→ filter by pool + level
Task-type handler
A task-type handler is a dashboard React component that renders the human-facing form from a schema. The default handler renders any Pydantic / Zod schema as a generic form — it works for 80% of tasks out of the box. Custom handlers exist for cases where generic JSON-schema rendering isn’t enough: file uploads with drag-drop, signature pads, image annotation, embedded video review. The dashboard’scomponents/form-renderer/ is the registry; you register a component for a kind value in the form definition.
For v0.1 the default handler covers everything. Custom task-type handlers are a Phase-2 plugin point — declared here so the architecture stays open, but no built-ins beyond the default.
What’s NOT a bucket
By design, these don’t get extension points:- Storage — Postgres or SQLite, nothing else. We test both.
- Queue / scheduling — single-process timeout scheduler, no Redis / Celery / RabbitMQ.
- Auth — argon2id passwords + HMAC session cookies. SSO comes via the hosted product post-launch.
- The
await_human()signature — public API; breaking it is a v1.0 event.
Why this matters
The constraint earns the architecture’s reliability. With four well-defined extension points:- The wire format between the SDK and the server is locked. Bumping the SDK in your agent code can’t break the dashboard.
- The error contract is locked. Every typed error has a docs URL and an action.
- Reviewing a contributor’s PR is fast: which bucket is this? Does it stay inside?
refuse-customization-creep rule: per-customer divergence goes into adapters, never into core forks.