Observability
The platform's defining feature: every automated step leaves a queryable row. This page is the contract — what gets recorded, when, and what the UI depends on.
The four record types
| Record | Written by | Granularity | Key fields |
|---|---|---|---|
AgentRun | chat endpoint | one HTTP chat exchange | input_text, output_text, latency_ms, status, error_message |
ToolCall | every tool/LLM step | one automated action | tool_name, tool_input/output, success, latency_ms, model_name, estimated_tokens, estimated_cost, optional agent_run_id |
WorkflowRun | workflow endpoints | one pipeline execution | workflow_name, input_text, final_output, status, quality_score |
WorkflowStep | workflow endpoints | one pipeline stage | step_name, input_data, output_data, status, latency_ms |
The contract
- Every automated/LLM step logs a
ToolCall— success and failure. Failed calls carrysuccess="false"anderror_message, and are committed even when the request 500s. - LLM-backed tool calls attach cost data —
model_name,estimated_tokens,estimated_costfromestimate_openai_cost. - Tool calls inside a chat link to their run via
agent_run_id. - Multi-step pipelines create a
WorkflowRunfirst (status="running", committed immediately) and log aWorkflowStepper stage, finalizing status andquality_scoreat the end. - Latency is wall-clock milliseconds measured around the step:
int((time.time() - start) * 1000).
The dashboard, run history, and workflow trace UIs assume these rules. Breaking them silently breaks the product.
Current tool-call names
tool_name | Logged by | Costed? |
|---|---|---|
email_analyzer | single-agent analyze | ❌ |
task_creator | single-agent analyze | ❌ (no LLM) |
email_analyzer_or_task_creator | analyze failure path | ❌ |
multi_agent_analysis_agent | workflow stage 1 | ✅ |
multi_agent_task_agent | workflow stage 2 | ❌ (no LLM) |
multi_agent_reply_agent | workflow stage 3 | ✅ |
multi_agent_reviewer_agent | workflow stage 4 | ✅ |
multi_agent_email_workflow | workflow failure path | ❌ |
document_search | search endpoint | ❌ |
langgraph_corrective_rag | ask endpoint | ❌ |
The uncosted LLM paths (chat, analyze, RAG) are the contract's known gaps — see Known Issues.
Reading the telemetry
curl http://localhost:8001/agents/1/runs # chat executions
curl http://localhost:8001/agents/1/tool-calls # every automated step
curl http://localhost:8001/agents/1/workflow-runs # pipeline executions
curl http://localhost:8001/agents/workflow-runs/3/steps # one pipeline's traceA workflow trace reads like a flight recorder — for run 3 you will see analysis_agent, task_agent, reply_agent, reviewer_agent steps (or a workflow_error step), each with inputs, outputs, status, and latency.
The dashboard aggregation
GET /agents/{id}/dashboard computes, in Python, over all of an agent's rows:
| Metric | Source | Method |
|---|---|---|
total/open/in_progress/completed_tasks | tasks | count by status |
total/successful/failed_tool_calls | tool_calls | count by success string |
total/successful/failed_workflow_runs | workflow_runs | count by status |
average_latency_ms | tool_calls | mean of non-null latencies |
estimated_total_tokens | tool_calls | safe_int sum |
estimated_total_cost | tool_calls | safe_float sum → "%.6f" string |
average_quality_score | workflow_runs | mean of parseable quality_scores |
The Next.js dashboard renders exactly this payload — see Frontend Data Fetching.
average_latency_msaverages tool calls, not chat runs — chat latency lives onAgentRun.- Cost/token totals only reflect the costed workflow stages (table above), so they understate true usage.
- All numbers are estimates — see Cost Monitoring.
What observability does not include yet
No structured application logging, no metrics export (Prometheus/OTel), no alerting, no tracing across requests. The row-based telemetry is the foundation those would build on — see Roadmap.
Related pages
- Service: Monitoring — the estimation math
- ORM Models — the tables behind these records
- Workflows — the biggest telemetry producer