The BentoLabs dashboard (conversation timelines, cost breakdowns, user analytics, agent behavior views) is built from four primitives the SDK emits as you run your app. Once you know what each one represents, you can predict how any chart in the product is computed.Documentation Index
Fetch the complete documentation index at: https://docs.bentolabs.ai/llms.txt
Use this file to discover all available pages before exploring further.
The four primitives
Trajectory
One run of your agent. The root span of a trace.
bento.begin(...) · @bento.interactionSpan
One step inside a trajectory. An LLM call, a tool call, or anything you choose to time.
bento.track_ai(...) · bento.tool_span(...) · @bento.toolAttribute
A typed key/value pair on a span. Becomes a column or filter in the dashboard.Kwargs on the calls above, plus
properties={...}Session
All trajectories that share a
convo_id. A server-side grouping, not an SDK object.Pass the same convo_id on every call.Under the hood these are OpenTelemetry spans with OpenInference and GenAI semantic conventions. You can ignore that unless you’re wiring BentoLabs into an existing OTel pipeline.
How they nest
track_ai call with no surrounding begin is its own one-span trajectory. You don’t have to open a trajectory to record an LLM call.
What gets emitted
Every call produces one OTel span. The attributes below land in dashboard columns. Everything else lives in the per-span attributes JSON.| Concept | OTel attribute | Dashboard column |
|---|---|---|
| Span name | span.name | Span name |
| User | gen_ai.user.id | User |
| Conversation | gen_ai.conversation.id | Session |
| Model | gen_ai.request.model | Model |
| Provider | gen_ai.system | Provider |
| Input | input.value | Input |
| Output | output.value | Output |
| Span kind | openinference.span.kind | Kind |
| Custom | (your properties keys) | Attributes JSON |
Span kinds
Theopeninference.span.kind attribute drives icons, colors, and filters in the dashboard.
| Kind | Emitted by | Meaning |
|---|---|---|
| (default) | bento.track_ai | A model call. Carries gen_ai.* attributes. |
tool | bento.tool_span, @bento.tool, interaction.tool_span | A tool or function call. |
retriever, embedding, agent, chain). Set them by passing openinference.span.kind in properties.
Sessions are server-side
There is noSession object in the SDK. A session is whatever trajectories share the same convo_id string.
user_id works the same way: a free-form string passed on every call. We do not store profile data.
See Sessions and users for ID-choosing rules.