Documentation Index
Fetch the complete documentation index at: https://docs.trodo.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
wrapAgent (the main pattern) handles the common case: an agent loop that runs to completion inside a single function call. But sometimes a logical “run” lives across multiple HTTP requests over many minutes — for example a long-lived chat session pinned to a websocket, or a scheduled job that gets resumed on a different worker.
For those cases use startRun (returns a runId) and endRun (finalises the run later — possibly from a different process). Between the two, any process can use joinRun(runId, …) to add child spans.
Not for MCP servers. If you’re building an MCP server, use
trackMcp instead — runless spans, no session lifecycle to manage. MCP servers proxy tool calls but don’t see the user’s prompt or the LLM’s final answer, so a Run wrapping an MCP session has no analytical content; and MCP has no clean session-end signal, so Runs created at initialize get stuck in running forever.When to reach for this
| Situation | Use |
|---|---|
| In-process agent: open → work → close in one function | wrapAgent |
| Downstream service joins an in-flight run | joinRun |
| MCP server (proxies tool calls; doesn’t see prompts) | trackMcp |
| Run spans many HTTP requests over hours, AND server owns prompt+answer | startRun + joinRun + endRun |
Example — websocket-pinned chat
- Node.js
- Python
runId threads through startRun → many joinRun calls → endRun. The dashboard shows one run, with every tool call as a child span beneath it.
API
startRun
| Option | Notes |
|---|---|
agentName | Required. Free-text identifier (e.g. "chat", "ingest_pipeline"). |
runId | Optional. Caller-supplied UUID for cross-process correlation. If omitted the SDK mints one and returns it. |
distinctId / distinct_id | The end user. Lets you filter runs per user across the dashboard. |
conversationId / conversation_id | Groups runs that belong to one user-facing conversation. |
parentRunId / parent_run_id | Marks this as a sub-agent run. |
metadata | Free-form JSON tags. |
input | Recorded as the run’s input for the dashboard. |
runId (string). The Run row exists in your dashboard immediately after this call resolves with status: "running".
endRun
| Option | Notes |
|---|---|
runId | Required (positional). |
output | Final output payload. Truncated at 64 KB. |
status | "ok" (default) or "error". |
errorSummary / error_summary | Human-readable error message — set when status="error". |
metadata | Optional final metadata to merge into the Run record. |
endRun aggregates any locally-buffered spans, finalises the row server-side, and unmarks the run as joined.
Why not wrapAgent?
wrapAgent is a single-context-manager block — open → work → close all happen in one call stack. That doesn’t fit when the run lives across multiple HTTP requests served by potentially different workers. startRun / endRun decompose the lifecycle so each phase can run in a different place.
For everything except long-lived multi-process sessions, prefer wrapAgent — it’s one HTTP call instead of two and keeps the surface area smaller.
Next
- wrapAgent — the in-process pattern.
- Spans (external) —
joinRunand cross-service propagation.