Admin
Admin
Admin is a local web panel for inspecting and operating a running heypi app. It shows chats, thread timelines, approvals, scheduled jobs, eval definitions, memory files, configuration, approval policy, active approval bypasses, calls, runs, adapters, and activity.
In dev workflows, the Chats view can send local test messages through the same handler path used by adapters. Thread pages show summarized conversation by default, can expand to full trace logs, and expose cancel/status thread actions when a turn is active. The Chats sidebar groups conversations by adapter, supports filtering, and shows a live pulse for pending approvals, running runs, jobs, and refresh time.
Admin is disabled by default and is served under /admin/* when enabled.
Config
Enable admin:
createHeypi({
state: { root: "./state" },
admin: true,
// ...adapters, agent, runtime
});By default, admin binds to its own loopback listener at 127.0.0.1:4321. On startup, heypi logs a one-time login URL that expires after 5 minutes.
Use admin.http when you need a specific admin host or port. Use port: 0 for local development when you want the OS to pick a free port:
createHeypi({
state: { root: "./state" },
admin: {
http: { host: "127.0.0.1", port: 0 },
},
// ...adapters, agent, runtime
});heypi logs the actual bound port and one-time admin login link at startup. Use a fixed port when a reverse proxy, tunnel, or external provider needs a stable URL.
For local development only, auth can be disabled:
createHeypi({
state: { root: "./state" },
admin: { auth: false },
// ...adapters, agent, runtime
});auth: false is only valid on loopback. Never set it on a public host.
For non-loopback access, put admin behind HTTPS and an access-controlled proxy:
createHeypi({
state: { root: "./state" },
http: { host: "0.0.0.0", port: 3000 },
admin: {
http: { host: "127.0.0.1", port: 4321 },
secret: process.env.HEYPI_ADMIN_SECRET!,
},
// ...adapters, agent, runtime
});With this shape, public webhooks bind on 0.0.0.0:3000, while admin stays reachable only from the server itself. Access it through SSH port forwarding, VPN, or a reverse proxy with its own authentication.
If you intentionally bind admin to a non-loopback host, keep auth enabled, set a strong secret, put it behind HTTPS, and set secureCookies: true. Do not expose admin over plain HTTP.
Notes:
state.rootis the admin auth boundary. Use a separate state root when admin access should be separated.- Admin state is stored under
<state.root>/admin/. /adminis a reserved route prefix. User adapters cannot register routes under it.- Local dev test threads are hidden from admin thread lists by default. Set
admin: { localThreads: true }when you want those loopback test conversations visible beside real adapter conversations. - Admin does not edit config, edit secrets, or provide shell access. Its write surface is limited to local chat messages for dev testing, approval approve/deny actions, and thread cancel/status controls.
Views
| View | Purpose |
|---|---|
| Chats | Inspect conversations, messages, model events, tool calls, approvals, and trace events. Send local dev messages when using admin for local testing. |
| Approvals | Review pending approval requests and submit approve/deny decisions through the same handler path used by chat commands. |
| Jobs | Inspect configured scheduled and heartbeat jobs, targets, next run times, and recent run state. |
| Evals | Inspect loaded eval definitions, tags, expectations, timeouts, and full prompts. |
| Memory | Inspect durable memory files by scope, preview content, and copy full file details. |
| Config | Inspect app, adapter, runtime, approval, task, memory, and admin configuration summaries. |
CLI
Mint a fresh one-time admin login link:
heypi admin linkWhen @hunvreus/heypi is installed locally in the app, you can also use:
pnpm exec heypi admin link
npm exec heypi -- admin linkUseful flags:
| Flag | Purpose |
|---|---|
--state ./state |
Use a specific state root when running outside the app folder. |
--url http://127.0.0.1:4321 |
Override the discovered admin URL, for example through a tunnel or proxy. |
--pid <pid> |
Select one admin server when multiple descriptors exist. |
--json |
Print machine-readable output. |
admin link reads local admin state, verifies the discovered server descriptor, signs a short-lived URL, and prints it. It does not ask the running server to mint tokens.