telemetry

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

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

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

func Finish(span trace.Span, err *error)

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

func FinishErr(span trace.Span, err error)

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

func LinkUpstream(ctx context.Context, addr protocol.MessageAddress) context.Context

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

func StartLLM(ctx context.Context, model string) (context.Context, trace.Span)

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

func StartSubagent(ctx context.Context, depth int) (context.Context, trace.Span)

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.

func StartTurn

StartTurn starts the per-turn span (the agent trace root) with generic addressing attributes; the active Conventions add the backend's span-type mapping (e.g. MLflow AGENT) so it anchors the agent-shaped trace.

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

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

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

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) LLM

func (NoConventions) Subagent

func (NoConventions) Subagent() []attribute.KeyValue

func (NoConventions) Tool

func (NoConventions) ToolResult

func (NoConventions) Turn

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL