Documentation
¶
Overview ¶
Package telemetry instruments the turn loop with OpenTelemetry spans at the key points (turn, LLM request, tool execution, sub-agent). It uses only the OTel API: with no TracerProvider/exporter configured (the default) every span is a no-op, so this is safe and cheap until the platform wires an exporter.
Upstream linkage: the inbound MessageAddress.telemetry may carry a W3C traceparent/tracestate (the cross-system OTel plan), which LinkUpstream extracts so the agent's spans are children of the originating trace.
Index ¶
- func AnnotateToolResult(span trace.Span, outputs json.RawMessage, isError bool)
- func Finish(span trace.Span, err *error)
- func FinishErr(span trace.Span, err error)
- func LinkUpstream(ctx context.Context, addr protocol.MessageAddress) context.Context
- func RecordLLMCachePlan(span trace.Span, stablePrefixBytes int, ...)
- func RecordLLMResult(span trace.Span, model string, ...)
- func SetConventions(c Conventions)
- func StartLLM(ctx context.Context, model string) (context.Context, trace.Span)
- func StartSubagent(ctx context.Context, depth int) (context.Context, trace.Span)
- func StartTool(ctx context.Context, name string, inputs json.RawMessage) (context.Context, trace.Span)
- func StartTurn(ctx context.Context, addr protocol.MessageAddress) (context.Context, trace.Span)
- type Conventions
- type MLflowConventions
- func (MLflowConventions) LLM(string) []attribute.KeyValue
- func (MLflowConventions) Subagent() []attribute.KeyValue
- func (MLflowConventions) Tool(inputs json.RawMessage) []attribute.KeyValue
- func (MLflowConventions) ToolResult(outputs json.RawMessage, isError bool) []attribute.KeyValue
- func (MLflowConventions) Turn(protocol.MessageAddress) []attribute.KeyValue
- type NoConventions
- func (NoConventions) LLM(string) []attribute.KeyValue
- func (NoConventions) Subagent() []attribute.KeyValue
- func (NoConventions) Tool(json.RawMessage) []attribute.KeyValue
- func (NoConventions) ToolResult(json.RawMessage, bool) []attribute.KeyValue
- func (NoConventions) Turn(protocol.MessageAddress) []attribute.KeyValue
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AnnotateToolResult ¶
func AnnotateToolResult(span trace.Span, outputs json.RawMessage, isError bool)
AnnotateToolResult records the tool's output payload + error flag on its span via the active convention (e.g. MLflow spanOutputs + tool.is_error). Safe on a nil/empty payload. Call before Finish/FinishErr.
func Finish ¶
Finish ends a span, recording an error+status when *err is non-nil. Intended for `defer Finish(span, &err)` with a named error return.
func FinishErr ¶
FinishErr ends a span, recording an error+status when err is non-nil. For call sites with a plain (non-pointer) error in scope.
func LinkUpstream ¶
LinkUpstream returns a context whose remote span context is extracted from the inbound address's telemetry (traceparent/tracestate), so spans started under it are children of the upstream trace. When absent, ctx is returned unchanged.
func RecordLLMCachePlan ¶ added in v0.0.2
func RecordLLMCachePlan(span trace.Span, stablePrefixBytes int, stablePromptDigest, dynamicSuffixDigest, toolSchemaDigest string)
RecordLLMCachePlan records only stable prompt/tool digests and the prefix byte count. The underlying prompt and schemas are intentionally excluded.
func RecordLLMResult ¶
func RecordLLMResult(span trace.Span, model string, promptTokens, completionTokens, totalTokens, cachedInputTokens, cacheCreationInputTokens int, latency time.Duration)
RecordLLMResult stamps the served model, token usage, and wall-clock latency on the LLM span (best-effort; a no-op span just drops them). Call on a successful provider response before Finish. Generic attribute keys; a convention MAY remap.
func SetConventions ¶
func SetConventions(c Conventions)
SetConventions swaps the active convention (no-op on nil). Call once during startup, before the first turn — it is not safe to change concurrently with span creation.
func StartLLM ¶
StartLLM starts a span around one provider request (generic llm.model attribute). Whether it carries a backend span-type is the convention's call — the MLflow convention leaves it untyped so the platform gateway can supply the authoritative LLM mirror span (linked via the injected traceparent) without double-counting.
func StartSubagent ¶
StartSubagent starts a span around an in-process sub-agent run (generic depth attribute); the convention adds any backend span-type mapping.
func StartTool ¶
func StartTool(ctx context.Context, name string, inputs json.RawMessage) (context.Context, trace.Span)
StartTool starts a span around one tool execution. The span is NAMED after the tool (e.g. "frontend_show_toast") — MLflow's Tool Calls dashboard labels/aggregates TOOL spans by span name, so a static name would collapse every tool into one row. The convention adds the backend span-type + inputs mapping (raw JSON args); pair with AnnotateToolResult at the finish site.
Types ¶
type Conventions ¶
type Conventions interface {
// Turn returns backend attributes for the per-turn root span.
Turn(addr protocol.MessageAddress) []attribute.KeyValue
// LLM returns backend attributes for a provider-call span.
LLM(model string) []attribute.KeyValue
// Tool returns backend attributes for a tool-exec span; inputs is the raw
// JSON tool arguments (may be empty).
Tool(inputs json.RawMessage) []attribute.KeyValue
// ToolResult returns backend attributes recorded at tool finish; outputs is
// the raw JSON result payload (may be empty).
ToolResult(outputs json.RawMessage, isError bool) []attribute.KeyValue
// Subagent returns backend attributes for a sub-agent span.
Subagent() []attribute.KeyValue
}
Conventions maps the harness's semantic span points (turn, LLM call, tool exec, sub-agent) onto a tracing backend's attribute vocabulary, so a backend whose conventions differ from MLflow's — e.g. OpenInference or the OTel GenAI semantic conventions — can be swapped in without touching the turn loop. Each method returns ONLY the backend-specific attributes for that span; the generic identity attributes (scitrera.*, llm.model, tool.name, subagent.depth) are always set by the telemetry package regardless of the active convention.
Implementations must be safe to call with a nil/zero convention receiver and return nil when they have nothing to add.
func SelectConventions ¶
func SelectConventions(name string) Conventions
SelectConventions maps a name (e.g. from SAHARA_TRACING_CONVENTION) to a built-in Conventions implementation. Empty/unknown → MLflow (the platform default); "none"/"otel"/"generic" → plain OTel spans with no backend-specific attributes.
type MLflowConventions ¶
type MLflowConventions struct{}
MLflowConventions maps the harness spans onto MLflow's tracing schema. It is the default Conventions (the platform backend).
func (MLflowConventions) LLM ¶
func (MLflowConventions) LLM(string) []attribute.KeyValue
LLM is intentionally empty: when the provider call goes through the platform LLM gateway, the gateway emits the authoritative mlflow.spanType="LLM" mirror span as a child of the harness's provider-call span (via the injected traceparent), so typing it here too would double-count LLM spans. For non-gateway providers it stays a structural (UNKNOWN) wrapper.
func (MLflowConventions) Subagent ¶
func (MLflowConventions) Subagent() []attribute.KeyValue
Subagent types a sub-agent span as an agent so nested runs render as agent sub-trees.
func (MLflowConventions) Tool ¶
func (MLflowConventions) Tool(inputs json.RawMessage) []attribute.KeyValue
Tool types the span TOOL (bare, so it feeds the "Tool Calls" dashboard) and records the raw JSON args as mlflow.spanInputs when present.
func (MLflowConventions) ToolResult ¶
func (MLflowConventions) ToolResult(outputs json.RawMessage, isError bool) []attribute.KeyValue
ToolResult records the error flag and the raw JSON result payload as mlflow.spanOutputs when present.
func (MLflowConventions) Turn ¶
func (MLflowConventions) Turn(protocol.MessageAddress) []attribute.KeyValue
Turn types the per-turn root as an agent span.
type NoConventions ¶
type NoConventions struct{}
NoConventions adds no backend-specific attributes — plain OTel spans carrying only the generic identity attributes. Useful when the trace sink applies its own attribute mapping (e.g. an OTel Collector processor) or for a backend consumed via raw OTel semantics.
func (NoConventions) Subagent ¶
func (NoConventions) Subagent() []attribute.KeyValue
func (NoConventions) Tool ¶
func (NoConventions) Tool(json.RawMessage) []attribute.KeyValue
func (NoConventions) ToolResult ¶
func (NoConventions) ToolResult(json.RawMessage, bool) []attribute.KeyValue
func (NoConventions) Turn ¶
func (NoConventions) Turn(protocol.MessageAddress) []attribute.KeyValue
Directories
¶
| Path | Synopsis |
|---|---|
|
Package otlpexport installs a global OpenTelemetry tracer + OTLP/HTTP exporter so the harness's pkg/telemetry spans (turn/tool/LLM) are exported to MLflow.
|
Package otlpexport installs a global OpenTelemetry tracer + OTLP/HTTP exporter so the harness's pkg/telemetry spans (turn/tool/LLM) are exported to MLflow. |