Portal Community

Event Viewer vs Node Explorer

DevTools has two views related to ANCP:

ViewRouteWhat It ShowsProtocol
Event Stream/eventsAll raw IEnvelope messages arriving on SignalR, including ANCP topic envelopesEdgeStream SignalR
Node Explorer/ancpInteractive ANCP node connection — ping, capabilities, action invokeANCP 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

TopicDirectionPayload Key Fields
ancp.heartbeatNode → ServernodeId, timestamp, sequenceNumber
ancp.capability.advertiseNode → ServernodeId, actions[]
ancp.capability.queryServer → NoderequestingAgent
ancp.flow.controlBidirectionalnodeId, backpressure, queueDepth
ancp.route.updateServer → Noderoutes[], ttl
ancp.ackNode → ServercorrelationId, nodeId, success
ancp.errorBidirectionalcode, 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