Wrap your agent
Record a run with one wrap. Everything inside becomes part of it, and framework calls are captured automatically.
wrapAgent is the default way to instrument. You give it a name and a function, and everything that runs inside that function becomes one run, captured as a tree of spans. Calls to instrumented frameworks (OpenAI, Anthropic, LangChain, and more) are picked up automatically, so a single wrap is usually all you need.
When to use it
Reach for wrapAgent when your agent runs in one process and finishes within a single call stack: a request handler, a background job, a script. For runs that span many requests or workers, see Long-running & background runs. For steps that aren't auto-captured, add manual spans.
Example
import trodo from 'trodo-node';
trodo.init({ siteId: process.env.TRODO_SITE_ID }); // autoInstrument on by default
const { result, runId } = await trodo.wrapAgent(
'customer-support',
async (run) => {
run.setInput({ query });
const answer = await agent.run(query); // OpenAI / Anthropic / LangChain auto-captured
run.setOutput(answer);
return answer;
},
{ distinctId: userId, conversationId: sessionId },
);import os, trodo
trodo.init(site_id=os.environ['TRODO_SITE_ID']) # auto-instrument on by default
with trodo.wrap_agent(
'customer-support',
distinct_id=user_id,
conversation_id=session_id,
) as run:
run.set_input({'query': query})
answer = agent.run(query) # OpenAI / Anthropic / LangChain auto-captured
run.set_output(answer)Open the Agent Runs dashboard and the row shows tokens in and out, cost, span count, tool count, and error count, plus the full trace tree.
What you set vs. what's rolled up
You set a few things explicitly; Trodo derives the rest from the spans inside the run.
| You set | Trodo rolls up |
|---|---|
| Run name | Total tokens (in / out) |
Input (setInput) | Cost, from provider + model |
Output (setOutput) | Total latency |
distinctId, conversationId | Span, tool, and error counts |
Cost is computed server-side from (provider, model); the SDK only sends token counts. See Pricing to add custom model prices.
The run object
The callback (Node) or context manager (Python) hands you a run:
run.setInput(value); // the run's input (user query, request payload)
run.setOutput(value); // the run's final outputrun.set_input(value) # the run's input (user query, request payload)
run.set_output(value) # the run's final outputRun ID. You'll need the run's ID to attach feedback later. In Node it's returned from the wrap; in Python, read it off the run:
const { runId } = await trodo.wrapAgent('chat', async (run) => {
/* ... */
}, { distinctId: userId, conversationId: sessionId });
await trodo.feedback(runId, { satisfaction: 'positive', rating: 5 });with trodo.wrap_agent('chat', distinct_id=user_id, conversation_id=session_id) as run:
... # run.run_id is available here
trodo.feedback(run.run_id, satisfaction='positive', rating=5)Options
| Option | Description |
|---|---|
distinctId / distinct_id | The user behind the run. See Users. |
conversationId / conversation_id | Groups runs into a multi-turn session. See Conversations. |
Need to attach more? Add metadata you can filter on later.
Auto-instrumentation
trodo.init() turns on auto-instrumentation by default. Any installed framework call inside the wrap becomes a child span with its prompt, response, and token usage. Install the instrumentor for your stack under Frameworks.
Opt out per process:
trodo.init({ siteId: process.env.TRODO_SITE_ID, autoInstrument: false });trodo.init(site_id=os.environ['TRODO_SITE_ID'], auto_instrument=False)Next
- Add manual spans for steps that aren't auto-captured
- Group runs into conversations for multi-turn apps
- Browse framework guides