awaithumans
v0.1.7
Published
HITL infrastructure for AI agents. Your agent calls awaitHuman(), a human reviews via Slack/email/dashboard, agent resumes with a typed response.
Maintainers
Keywords
Readme
awaithumans — HITL infrastructure for AI agents
Your agents already await promises. Now they can await humans.
Docs · Quickstart · Examples · Discord
HITL infrastructure for AI agents — open source. A single primitive (awaitHuman()) your agent calls when the model can't or shouldn't proceed alone. A human gets notified (Slack, email, or dashboard), reviews the request, submits a typed response, and your agent resumes — like awaiting any other promise.
import { awaitHuman } from "awaithumans";
import { z } from "zod";
const RefundRequest = z.object({
orderId: z.string(),
amountUsd: z.number(),
});
const Decision = z.object({
approved: z.boolean(),
note: z.string().optional(),
});
const decision = await awaitHuman({
task: "Approve refund request",
payloadSchema: RefundRequest,
payload: { orderId: "A-4721", amountUsd: 180 },
responseSchema: Decision,
timeoutMs: 900_000,
});
if (decision.approved) {
await processRefund(...);
}

Install
npm install awaithumans
# or
pnpm add awaithumans
# or
bun add awaithumansWorks in Node 20+, Bun, Deno, and edge runtimes (Cloudflare Workers,
Vercel Edge). No node:* imports.
Run the server
The awaithumans server (which handles task storage, Slack/email channels, and hosts the review dashboard) is written in Python. As a TypeScript developer you don't have to touch a Python environment — the npm CLI wraps it:
npx awaithumans devUnder the hood this uses uv to fetch + run the Python server on demand. Install uv once:
curl -LsSf https://astral.sh/uv/install.sh | sh # unix
powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # windowsFirst run prints a setup URL. Open it, create the operator account,
you're in. The dashboard is at http://localhost:3001.
Prefer Docker? docker run -p 3001:3001 ghcr.io/awaithumans/awaithumans:latest.
Tasks can be delivered to Slack channels with a "Claim this task" button — first clicker atomically wins, response form opens as a modal, agent unblocks when they submit. Add notify: ["slack:#ops"] to the awaitHuman() call:

Durable workflows
When your agent runs inside Temporal or LangGraph, you don't want the wait sitting on an orchestrator thread for 15 minutes:
// Temporal — signal-based suspend + callback
import { awaitHuman } from "awaithumans/temporal";
// LangGraph — interrupt/resume
import { awaitHuman } from "awaithumans/langgraph";Same awaitHuman shape, same typed response. The adapter just
changes how the wait is orchestrated.
Testing
An in-memory mock client so your agent tests don't need a running server:
import { createTestClient } from "awaithumans/testing";
const client = createTestClient();
// Drive the human's response programmatically.
client.onAwait((task) => ({ approved: true, note: "looks good" }));Documentation
- Repository: github.com/awaithumans/awaithumans
- Full docs: awaithumans.dev
- Quickstart:
examples/quickstart-ts/ - Changelog:
CHANGELOG.md
License
Apache License 2.0. The TypeScript SDK, every adapter subpath export, and the Python server + dashboard it talks to are all under the same license — permissive, OSI-approved, with an explicit patent grant.
