Production infrastructure for AI agents
Website · Documentation · Guides · Core · Template · Discord
systemprompt-events
Every A2A, AG-UI, analytics, and context event fans out through one bus, and a durable Postgres outbox carries it across replicas so nothing is lost to a restart. Any component holding a UserId can publish without touching the wire format.
Layer: Infra. Infrastructure primitives consumed by the domain and application crates. Part of the systemprompt-core workspace.
What it does
The in-process event bus fans typed events out to per-user SSE connections, managing connection lifecycles and cleaning up disconnected clients. It is not SSE-only: a durable Postgres outbox (event_outbox table, via LISTEN/NOTIFY) relays events across replicas so a multi-instance deployment stays consistent. The crate is shared between the HTTP API entry crate and the runtime layer.
Modules
| Module | Purpose |
|---|---|
services |
The GenericBroadcaster implementation and per-event aliases, the static EventRouter, ConnectionGuard, keep-alive utilities, the PostgresEventBridge (LISTEN/NOTIFY relay), and the outbox repository. |
sse |
The ToSse trait and serde-driven impls converting systemprompt-models event types into axum SSE records. |
extension |
EventsExtension declares the event_outbox schema through the workspace extension framework. |
error |
EventError / EventResult. |
Schema DDL lives in schema/ (event_outbox.sql plus the migrations/ directory).
Event flow
┌─────────────────┐
│ EventRouter │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────────┐
│AGUI_BROADCASTER│ │A2A_BROADCASTER│ │CONTEXT_BROADCASTER│
└───────┬───────┘ └───────┬───────┘ └─────────┬─────────┘
│ │ │
▼ ▼ ▼
SSE Clients SSE Clients SSE Clients
AG-UI and A2A events route to both their primary broadcaster and the context broadcaster for aggregation. Across replicas, PostgresEventBridge relays outbox rows so an instance publishes locally and every other instance sees it.
Usage
[]
= "0.21"
use ;
use UserId;
async
Public API
Traits
| Trait | Methods | Purpose |
|---|---|---|
Broadcaster |
register, unregister, broadcast, connection_count, total_connections |
Type-safe event broadcasting |
Types
| Type | Description |
|---|---|
EventSender |
tokio::sync::mpsc::Sender<Result<Event, Infallible>> |
EventError / EventResult<T> |
thiserror-derived error and result alias |
GenericBroadcaster<E> |
Generic broadcaster for any ToSse + Clone + Send + Sync event |
AgUiBroadcaster |
GenericBroadcaster<AgUiEvent> |
A2ABroadcaster |
GenericBroadcaster<A2AEvent> |
ContextBroadcaster |
GenericBroadcaster<ContextEvent> |
AnalyticsBroadcaster |
GenericBroadcaster<AnalyticsEvent> |
ConnectionGuard<E> |
RAII guard for automatic unregistration |
EventRouter |
Routes events to appropriate broadcasters |
PostgresEventBridge |
LISTEN/NOTIFY relay draining the event_outbox table across replicas |
OutboxChannel / OUTBOX_CHANNEL |
Outbox notification channel type and name |
EventsExtension |
Extension registering the event_outbox schema |
Constants
| Constant | Value | Purpose |
|---|---|---|
HEARTBEAT_INTERVAL |
15 seconds | SSE keep-alive interval |
HEARTBEAT_JSON |
{"type":"heartbeat"} |
Keep-alive payload |
Global Singletons
| Static | Type | Purpose |
|---|---|---|
AGUI_BROADCASTER |
LazyLock<AgUiBroadcaster> |
AG-UI event broadcasts |
A2A_BROADCASTER |
LazyLock<A2ABroadcaster> |
Agent-to-agent events |
CONTEXT_BROADCASTER |
LazyLock<ContextBroadcaster> |
Aggregated context events |
ANALYTICS_BROADCASTER |
LazyLock<AnalyticsBroadcaster> |
Analytics event tracking |
Tests
Tests are located in crates/tests/unit/infra/events/ following the project convention of separating tests from source files.
Dependencies
| Crate | Purpose |
|---|---|
systemprompt-models |
Event types (AgUiEvent, A2AEvent, ContextEvent, SystemEvent, AnalyticsEvent) |
systemprompt-identifiers |
UserId / ConnectionId types (sqlx feature) |
systemprompt-extension |
Schema registration for the event_outbox table |
tokio |
Async runtime, channels, synchronization |
axum |
SSE Event and KeepAlive types |
sqlx |
Durable outbox relay over Postgres LISTEN/NOTIFY |
chrono |
Outbox row timestamps |
inventory |
Compile-time extension registration |
serde / serde_json |
Event serialization |
tracing |
Structured logging |
License
BSL-1.1 (Business Source License). Source-available for evaluation, testing, and non-production use. Production use requires a commercial license. Each version converts to Apache 2.0 four years after publication. See LICENSE.
systemprompt.io · Documentation · Guides · Live Demo · Template · crates.io · docs.rs · Discord
Infra layer · Own how your organization uses AI.