Skip to main content
A trace is one request your application handled: a root span with child spans for the model calls and tool calls it made. Hue shows, searches and evaluates what those spans record, so the shape of the trace and the content on each span decide what you can do with it later.

Span structure

Keep every model and tool span inside the request span that caused it, so the trace shows the order the work ran in. To include spans from instrumentation you already have, attach Hue to the OpenTelemetry provider that instrumentation uses (existing providers in TypeScript, tracer_provider= in Python); its spans then parent under the active Hue span, and you don’t need to replace it. Across processes, propagate W3C trace context: hue.inject(carrier) in the producer and hue.extract(carrier) as the parent in the worker. Hue never propagates the API key or baggage. A sub-agent that runs as its own trace can carry the parent’s user ID so you can follow it; see identify users.

Record what actually happened

Record the values your agent really received and returned, not summaries or reconstructions:
  • Request span: the user’s message or task as input and the reply the user saw as output. Hue titles traces from this input, and a case built from the trace uses it as the task.
  • Model spans: the messages in the shape you sent them, including system instructions and tool definitions when you send them separately, and the provider-reported token counts. Leave unknown usage absent rather than 0.
  • Tool spans: the exact arguments and the result the agent read. When code trims a tool result before the model sees it, record what the model saw.
Content capture is on by default in both SDKs; Data privacy explains the switch and the metadata-only opt-out. Hue stores what the spans carry. It doesn’t fill in missing prompts, invent output or estimate usage, and JSON null, false, 0 and "" stay distinct from an absent value.
callModel, lookupOrder and writeReply stand for your own code. With the Vercel AI SDK, the telemetry adapter creates the model and tool spans for you inside the request span. For tools the provider runs itself, such as hosted MCP or web search, pass the response to hue.recordProviderToolCalls(response) in TypeScript or model.record_provider_tool_calls(response) in Python, inside the model span (TypeScript, Python). When a tool is an MCP call, pass the server identity so the trace names the app it reached: mcp: client.getServerVersion() on hue.tool in TypeScript, or mcp= in Python. Hue uses it to match calls to simulated apps when you create a case.

Streaming and long work

A span measures the work inside it, so keep the request span open until the response stream and every tool it triggers have finished, or until the request is cancelled. A returned streaming Response is not the end of generation. Consume the stream inside the request span, or end the span from the framework’s completion hook: the AI SDK recipe awaits consumeStream(), and the Next.js recipe flushes after the response. In Python, a request span held across yield in a generator ends when the caller finishes reading. If the caller stops early, Python raises GeneratorExit inside the generator, and letting it escape records the span as failed. Return instead, so an abandoned stream ends the span normally:
In an async server, write the streaming body as an async generator and keep the span inside it; see Async servers. In a serving application, flush after the response with a bounded budget (flushSafe / force_flush_safe) and keep one client for the process lifetime. Never shut down a shared provider per request. See production setup for TypeScript and Python.

Identify users

Always attach a stable application user ID to the root span of each user request. Set user.id with OpenTelemetry, or pass userId (TypeScript) or user_id (Python) to the Hue SDK helpers. Reuse that ID across requests and sessions, including sub-agents. Child spans created by Hue SDK helpers inherit it. An opaque database ID works; you do not need an email address. Hue uses this identity to group the user’s traces and build their World. A trace ID or session ID cannot replace it. Without a root user ID or an explicit World entity, a trace cannot contribute to a user’s World.

Identify requests

These attributes let you and your coding agent filter, group and compare traces. The field glossary lists the attributes Hue maps into trace and span fields.
  • Mark failures. Set the span status to ERROR. error.type alone, or a Langfuse level, does not mark a failure. Hue helpers set both and never record exception messages or stack traces.
  • Sessions. Set session.id or gen_ai.conversation.id on the root. The SDK helpers take sessionId (TypeScript) or session_id (Python) and pass it to child spans.
  • Task types. Set a stable hue.trace.name or langfuse.trace.name, or give the root span a descriptive name.
  • Releases and environments. Set service.version to compare deployments and deployment.environment.name on the resource, with production for production traffic. Send development and staging to a separate project with its own key.

Check a trace

Open Traces in Hue, or ask your coding agent to read the trace over the Hue MCP server. Confirm that:
  • The model and tool spans sit under the request span in the order they ran. The request span is the trace root unless the request arrived with propagated parent context, which it keeps.
  • The request span shows the real user input and the reply, and the model and tool spans show their messages, arguments and results.
  • Sessions, users and errors appear where you expect them.
verifyTrace / verify_trace confirms which spans and fields arrived without reading their values (TypeScript, Python). It takes the trace ID and span IDs, which the helpers’ spans expose as traceId and spanId (trace_id and span_id in Python); with your own OpenTelemetry spans, read them from the span context. Images, audio and documents in a trace are covered in Media.