Skip to main content
The Observe section in the sidebar gives you a bird’s-eye view of everything happening in your Comis installation — how active your agents are, how much they cost, whether messages are being delivered successfully, how prompt caching is performing, whether spend is within its ceilings, and — when something goes wrong — the deterministic root cause. Each sub-view is its own page: Overview, Context Engine, Context DAG, Billing, Delivery, Diagnostics, Cache Health, Spend & Governance, and the Incident drill-down. (Security-decision history lives in its own Security & Audit view.) Who it’s for: anyone watching costs, debugging delivery failures, measuring cache effectiveness, enforcing spend ceilings, or root-causing a degraded session.

Where the metrics come from

All Observe data is sourced from Comis’s own in-process collectors and persisted to SQLite (in ~/.comis/). This native dashboard is the zero-dependency lens — it needs no external services. If you prefer the standards lens, Comis also ships an opt-in OpenTelemetry/Prometheus export surface (off by default): a loopback /metrics endpoint plus Grafana dashboards-as-code and a one-command docker-compose stand-up — see Prometheus & Grafana. The two render the same signals. The native dashboard reads them via JSON-RPC: Auto-refresh runs every 30 seconds; SSE event metrics:update triggers an extra refresh as soon as new data is recorded. A Prometheus /metrics endpoint is not exposed by default, but can be enabled via the opt-in Prometheus & Grafana surface (loopback-bound on 127.0.0.1:9464).
The Overview page at /observe/overview also contains five internal tabs — Overview, Billing, Delivery, Channels, and Diagnostics — that surface the same data as the standalone sub-views (plus a Channels tab unique to this page). The sidebar links route to the standalone components (e.g., /observe/billing); the Overview’s internal tabs offer a unified view within a single page.

What You See

Overview

Route: /observe/overview (also the default when clicking “Overview” in the sidebar) The Overview is your at-a-glance summary. At the top, six stat cards show recent activity numbers:
  • Requests/min — agent request rate (recent throughput)
  • Error Rate — percentage of failed deliveries, color-coded green/yellow/red
  • Avg Latency — average delivery latency in milliseconds
  • Active Agents — count of agents that are currently running (not suspended)
  • Tokens (24h) — AI tokens consumed in the last 24 hours
  • Cost Today — estimated cost across all providers
Below the stat cards, a 24-hour activity chart plots token usage over time so you can see when your agents are busiest, followed by per-agent and per-channel health grids. The Overview also includes internal tabs for Billing, Delivery, Channels, and Diagnostics within the same page.

Billing

Route: /observe/billing (standalone sub-view) The Billing view breaks down your AI spending across drill-down levels:
  • By Provider — one row per AI provider (such as Anthropic, OpenAI, or Google) showing the provider name, total tokens used, number of API calls, cost, and cache savings. The cache savings column shows how much prompt caching has reduced your spending for that provider. A totals row at the bottom sums everything up.
  • By Agent — one row per agent showing the agent name, tokens used, what percentage of total usage that agent accounts for, and cost.
This helps you answer questions like “Which provider is costing the most?” and “Is one agent consuming a disproportionate share of resources?”

Per-tool and per-subagent cost

At the agent level, two additional tables surface finer-grained attribution when the data is available:
  • Per-tool cost (labeled best-effort) — attributes a turn’s cost to the tool(s) that triggered it (from the tool_tag granularity). The per-tool shares are an even split across the distinct tools that fired in a turn, so they sum to the turn total — they are a labeled estimate, never an exact per-tool charge.
  • Per-subagent cost — the corrected-dollar cost rolled up per subagent node, showing both the node’s own cost and its subtree cost (the node plus all its descendants). This is exact within the agent graph.
These sections appear only when the daemon surfaces the granularity (governed by observability.costGranularity.{perTool, subagentRollup}); otherwise the view degrades silently rather than showing empty tables.

Filter and export

A filter bar at the agent level supports a typed-query DSL for narrowing the rows in place. Tokens are key:value, space-separated: Unknown keys are ignored (a hint names them) — the query never fails. The filter is applied entirely in the browser over already-fetched rows; it is never turned into a database query. The Export CSV and Export JSON buttons download the currently-filtered rows. The export carries a fixed set of cost columns only (agent id, tokens, percent-of-total, cost) — never message bodies or any other content.
The cache savings column helps you see the return on investment from prompt caching. Providers with high cache savings ratios indicate effective prompt reuse — your system prompts and repeated context are being cached efficiently. The per-tool table’s “best-effort” label is a reminder that a turn’s cost is split across its tools, not measured per tool.

