Noddocs

Activity & Observability

See what every agent is doing in real time

Overview

The activity feed is a live stream of everything your agents are doing. It shows decisions created and resolved, messages sent, actions performed (file edits, commands, searches), and system events. Users see this in the Activity tab of the Nod app.

Event types

TypeDescriptionExample
decision_createdAgent created a new request"Deploy Bot requested: Deploy to production?"
decision_resolvedA request was approved/rejected/responded to"Alice approved: Deploy to production"
agent_messageAgent sent a chat message"Deploy Bot sent a message"
agent_actionAgent performed an action"Running: npm install stripe"
systemLifecycle event"Deploy Bot: started"

Logging activity from your agent

Use the alert event type to log actions to the activity feed:

Via REST
POST /api/agent/events
{
  "type": "alert",
  "title": "Running: npm install stripe",
  "text": "npm install stripe --save",
  "task_run_id": "run_abc123"      // optional — links to a task run
}
Via WebSocket
{
  "type": "alert",
  "title": "Editing src/index.ts",
  "text": "/Users/alice/project/src/index.ts"
}

The title is what users see in the feed. The text is shown as a subtitle with additional detail. If you include task_run_id, the activity is linked to that specific task run.

Processing indicators

Show users when your agent is actively working. The Nod app displays a "Thinking..." bubble in the chat with an animated indicator. While this bubble is active, any activity events (alert) your agent logs will update the bubble text in real time — so users see exactly what the agent is doing (e.g. "Running tests...", "Searching the web...").

Processing indicators work via both WebSocket and REST, with different patterns suited to each connection type.

WebSocket agents (automatic)

WebSocket-connected agents use a heartbeat/idle cycle. The Nod app automatically shows the "Thinking..." bubble when the user sends a message or approves a request — your agent just needs to keep it alive and signal when it's done.

1. Keep the indicator alive (send every ~1 second)
// Default — shows "Thinking"
{ "type": "agent_heartbeat", "conversation_id": "conv_abc123" }

// With custom label — updates the bubble text instantly
{ "type": "agent_heartbeat", "conversation_id": "conv_abc123", "status_text": "Searching the web..." }
{ "type": "agent_heartbeat", "conversation_id": "conv_abc123", "status_text": "Reading files..." }
{ "type": "agent_heartbeat", "conversation_id": "conv_abc123", "status_text": "Running tests..." }
2. Signal completion — clears the indicator
{ "type": "agent_idle", "conversation_id": "conv_abc123" }

The heartbeat system is smart — it only writes to the database on state transitions (idle → processing, text changes), not on every heartbeat. So sending heartbeats every second is efficient.

While the indicator is active, any alert events your agent logs will update the bubble text. For example, logging {"type": "alert", "title": "Editing src/index.ts"} will change the bubble from "Thinking..." to "Editing src/index.ts" automatically.

Webhook agents (explicit start/stop)

Webhook-based agents (n8n, Make, custom workflows) don't have a persistent connection, so the app cannot show the indicator automatically. Instead, use explicit start and stop events via REST.

1. Start the indicator
POST /api/agent/events
{
  "type": "processing_start",
  "conversation_id": "conv_abc123"
}

// With custom label
{
  "type": "processing_start",
  "conversation_id": "conv_abc123",
  "status_text": "Processing your request..."
}
2. Stop the indicator
POST /api/agent/events
{
  "type": "processing_stop",
  "conversation_id": "conv_abc123"
}

Between start and stop, any alert events you send will update the bubble text — just like WebSocket agents. For example, an n8n workflow might:

Example: n8n workflow sequence
POST → { "type": "processing_start", "conversation_id": "conv_abc123" }
POST → { "type": "alert", "title": "Searching the web..." }
POST → { "type": "alert", "title": "Summarizing results..." }
POST → { "type": "message", "text": "Here are the results...", "conversation_id": "conv_abc123" }
POST → { "type": "processing_stop", "conversation_id": "conv_abc123" }
If your agent crashes and processing_stop is never sent, the indicator auto-clears after 30 seconds. This is a built-in safety net — no action required.

Online status

When your agent connects via WebSocket, it automatically shows as online in the Nod app. When it disconnects, the status updates accordingly. Users can check the current session state:

GET /api/agents/:id/session
{
  "is_online": true,
  "is_processing": true,
  "conversation_id": "conv_abc123",
  "status_text": "Searching the web..."
}

Task run activities

Activities logged during a task run (with task_run_id set) are associated with that run. Users can view per-run activities in the task detail view:

GET /api/tasks/runs/:run_id/activities
See Activity API for the full endpoint reference and response format.