Documentation
¶
Overview ¶
Package trace adds OpenTelemetry GenAI instrumentation to an agent — opt-in, so the core agent package carries NO OTel dependency (a user who doesn't import trace pays nothing; contrast frameworks whose core drags the full OTel + Temporal stack into every binary). It plugs in through the existing middleware hooks — Model (an agent.WithMiddleware middleware) and Tool (an agent.WithToolMiddleware middleware) — emitting spans with the OTel GenAI semantic-convention attributes. Instrument wires both onto an agent as one agent.Option.
We hardcode the stable gen_ai.* attribute keys rather than import the semconv module, which churns every release (v1.37 -> v1.41). Message and tool-argument CONTENT is not captured unless OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT is set to "true" or "1" (privacy-safe by default; unlike ADK #1634 which leaked tool args regardless), honoring the OTel GenAI convention's opt-in. Neither is error text, which can carry that content: with capture off a failed span records middleware.ErrorSummary (category, condition, provider status) as its status, and with it on its text, with every URL in it redacted. Pass WithRates to also record USD cost on the chat span.
Index ¶
- func Instrument(tracer oteltrace.Tracer, opts ...Option) agent.Option
- func Invoke(ctx context.Context, tracer oteltrace.Tracer, name string) (context.Context, func(error))
- func Model(tracer oteltrace.Tracer, opts ...Option) agent.Middleware
- func Tool(tracer oteltrace.Tracer) agent.ToolMiddleware
- type Option
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Instrument ¶
Instrument is the agent option that wires the gen_ai span taxonomy onto an agent in one call: the "chat" span (via Model) and the "execute_tool" span (via Tool), using tracer. It is the low-friction way to enable observability without hand-wiring each middleware, while the core agent package keeps no OpenTelemetry dependency (importing this package is the single opt-in). Options (WithRates) apply to the chat span. Its middleware is appended where the option appears among the agent's options. For the top-level "invoke_agent" span, wrap the run with Invoke, which lives at the call site rather than on the agent.
a, err := agent.New(model, journal, agent.WithTools(tools...), trace.Instrument(tracer, trace.WithRates(rates)))
func Invoke ¶
func Invoke(ctx context.Context, tracer oteltrace.Tracer, name string) (context.Context, func(error))
Invoke starts a top-level gen_ai "invoke_agent" span; call the returned end(err) when the run finishes. Wrap agent.Run:
ctx, end := trace.Invoke(ctx, tracer, "support-agent") msg, err := a.Run(ctx, runID, input) end(err)
func Model ¶
func Model(tracer oteltrace.Tracer, opts ...Option) agent.Middleware
Model returns middleware that wraps each model call in a gen_ai "chat" span with token usage, the finish reason and status. The span names the provider (gen_ai.system) and model (gen_ai.request.model) the call is sent to, as agent.ModelInfoOf reports them for call.Model; a Model that does not describe itself leaves both out, and the span is named "chat". Attach via agent.Agent.Use; placed outside a Hedge, the span names the primary.
func Tool ¶
func Tool(tracer oteltrace.Tracer) agent.ToolMiddleware
Tool returns tool middleware that wraps every tool call in a gen_ai "execute_tool" span. Attach with agent.WithToolMiddleware. Because it runs inside the agent loop, the span lives in the context passed to the tool — so when a tool is itself a sub-agent, that sub-agent's run (and its own spans) nest as children of this span: the trace crosses the sub-agent boundary automatically, a gap in ADK / AgenticGoKit / trpc-agent-go.
Types ¶
type Option ¶
type Option func(*config)
Option configures the chat span.
func WithRates ¶
func WithRates(r middleware.Rates) Option
WithRates records USD cost on the chat span (attribute gen_ai.usage.cost), computed from token usage at these rates. Reuses middleware.Rates so a caller pricing runs with a CostMeter uses one rate table for both.