Skip to main content

notifications

In-app notifications primitive with pluggable server-side channels. Use when the agent needs to surface progress, alerts, or completions to the user — both in-app (bell + toast) and out-of-band (webhook, Slack, custom).

Source facts

Repository
BuilderIO/agent-native
Last source activity
April 23, 2026 at 14:00
Detected SKILL.md language
English
Stars
7,449
Forks
681

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
notifications
description
In-app notifications primitive with pluggable server-side channels. Use when the agent needs to surface progress, alerts, or completions to the user — both in-app (bell + toast) and out-of-band (webhook, Slack, custom).
# Notifications `notify()` is the framework's "tell the user something" primitive. Every call persists a row to the inbox (drives the bell UI) and fans out to any registered server-side channels. Channels follow the same pluggable-provider pattern as `tracking` — register at startup, `notify()` fans out, errors are isolated. Use for: *agent progress milestones, automation triggers firing, background job completions, critical errors*. Don't use for chat replies — those go through the conversation. ## Tools | Tool | Purpose | |---|---| | `notify` | Send a notification (severity + title + optional body/metadata/channels) | | `list-notifications` | Show recent notifications for the current user | ## Sending ``` notify --severity info --title "Booking confirmed" --body "Jane at 3pm" ``` | Severity | When | |---|---| | `info` | FYI / progress / confirmation | | `warning` | Something to look at soon | | `critical` | Needs immediate attention | Optional: `--metadataJson '{"threadId":"abc"}'`, `--channels inbox,webhook` (omit to run all registered). ## Delivery `notify()` always inserts into the `notifications` table (unless `channels` explicitly excludes `inbox`), then fans out to every registered channel in parallel (best-effort; a failing channel doesn't block others). Finally it emits `notification.sent` on the event bus so automations can chain — e.g. *"when a critical notification fires, also page on-call."* ## Built-in Channels | Channel | How | Requires | |---|---|---| | `inbox` | INSERT → drives bell UI | (always on) | | `webhook` | POST JSON to `NOTIFICATIONS_WEBHOOK_URL` (+ optional `NOTIFICATIONS_WEBHOOK_AUTH`); both support `${keys.NAME}` + URL allowlists from the ad-hoc-keys system | env var set | The webhook channel resolves `${keys.NAME}` server-side — the raw value never enters the agent context. ## Registering a Custom Channel ```ts // server/plugins/notifications-slack.ts import { registerNotificationChannel } from "@agent-native/core/notifications"; export default () => { registerNotificationChannel({ name: "slack-ops", async deliver(input, meta) { await fetch(process.env.OPS_SLACK_WEBHOOK!, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: `*${input.severity}* — ${input.title}`, owner: meta.owner }), }); }, }); }; ``` Names are unique — re-registering replaces. `deliver()` must be best-effort; a thrown error is logged and ignored. Do NOT call `notify()` from inside a channel (recursion). ## HTTP API Mounted at `/_agent-native/notifications/*` by `core-routes-plugin`, all session-scoped: - `GET /notifications?unread=true&limit=50&before=<iso>` - `GET /notifications/count` - `POST /notifications/:id/read` - `POST /notifications/read-all` - `DELETE /notifications/:id` ## UI ```tsx import { NotificationsBell } from "@agent-native/core/client/notifications"; <NotificationsBell browserNotifications /> ``` Bell icon + unread badge + lazy-loaded dropdown. Pass `browserNotifications` to also fire system `new Notification(...)` popups for items that arrive after mount (dedups by id, renders an "Enable" prompt until permission is granted, silently no-ops on denied / unsupported). Styled with shadcn tokens — adapts to the host theme. ## Related - `automations` — event-triggered bodies can call `notify`. - `secrets` — `${keys.NAME}` substitution + URL allowlists powering the webhook channel. - `tracking` — analytics; separate concern, don't route through notifications.
View on GitHub