Heypi is code-first: every extension is plain TypeScript, not config. The main extension points are custom tools, confirmation rules, command risk classification, adapters, stores, attachment stores, and runtime providers. You can also load Pi extensions directly from your agent directory.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/hunvreus/heypi/llms.txt
Use this file to discover all available pages before exploring further.
Custom Tools
Usetool() to define a custom tool that integrates with Heypi’s confirmation and approval replay system. When a tool has a confirm handler, Heypi stores the pending call, renders approval buttons where the adapter supports them, and replays the tool after approval.
If you pass a tools array, include coreTools() explicitly to keep the built-in tool set:
execute function receives the tool parameters as the first argument and an execution context as the second. Use ctx.runtime when the tool needs command or file work to run through the selected runtime:
ctx.runtime is the raw selected runtime for the current turn. Runtime calls
inside a custom tool are covered by the tool’s own confirm result. Heypi
does not create separate nested approval records for those internal calls.
Custom tool JavaScript itself is not sandboxed — the application developer
owns that code.Raw Pi Tool Definitions
Raw PiToolDefinition objects are supported for tools that do not require confirmation. If a raw Pi tool includes a confirm field, Heypi fails closed because it cannot safely replay the tool after approval.
Dynamic Context
UseagentFrom(..., { context }) to append small runtime context blocks to the system prompt for each turn:
Confirmation
confirm controls whether a tool call needs approval. It can be a static object or a function that receives the tool’s arguments.
- Static
- Function
Return values
| Return value | Effect |
|---|---|
{ message, details } | Show approval prompt to approvers |
false or undefined | Allow the call without approval |
{ block: "reason" } | Block the call silently without asking |
message for user-facing approval copy. reason is accepted for compatibility and used as the main text when message is omitted. Use policyReason only for policy or audit detail (such as the command pattern that triggered approval) — adapters do not show it as the main approval text.
Approvers are configured at the app level:
approvers list means any user in the chat can approve.
commandConfirm()
commandConfirm() adapts command risk classification to the standard confirm contract. It is the default confirm handler for the built-in bash core tool.
Default hard blocks include commands such as rm -rf /, mkfs, shutdown, and reboot. Default approval patterns include commands such as curl, wget, ssh, docker, kubectl, terraform, helm, firewall changes, git push, and package publishing.
You can customize commandConfirm() directly through coreTools():
commandConfirm() directly inside a custom tool’s confirm handler:
details fields in Slack, Telegram, and Discord. Use details for visible, domain-specific fields on your custom tools — core bash confirmations already include a Command code field by default:
Command risk evaluation order
Commands are parsed before policy evaluation. Each simple command segment is classified separately and the highest risk wins.Custom block patterns
Match against your
block list first. Blocked commands are rejected immediately.Custom allow patterns
Your
allow rules can bypass approval for matching segments. They cannot bypass block patterns and do not allow other segments in the same compound command.Other Extension Points
Advanced extension contracts are available on explicit subpaths:Custom Adapters
Custom Adapters
Implement the The built-in adapters are concrete provider integrations, not subclassable base classes.
Adapter interface to integrate a new messaging platform. A custom adapter can live in a separate package and is registered exactly like a built-in adapter:Custom Stores
Custom Stores
Implement the
Store interface to use a different persistence backend. Production shared stores must provide durable locks. Scheduler-capable stores also need jobs and jobRuns. Implement transaction() when multiple repository updates must commit atomically.Custom Attachment Stores
Custom Attachment Stores
Implement
AttachmentStore and configure it with attachments: { store }. Attachment stores receive the current scope on save and resolve, and should reject cross-scope refs. Attachment processing options (including optional document conversion) are configured via attachments.process.The bundled document converter requires Python 3 and either
uv or
MarkItDown installed in the Python environment.Custom Runtime Providers
Custom Runtime Providers
Implement
RuntimeProvider and configure it with runtime.provider. Providers can add package-specific options and methods — such as previews, port forwarding, image setup, or remote workspace management — without changing Heypi core.Official experimental provider packages:@hunvreus/heypi-runtime-docker@hunvreus/heypi-runtime-gondolin
close().Pi Extensions
Pi Extensions
Pi extensions are loaded from explicit paths listed in
agent.extensions or from agent/extensions/. Heypi disables Pi’s default global extension discovery — configure each chat agent’s extension set directly.Extension code runs in-process and should be treated as trusted application code. Interactive Pi extension UI and slash-command flows are not exposed as first-class chat features.