EdgeStream
ANCP Protocol View
The Event Stream at /events is the raw envelope viewer — every message that arrives on the EdgeStream SignalR connection is logged here with full envelope detail. It is the lowest-level diagnostic tool in DevTools.
Event Viewer vs Node Explorer
DevTools has two views related to ANCP:
| View | Route | What It Shows | Protocol |
|---|---|---|---|
| Event Stream | /events | All raw IEnvelope messages arriving on SignalR, including ANCP topic envelopes | EdgeStream SignalR |
| Node Explorer | /ancp | Interactive ANCP node connection — ping, capabilities, action invoke | ANCP HTTP direct |
Event Stream — Raw Envelope Viewer
// Route in App.tsx
<Route path="/events" element={<EventViewerPage />} />
// EventViewerPage source: packages/app-pages-react/src/EventViewerPage.tsx
// Every message flowing through the EdgeStream pipeline is displayed:
// - workflow.* events
// - agent.* messages
// - ui.* actions
// - system.* broadcasts
// - ancp.* protocol frames (heartbeat, capability, flow-control, ack)
// Each entry shows the full IEnvelope:
{
meta: {
id: string, // unique message ID
serverId: string, // which server it came from
transport: string, // 'signalr'
protocol: string, // message protocol version
receivedAt: string, // ISO timestamp
topic: string, // e.g. 'ancp.heartbeat'
correlationId: string, // links request-reply pairs
},
direction: 'inbound' | 'outbound',
body: object, // the parsed message payload
headers: Record<string, string>,
attributes: Record<string, unknown>,
}
Viewing ANCP Messages via Event Stream
ANCP protocol frames appear in the Event Stream alongside all other EdgeStream messages. To isolate ANCP traffic from the raw event viewer, you can subscribe to the ancp.* topic namespace:
// Monitor ANCP protocol activity from your own code:
const stream = useEdgeStream();
stream.subscribe('bas', 'ancp.*', (envelope) => {
const { topic } = envelope.meta;
switch (topic) {
case 'ancp.heartbeat':
// { nodeId, timestamp, sequenceNumber }
console.log('Heartbeat from node', envelope.body.nodeId);
break;
case 'ancp.capability.advertise':
// { nodeId, actions: AncpActionDescriptor[] }
console.log('Capability update', envelope.body.actions.length, 'actions');
break;
case 'ancp.flow.control':
// { nodeId, backpressure: 'apply' | 'release', queueDepth }
console.log('Flow control signal', envelope.body.backpressure);
break;
case 'ancp.ack':
// { correlationId, nodeId, success }
console.log('Ack for', envelope.body.correlationId);
break;
case 'ancp.error':
// { code, message, nodeId }
console.error('ANCP error', envelope.body.message);
break;
}
});
ANCP Topic Reference
| Topic | Direction | Payload Key Fields |
|---|---|---|
ancp.heartbeat | Node → Server | nodeId, timestamp, sequenceNumber |
ancp.capability.advertise | Node → Server | nodeId, actions[] |
ancp.capability.query | Server → Node | requestingAgent |
ancp.flow.control | Bidirectional | nodeId, backpressure, queueDepth |
ancp.route.update | Server → Node | routes[], ttl |
ancp.ack | Node → Server | correlationId, nodeId, success |
ancp.error | Bidirectional | code, message, nodeId |
Activity Stream — Processed View
The Activity Stream at /activity-stream provides a higher-level view than the raw Event Stream. It shows message processing outcomes — not raw envelopes:
// Route in App.tsx
<Route path="/activity-stream" element={<ActivityStreamPage />} />
// ActivityStreamPage wraps ActivityStreamMonitor from @edge-stream/observability-react
// Filter by:
// - Status: all | completed | failed | processing
// - Server ID: text match
// - Search: text search across message content
// Two view modes (persisted in localStorage 'activity-stream-view-mode'):
// - Overview: summary table of all processed messages
// - Timeline: chronological log with hook/subscriber breakdown
// Controls:
// - Export: downloads JSON of current filtered log set
// - Clear: calls loggingService.clearAllLogs()
// - Refresh: re-queries loggingService.queryLogs(filter)
ANCP and EdgeStream Together
ANCP frames that flow through the EdgeStream pipeline appear in both the Event Stream (raw) and the Activity Stream (processed). Use Event Stream to see the raw envelope fields; use Activity Stream to see which hooks and subscribers processed each message and whether they succeeded.
EnvelopeViewer Component
The Event Stream uses the EnvelopeViewer component from app-pages-react to render each envelope with expandable JSON trees:
// packages/app-pages-react/src/components/EnvelopeViewer.tsx
// Renders:
// - Topic badge (colored by namespace)
// - Direction indicator (inbound / outbound)
// - Timestamp
// - Collapsible sections for: meta | body | headers | attributes
// - JsonViewer for body content
// Color coding by topic namespace:
// workflow.* → blue
// agent.* → purple
// ui.* → orange
// system.* → yellow
// ancp.* → teal