Approvals
Approvals
Approvals pause pending tool calls until an authorized actor approves or denies them in chat.
Config
createHeypi({
approval: {
expiresInMs: 30 * 60_000,
allowSelfApproval: true,
bypass: {
durationMs: 5 * 60_000,
maxDurationMs: 15 * 60_000,
scope: "thread",
},
},
adapters: [
slack({
// ...Slack auth and delivery config
permissions: {
approvers: { users: ["U123"], groups: ["S123"] },
admins: { users: ["U999"] },
},
}),
],
// ...state, agent, runtime
});Options
approval controls approval behavior. Adapter permissions controls who can approve for that adapter.
| Option | Required | Default | Description |
|---|---|---|---|
expiresInMs |
No | No expiry | Milliseconds before a pending approval expires. |
allowSelfApproval |
No | true |
Whether a requester who is also an approver/admin can approve their own request. |
bypass |
No | Disabled | false disables bypasses. An object enables temporary approval bypasses. |
bypass options:
| Option | Required | Default | Description |
|---|---|---|---|
durationMs |
No | 300_000 |
Duration granted by an approval bypass decision. |
maxDurationMs |
No | 900_000 |
Upper bound for any bypass duration. |
scope |
No | thread |
Where the requester actor's bypass applies: thread, channel, user, or adapter. |
Bypasses are actor-bound. A thread bypass lets the same requester skip approval in that thread until expiry; it does not let other actors in the thread skip approval.
Adapter permissions.approvers and permissions.admins accept either an array of user IDs or { users, groups }. Admins inherit approver permissions. Group support depends on the adapter: Slack uses user group IDs, Discord uses role IDs, Telegram has no shared group concept, and webhook permissions use caller-provided user IDs.
Approval controls
Approval buttons are the primary control surface where the adapter supports them.
Typed fallback commands are provider-specific. Slack uses /heypi subcommands, Discord and Telegram use native commands, and webhook/internal adapters can send trusted text commands:
/approvals
/bypasses
/approve <approval-id>
/approve <approval-id> bypass
/deny <approval-id>
/revoke <bypass-id>In Telegram groups, use bot-qualified commands such as /approve@YourBotName <approval-id> when needed. In Slack, use /heypi approve <approval-id> instead of /approve. Natural language approval text is treated as a normal agent prompt, not as an approval decision.
In chat, /approvals lists pending approvals for the current channel. Use the admin UI or heypi approvals list for cross-channel inspection.
How calls become approvals
approval does not make every tool call require approval. Tool confirmation does that:
approval.command()controls bash risk policy.- Custom tools can return a confirmation object from
confirm. - Managed tools such as memory and skills use their own write policies.
See Agent tools: Confirmation for the confirm return shape and examples.
Notes
- Approval decisions are logged with the requester, approver, call, tool, and result.
- Without configured adapter approvers or admins, human approvals are limited by thread visibility, not by a central allowlist. Configure explicit adapter permissions for shared or team-facing bots.
allow.botslets bots send messages to the agent. It does not let bots list, approve, deny, or revoke approvals unless the bot actor is explicitly listed in adapterpermissions.approversorpermissions.admins.- Users can deny their own requested approval.
- Human requesters can approve their own pending request when they are authorized by the zero-config fallback or by adapter permissions, unless
allowSelfApprovalis disabled. - Pending approvals are persisted. On startup, heypi fails stale running calls and requeues stale running job runs from a previous process so they do not stay stuck in
running.
heypi logs a startup warning when bash or confirmed custom tools are enabled without explicit adapter approvers or admins.