Delivery

Route: /observe/delivery (standalone sub-view) The Delivery view tracks whether messages are actually reaching their destinations. At the top, you will see three summary numbers:
  • Success rate — the percentage of messages delivered successfully (green if 99%+, yellow if 95-99%, red below 95%)
  • Average latency — how long deliveries take on average
  • Total deliveries — the total count in the selected time window
Below the summary, a filter row lets you narrow results by:
  • Channel type — filter to a specific platform (Telegram, Discord, etc.)
  • Status — show only successful, failed, or timed-out deliveries
  • Time range — choose between 1 hour, 6 hours, 24 hours, or 7 days
The trace table below shows each delivery with its timestamp, channel, a short message preview, status, latency, and number of steps. Click any row to expand it and see the full delivery step waterfall — a step-by-step breakdown showing exactly where in the process a delivery succeeded or failed.

Diagnostics

Route: /observe/diagnostics (standalone sub-view) The Diagnostics view is an event log showing system-level activity. Each row has:
  • Time — when the event occurred
  • Category — what part of the system generated the event
  • Message — a description of what happened
  • Level — a severity badge (error, warning, or informational)
Events are sorted with the most recent at the top.

Cache Health

Route: /observe/cache (standalone sub-view) The Cache Health view answers “did prompt caching break this period, why, and what did it cost?” It reads obs.cacheBreaks.byReason and obs.cacheStats.window:
  • Stat cards — total cache breaks, $ lost (the summed directly-lost cache-read saving across all reasons), and the hit/write ratio.
  • Break-rate-by-reason table — one row per cache-break reason (e.g. tools_changed, system_prompt_changed, ttl_expired) with its count and estimated dollars lost. The dollar figure is 0 for an unknown-priced model (honest, never fabricated).
When the daemon surfaces no cache-break data, the view shows a “cache health not configured” empty state rather than a blank.

Spend & Governance

Route: /observe/spend (standalone sub-view) The Spend & Governance view is the native mirror of the Grafana Cost dashboard — no Grafana required. It reads the live spend the kill-switch enforces (obs.spend.snapshot, the in-memory accumulator — not a lagging SQL re-sum):
  • Headroom gauges — per-agent / per-tenant / global spend versus its ceiling, with the remaining headroom. A null ceiling renders a “spend governance not configured” state (honest — the kill-switch ships off with null ceilings).
  • Pricing coverage — the three-state split (priced / free / unknown) so you can see how trustworthy the dollars are before acting on them.
See Spend Governance (the cost kill-switch) for the enforcement policy these gauges visualize.

Incident (the root-cause drill-down)

Route: /observe/incident?ref=<sessionKey|traceId> (standalone sub-view) The Incident view is the in-product twin of comis explain: it surfaces the deterministic, no-LLM obs.explain IncidentReport for a single session — anomaly to root cause without leaving the product, and without Grafana. The same session always renders the same verdict. It is reachable from every per-session row — click a session in the Billing By-Session table, or the Explain Incident button in a session’s detail page — which navigates here keyed on that session’s sessionKey. The view renders:
  • Header — the outcome severity (ok / degraded / failed) and the deterministic likelyRootCause code.
  • Stat cards — cost, tokens, duration, turns, cache-read ratio.
  • Failures table and the circuit-breaker timeline (the normalized, newest-first failures + when each breaker opened/reset).
  • Optional, presence-conditional sections — rendered only when the session produced them: Spend (the kill-switch breach: scope + spent + ceiling), Cache breaks (per-reason count + $ lost), Recall (memory-recall outcome counts), and Audit (per-kind security-event counts). The report is content-free — counts, ids, dollars, and closed enums only, never a message body, query, or secret.
With no ref selected, the view shows a “select an incident to explain” empty state.
Grafana relationship — link, never embed. When the opt-in Prometheus & Grafana surface is enabled (observability.prometheus.enabled: true), the Incident view shows an “Open in Grafana” link to the matching dashboard (opening in a new tab). When Prometheus is disabled, no link is shown. The native dashboard never embeds Grafana (no <iframe>) — it stays a zero-dependency SPA. One signal set, two lenses.

