Reference
Event System
Open Astra emits typed, Zod-validated events for every significant action. Events are published on an in-process event bus and optionally forwarded to configured outbound webhooks. All event payloads are JSON-serializable.
Event bus
The event bus (events/bus.ts) is a singleton initialized at startup via getEventBus(). You can subscribe to events programmatically in plugins or custom tools:
import { getEventBus } from '../events/index';
const bus = getEventBus();
bus.on('agent.completed', (event) => {
console.log(\`Agent ${event.agentId} completed in ${event.durationMs}ms\`);
});
Agent events
| Event | When emitted | Key payload fields |
|---|
agent.started | At the start of each agent turn | agentId, sessionId, userId, surface |
agent.completed | After the agent turn finishes (including tool loop) | agentId, sessionId, durationMs, usage, toolCallCount |
agent.failed | When an unhandled error occurs during a turn | agentId, error, consecutiveFailures |
agent.paused | When max consecutive failures is reached | agentId, consecutiveFailures |
agent.resumed | When a paused agent is resumed | agentId, resumedBy |
agent.compacted | When context is compacted due to token limit | agentId, sessionId, messagesCompacted |
Streaming events
| Event | When emitted | Key payload fields |
|---|
agent.stream.delta | Each token chunk during streaming | agentId, sessionId, delta |
agent.stream.tool_call | When a tool call is detected in stream | agentId, toolName, params |
agent.stream.tool_result | After a tool finishes in stream | agentId, toolName, result, durationMs |
agent.stream.complete | When stream finishes | agentId, sessionId, totalTokens |
| Event | When emitted | Key payload fields |
|---|
tool.executed | After any tool call completes (success or error) | toolName, agentId, params, result, durationMs, error? |
Memory events
| Event | When emitted | Key payload fields |
|---|
memory.written | When a new memory entry is saved | tier, type, userId, workspaceId |
Session events
| Event | When emitted | Key payload fields |
|---|
session.created | When a new session is created | sessionId, userId, surface, agentId |
Webhook events
| Event | When emitted | Key payload fields |
|---|
webhook.dispatched | After an outbound webhook fires | url, event, statusCode, durationMs |
approval.requested | When a tool requires human approval | requestId, agentId, tool, params, expiresAt |
quota.exceeded | When a quota limit is hit | agentId, quotaType, limit, current |
Outbound webhooks
Configure a webhook URL to receive events as HTTP POST requests. The payload is a JSON object with an event field and all event payload fields. Requests are signed with HMAC-SHA256 using WEBHOOK_SECRET:
// Verify webhook signature in your receiver
import { createHmac } from 'crypto';
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === \`sha256=${expected}\`;
}