Understanding Your Costs

The Billing tab is your best tool for keeping spending under control. Here is how to read it effectively:
  1. Start with the By Provider table to see which AI service is your biggest expense. The totals row at the bottom gives you the full picture.
  2. Switch to the By Agent table to find which agents are consuming the most resources. The percentage column makes it easy to spot outliers.
  3. Compare the two tables — a high-cost provider combined with a high-usage agent tells you exactly where to optimize.
Check the Billing tab weekly to catch unexpected cost increases early. A sudden spike in one agent’s token usage often means it is stuck in a loop or receiving more traffic than expected.

Tracking Message Delivery

When messages are not getting through, the Delivery tab helps you pinpoint the problem.
1

Switch to the Delivery tab

Click the Delivery tab at the top of the Observability view.
2

Filter by channel or status

Use the filter dropdowns to narrow results. To find problems quickly, set the status filter to Failed or Timeout.
3

Look for failed deliveries

Scan the trace table for rows with a red “failed” or orange “timeout” status badge.
4

Inspect the delivery waterfall

Click a failed delivery row to expand it. The step waterfall shows each stage of the delivery process with a green dot for successful steps and a red dot for the step that failed, along with the error message. This tells you exactly where the delivery broke down.
Data updates in real time via Server-Sent Events (SSE). Stat cards, tables, and charts refresh automatically as events arrive — there is no manual polling delay.

Context Engine

Route: /observe/context (standalone sub-view) The Context Engine view provides end-to-end observability for the DAG-based context pipeline. It refreshes automatically every 30 seconds and shows data for a selected agent or all agents at once via a filter dropdown.

Pipeline Metrics

The top section shows key metrics in a 2-column grid:
  • Cache Hit Rate — percentage of prompt cache reuse (displayed as a gauge)
  • Budget Utilization — how much of the token budget is being consumed (displayed as a gauge)
  • Token Budget Segment Bar — a full-width segmented bar showing how the token budget is allocated across system prompt, tools, context, and messages
  • Eviction Chart — breakdown of context evictions by category

Layer Waterfall

Below the metrics, a layer waterfall visualization shows the context assembly pipeline. Each layer represents a stage in context construction (system prompt, RAG results, session history, tool schemas, etc.) with timing information showing how long each layer took to assemble. This helps identify bottlenecks in context construction.

DAG Compaction Panel

When DAG compaction has occurred, an additional section shows compaction statistics:
  • Total Compactions — how many compaction operations have run
  • Avg Summaries — average number of summary nodes per compaction
  • Max Depth — the deepest level in the DAG tree
  • Latest Duration — how long the most recent compaction took (in milliseconds)

Context DAG Browser

Route: /context (standalone sub-view, listed under Observe in the sidebar) The Context DAG Browser is an interactive tool for inspecting the directed acyclic graph (DAG) of context nodes that the context engine builds during conversations. It uses a two-column layout:

Left Panel: Conversation List and Tree

  • Conversation list — shows all DAG conversations with their session keys. Select a conversation to load its tree structure.
  • Summary tree — an expandable tree view showing the hierarchical structure of the DAG. Nodes represent messages and summaries at various depth levels. Click a node to inspect it.
  • Search — a search bar performs server-side FTS5 full-text search within the selected conversation, highlighting matching nodes.

Right Panel: Node Inspection

When you click a node in the tree, a slide-in detail panel shows:
  • Node type — message or summary
  • Content — the full text content of the node
  • Depth — the node’s level in the DAG hierarchy
  • Kind — the node’s classification (e.g., user message, assistant response)
  • Token count — how many tokens the node content contains
  • Parent IDs — which nodes this node was derived from
  • Child IDs — which nodes were derived from this node
  • Source message count — for summary nodes, how many original messages were compressed
This view is primarily useful for operators debugging context compaction behavior, understanding how summaries are generated, and verifying that the DAG structure matches expectations.

Channels View

Manage your connected messaging platforms and see their status.

Operations Monitoring

Server-side monitoring, health checks, and alerting.

Agents View

View and manage your AI agents, their configuration, and activity.