telemetry

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package telemetry configures OpenTelemetry for Tacklr hosts and process tools.

Host API:

  • Config, Init — OTLP traces, metrics, and logs
  • InstallDefault, InstallDefaultWithOTLP, NewLogger — slog setup
  • MeterProviderFromPrometheusRegisterer — Prometheus scrape
  • DefaultResource — service resource
  • StdioWatchDog — AgentWatchDog that writes to stderr
  • server.WithTracerProvider, WithMeterProvider — registry providers

Span starters, Instruments.Record*, attribute constants, and EmitEvent are for the harness and server packages. Hosts must not start tacklr spans or record harness metrics; that can break traces and double-count metrics.

Index

Constants

View Source
const (
	SpanTurn           = "tacklr.turn"
	SpanTool           = "tacklr.tool"
	SpanPlanInstall    = "tacklr.plan.install"
	SpanContextHandoff = "tacklr.context.handoff"
	SpanModel          = "tacklr.model"
	SpanBrain          = "tacklr.brain"
)

Span names (use these; backends index span name).

Trace shape:

tacklr.turn
  log: prompt.received | resume.received
  tacklr.model | tacklr.tool | tacklr.plan.install | tacklr.context.handoff
    tacklr.brain   (under tool when knowledge builtins run)
  log: turn.ended

Set static attributes at span start. Outcome and error enums at end only. Do not use high-cardinality values as metric labels; use log events for free text. Lifecycle milestones use OTel Logs SetEventName, not span.AddEvent.

View Source
const (
	AttrArea        = "tacklr.area"
	AttrSessionID   = "tacklr.session_id"
	AttrAgentID     = "tacklr.agent_id"
	AttrThreadID    = "tacklr.thread_id"
	AttrTurnKind    = "tacklr.turn.kind" // prompt | resume
	AttrLoadSession = "tacklr.load_session"
	AttrToolName    = "tacklr.tool.name"
	AttrToolNS      = "tacklr.tool.namespace"
	AttrToolStatus  = "tacklr.tool.status" // success | error | interrupt | …
	AttrOpenTodos   = "tacklr.open_todos"  // remaining todos at handoff
	AttrOutcome     = "tacklr.outcome"     // ok | error | cancelled | fallback

	// Model invoke (tacklr.model) — start attrs where possible.
	AttrModelPhase       = "tacklr.model.phase" // turn | handoff | compress
	AttrModelSeq         = "tacklr.model.seq"
	AttrContextMsgs      = "tacklr.context.messages"
	AttrContextToolPairs = "tacklr.context.tool_pairs"
	AttrHTTPStatus       = "tacklr.http.status"
	AttrErrorCode        = "tacklr.error.code"
	AttrErrorClass       = "tacklr.error.class" // bucketed enum
	AttrAfterTools       = "tacklr.model.after_tools"

	// Brain retrieval (tacklr.brain) — span attrs for trace debug only.
	// Metrics use LabelBrainOp / LabelDegrade / LabelEmpty (see RecordBrain).
	AttrBrainOp      = "tacklr.brain.op"      // see BrainOp* closed enum
	AttrBrainDegrade = "tacklr.brain.degrade" // none | lexical_only | containment_only
	AttrBrainHits    = "tacklr.brain.hits"    // page size; not a metric label (cardinality)

	// OpenTelemetry GenAI semantic conventions (stable keys).
	// https://opentelemetry.io/docs/specs/semconv/gen-ai/
	AttrGenAIOperationName = "gen_ai.operation.name"
	AttrGenAIProviderName  = "gen_ai.provider.name"
	AttrGenAIRequestModel  = "gen_ai.request.model"
	AttrGenAIInputTokens   = "gen_ai.usage.input_tokens"
	AttrGenAIOutputTokens  = "gen_ai.usage.output_tokens"
)

Span and log attribute keys (static identifiers only).

View Source
const (
	ModelPhaseTurn     = "turn"
	ModelPhaseHandoff  = "handoff"
	ModelPhaseCompress = "compress"
)

Model phase values for AttrModelPhase (closed enum).

View Source
const (
	GenAIOperationChat   = "chat"
	GenAIProviderAzure   = "azure.openai"
	GenAIProviderOpenAI  = "openai"
	GenAIProviderUnknown = "unknown"
)

GenAI operation / provider values (closed enums for low cardinality).

View Source
const (
	ErrorClassOK          = "ok"
	ErrorClassProvider4xx = "provider_4xx"
	ErrorClassProvider5xx = "provider_5xx"
	ErrorClassMaxTokens   = "max_tokens"
	ErrorClassCancelled   = "cancelled"
	ErrorClassTimeout     = "timeout"
	ErrorClassOther       = "other"
)

Error class buckets for metrics/span attrs (closed enum).

View Source
const (
	BrainOpSearch      = "search"
	BrainOpFindExact   = "find_exact"
	BrainOpFindObjects = "find_objects"
	BrainOpFindLinks   = "find_links"
	BrainOpContinue    = "continue"
	BrainOpExpand      = "expand"
	BrainOpExpandMany  = "expand_many"
)

Brain op values for AttrBrainOp / LabelBrainOp (closed enum). Keep in sync with brain.Op constants.

View Source
const (
	BrainDegradeNone            = "none"
	BrainDegradeLexicalOnly     = "lexical_only"
	BrainDegradeContainmentOnly = "containment_only"
)

Brain degrade modes (closed enum).

View Source
const (
	HandoffOutcomeOK       = "ok"
	HandoffOutcomeFallback = "fallback"
	HandoffOutcomeError    = "error"
)

Handoff outcome values.

View Source
const (
	EventPromptReceived  = "prompt.received"
	EventResumeReceived  = "resume.received"
	EventTurnEnded       = "turn.ended"
	EventProviderFailed  = "provider.failed"
	EventModelAfterTools = "model.after_tools"
)

Log event names (OTel Logs API Record.SetEventName).

View Source
const (
	EventAttrPromptLen            = "prompt_len"
	EventAttrResumeInterruptCount = "resume_interrupt_count"
	EventAttrOutcome              = "outcome"
	EventAttrBodySnip             = "body_snip"
	EventAttrInputItems           = "input_items"
)

Event attribute keys on log-based events.

View Source
const (
	AreaRegistry   = "registry"
	AreaHarness    = "harness"
	AreaModelTasks = "model_tasks"
	AreaContext    = "context"
	AreaInference  = "inference"
	AreaBrain      = "brain"
)

Area values for AttrArea.

View Source
const (
	OutcomeOK        = "ok"
	OutcomeError     = "error"
	OutcomeCancelled = "cancelled"
)

Outcome values for AttrOutcome / EventAttrOutcome.

View Source
const (
	MetricTurnDuration    = "tacklr.turn.duration"
	MetricTurnTotal       = "tacklr.turn.total"
	MetricTurnActive      = "tacklr.turn.active"
	MetricToolCalls       = "tacklr.tool.calls"
	MetricToolDuration    = "tacklr.tool.duration"
	MetricInterruptTotal  = "tacklr.interrupt.total"
	MetricHandoffTotal    = "tacklr.context.handoff.total"
	MetricCompressTotal   = "tacklr.context.compress.total"
	MetricSessionCreated  = "tacklr.session.created.total"
	MetricCheckpointSave  = "tacklr.checkpoint.save.total"
	MetricModelDuration   = "tacklr.model.duration"
	MetricModelTotal      = "tacklr.model.total"
	MetricTokensInput     = "tacklr.tokens.input"
	MetricTokensOutput    = "tacklr.tokens.output"
	MetricTokensReasoning = "tacklr.tokens.reasoning"
	MetricBrainTotal      = "tacklr.brain.total"
	MetricBrainDuration   = "tacklr.brain.duration"
)

Metric names (OTel). Prometheus export sanitizes '.' → '_'.

View Source
const (
	LabelAgentID    = "agent_id"
	LabelTurnKind   = "turn_kind"
	LabelOutcome    = "outcome"
	LabelTool       = "tool"
	LabelToolNS     = "tool_namespace"
	LabelStatus     = "status"
	LabelKind       = "kind" // interrupt kind
	LabelModelPhase = "model_phase"
	LabelErrorClass = "error_class"
	LabelBrainOp    = "brain_op"
	LabelDegrade    = "degrade"
	LabelEmpty      = "empty" // "true" | "false"
)

Label keys (low cardinality only — closed enums / config ids, never free text).

View Source
const InstrumentationName = "github.com/ryanaldo34/tacklr"

InstrumentationName is the OpenTelemetry instrumentation library name for Tacklr spans and meters. Hosts that build Tracer/Meter from their own providers should use this name (or call TracerFromProvider / MeterFromProvider).

Variables

This section is empty.

Functions

func AgentIDFromContext

func AgentIDFromContext(ctx context.Context) string

AgentIDFromContext returns agent_id or "".

func ContextWithAfterTools

func ContextWithAfterTools(ctx context.Context) context.Context

ContextWithAfterTools marks the next model span as after a tool batch (harness use).

func ContextWithAgentID

func ContextWithAgentID(ctx context.Context, agentID string) context.Context

ContextWithAgentID attaches agent_id for tool/handoff metrics.

func ContextWithInstruments

func ContextWithInstruments(ctx context.Context, inst *Instruments) context.Context

ContextWithInstruments attaches pre-built Instruments for the turn (and children).

func ContextWithMeter

func ContextWithMeter(ctx context.Context, m metric.Meter) context.Context

ContextWithMeter attaches m for MeterFromContext. Prefer ContextWithInstruments when instruments are pre-built for a registry.

func ContextWithModelIdentity

func ContextWithModelIdentity(ctx context.Context, id ModelIdentity) context.Context

ContextWithModelIdentity attaches static GenAI identity for model spans.

func ContextWithTracer

func ContextWithTracer(ctx context.Context, t trace.Tracer) context.Context

ContextWithTracer returns a child context that causes TracerFromContext to prefer t over the global provider. A nil t is ignored.

func DefaultResource

func DefaultResource(serviceName, serviceVersion string) (*resource.Resource, error)

DefaultResource builds a shared Resource for TracerProvider and MeterProvider so backends can correlate service.name across traces, metrics, and logs.

func EmitEvent

func EmitEvent(ctx context.Context, name string, attrs ...log.KeyValue)

EmitEvent emits an OTel log record with EventName set (span-correlated). Severity defaults to Info; use EmitEventSeverity for errors.

func EmitEventSeverity

func EmitEventSeverity(ctx context.Context, name string, severity log.Severity, attrs ...log.KeyValue)

EmitEventSeverity is EmitEvent with an explicit severity.

func Init

func Init(ctx context.Context, cfg Config) (shutdown func(context.Context) error, err error)

Init installs global TracerProvider, MeterProvider (unless DisableMetrics), LoggerProvider (unless DisableLogs), and a W3C text-map propagator. One OTLP endpoint serves traces, metrics, and logs so hosts can point a collector at a single address (Tempo + Mimir/Prometheus + Loki). Returns a shutdown that flushes exporters.

func InstallDefault

func InstallDefault(base slog.Handler)

InstallDefault wraps base with span correlation. Safe to call after Init.

func InstallDefaultWithOTLP

func InstallDefaultWithOTLP(base, otlp slog.Handler)

InstallDefaultWithOTLP dual-writes slog to base (e.g. stderr) and OTLP logs (Loki via the collector). base and otlp may be nil (otlp skipped when nil). Span correlation is applied once on the combined handler.

func Logger

func Logger() log.Logger

Logger returns the package Logger from the global LoggerProvider (noop-safe).

func Meter

func Meter() metric.Meter

Meter returns a Tacklr-scoped Meter from the global MeterProvider.

func MeterFromContext

func MeterFromContext(ctx context.Context) metric.Meter

MeterFromContext returns a context meter or the global Meter.

func MeterFromProvider

func MeterFromProvider(mp metric.MeterProvider) metric.Meter

MeterFromProvider returns a Tacklr-scoped Meter from mp (or global if mp is nil).

func MeterProviderFromPrometheusRegisterer

func MeterProviderFromPrometheusRegisterer(reg prometheus.Registerer, serviceName, serviceVersion string) (*sdkmetric.MeterProvider, error)

MeterProviderFromPrometheusRegisterer builds a MeterProvider that records into reg for classic Prometheus scrape (host serves GET /metrics via promhttp).

The host owns the HTTP server and scrape URL, for example:

reg := prometheus.NewRegistry()
mp, err := telemetry.MeterProviderFromPrometheusRegisterer(reg, "my-agent", "")
// server.NewRegistry(..., server.WithMeterProvider(mp))
// http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))

serviceName/serviceVersion set the same resource attributes as OTLP Init.

func NewBrainObserver

func NewBrainObserver() brain.Observer

NewBrainObserver returns an Observer for brain.WithObserver.

func NewLogger

func NewLogger(base slog.Handler) *slog.Logger

NewLogger builds a slog.Logger that correlates records to the active span.

func NewOTLPSlogHandler

func NewOTLPSlogHandler(name string) slog.Handler

NewOTLPSlogHandler returns a slog.Handler that exports records via the global LoggerProvider (OTLP → collector → Loki). Call after Init so the provider is set. name is the instrumentation scope (typically the service name).

func SetMeterProvider

func SetMeterProvider(mp metric.MeterProvider)

SetMeterProvider installs mp as the process-wide MeterProvider and rebuilds the cached global Instruments so later Init/SetMeterProvider calls take effect. Prefer server.WithMeterProvider for library hosts. Pass nil for noop.

func SetTracerProvider

func SetTracerProvider(tp trace.TracerProvider)

SetTracerProvider installs tp as the process-wide OpenTelemetry TracerProvider. Hosts that already own OTEL should prefer server.WithTracerProvider on the registry instead of replacing the global. Pass nil for a no-op provider.

func Tracer

func Tracer() trace.Tracer

Tracer returns the package tracer from the global TracerProvider (noop-safe when Init was not called with an endpoint).

func TracerFromContext

func TracerFromContext(ctx context.Context) trace.Tracer

TracerFromContext returns the tracer attached with ContextWithTracer, or the global package tracer when none is set.

func TracerFromProvider

func TracerFromProvider(tp trace.TracerProvider) trace.Tracer

TracerFromProvider returns a Tacklr-scoped Tracer from tp. If tp is nil, returns the global Tracer().

Types

type BrainObserver

type BrainObserver struct{}

BrainObserver maps brain.Observer to tacklr.brain OTel spans/metrics.

func (BrainObserver) StartOp

StartOp implements brain.Observer.

type BrainSpan

type BrainSpan struct {
	// contains filtered or unexported fields
}

BrainSpan is an in-flight tacklr.brain span.

func StartBrainSpan

func StartBrainSpan(ctx context.Context, op string) (context.Context, *BrainSpan)

StartBrainSpan starts a tacklr.brain child span.

func (*BrainSpan) End

func (b *BrainSpan) End(hits int, degrade string, err error)

End finishes the span and records brain metrics. hits is returned page size (0 on error) — span-only for debug, not a metric. degrade is BrainDegrade*; empty-result rate is derived for the total counter.

type Config

type Config struct {
	ServiceName    string
	ServiceVersion string
	// OTLPEndpoint is host:port or full URL. Empty uses OTEL_EXPORTER_OTLP_ENDPOINT
	// when set; if still empty, tracing and metrics are no-op.
	OTLPEndpoint string
	// Protocol is "grpc" (default) or "http".
	Protocol string
	// Insecure disables TLS for the exporters (local collectors / Alloy).
	Insecure bool
	// SampleRatio in (0,1]; values <=0 are treated as 1.0 (always sample traces).
	SampleRatio float64
	// DisableMetrics skips MeterProvider setup (traces only). Default false:
	// the same OTLP endpoint receives metrics.
	DisableMetrics bool
	// DisableLogs skips LoggerProvider setup. Default false: lifecycle events
	// (prompt.received, provider.failed, …) export as OTel log records correlated
	// to the active span (preferred over span.AddEvent).
	DisableLogs bool
}

Config configures OTLP traces and metrics for a simple host process. An empty OTLPEndpoint (and no OTEL env endpoint) installs no-op providers.

type HandoffSpan

type HandoffSpan struct {
	// contains filtered or unexported fields
}

HandoffSpan is an in-flight tacklr.context.handoff span. Call End once.

func StartHandoffSpan

func StartHandoffSpan(ctx context.Context, openTodos int) (context.Context, *HandoffSpan)

StartHandoffSpan starts a context-handoff span. openTodos is remaining work.

func (*HandoffSpan) End

func (s *HandoffSpan) End(outcome string, err error)

End ends the handoff span and records the handoff metric. outcome is HandoffOutcomeOK, HandoffOutcomeFallback, or HandoffOutcomeError.

type Instruments

type Instruments struct {
	// contains filtered or unexported fields
}

Instruments holds cached metric instruments for one Meter.

func InstrumentsFromContext

func InstrumentsFromContext(ctx context.Context) *Instruments

InstrumentsFromContext returns instruments from context, or a shared set bound to the global meter (lazy).

func MustInstruments

func MustInstruments(m metric.Meter) *Instruments

MustInstruments builds instruments from m. Panics only on programmer error from the SDK (invalid names); treated as init-time failure.

func NewInstruments

func NewInstruments(m metric.Meter) (*Instruments, error)

NewInstruments creates counters/histograms on m.

func (*Instruments) RecordBrain

func (i *Instruments) RecordBrain(ctx context.Context, agentID, op, outcome, degrade string, empty bool, d time.Duration)

RecordBrain records one knowledge-retrieval op.

Counter labels: agent_id, brain_op, outcome, degrade, empty ("true"|"false"). empty is only on the counter (empty-result rate); duration omits it to keep histogram series smaller. Hits live on the span only (per-request debug).

func (*Instruments) RecordCheckpointSave

func (i *Instruments) RecordCheckpointSave(ctx context.Context, outcome string)

func (*Instruments) RecordCompress

func (i *Instruments) RecordCompress(ctx context.Context, agentID string)

func (*Instruments) RecordHandoff

func (i *Instruments) RecordHandoff(ctx context.Context, agentID, outcome string)

RecordHandoff records a context handoff. outcome is a closed enum (HandoffOutcomeOK | HandoffOutcomeFallback | HandoffOutcomeError).

func (*Instruments) RecordInterrupt

func (i *Instruments) RecordInterrupt(ctx context.Context, agentID, kind string)

func (*Instruments) RecordModel

func (i *Instruments) RecordModel(ctx context.Context, agentID, phase, outcome, errClass string, d time.Duration)

RecordModel records one model invoke (duration + count). phase and errClass must be closed enums (ModelPhase* / ErrorClass*).

func (*Instruments) RecordSessionCreated

func (i *Instruments) RecordSessionCreated(ctx context.Context)

func (*Instruments) RecordTokens

func (i *Instruments) RecordTokens(ctx context.Context, agentID string, input, output, reasoning int)

RecordTokens adds provider-reported token counts (no high-cardinality labels).

func (*Instruments) RecordTool

func (i *Instruments) RecordTool(ctx context.Context, agentID, tool, namespace, status string, d time.Duration)

func (*Instruments) RecordTurnEnd

func (i *Instruments) RecordTurnEnd(ctx context.Context, agentID, turnKind, outcome string, d time.Duration)

func (*Instruments) RecordTurnStart

func (i *Instruments) RecordTurnStart(ctx context.Context, agentID string)

type ModelIdentity

type ModelIdentity struct {
	// Provider is a closed enum: azure.openai | openai | unknown.
	Provider string
	// Model is the deployment/model id (treat as low-cardinality config).
	Model string
	// Operation defaults to GenAIOperationChat when empty.
	Operation string
}

ModelIdentity is static request identity for GenAI span attrs (set at span start).

func NewModelIdentity

func NewModelIdentity(model, baseURL string) ModelIdentity

NewModelIdentity builds GenAI identity from deployment config (model id + API base URL).

type ModelSpan

type ModelSpan struct {
	// contains filtered or unexported fields
}

ModelSpan is an in-flight tacklr.model span. Call End once.

func StartModelSpan

func StartModelSpan(ctx context.Context, phase string, seq int, shape WindowShape) (context.Context, *ModelSpan)

StartModelSpan starts a model span. Emits model.after_tools when ContextWithAfterTools is set.

func (*ModelSpan) End

func (m *ModelSpan) End(err error, usage TokenUsage)

End ends the model span with outcome, usage, and metrics. HTTP status and code come from err when it implements providerStatus.

type MultiHandler

type MultiHandler []slog.Handler

MultiHandler fans out each record to every child handler (e.g. stderr + OTLP). Enabled is true if any child is enabled; Handle returns the first error.

func (MultiHandler) Enabled

func (m MultiHandler) Enabled(ctx context.Context, level slog.Level) bool

func (MultiHandler) Handle

func (m MultiHandler) Handle(ctx context.Context, r slog.Record) error

func (MultiHandler) WithAttrs

func (m MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (MultiHandler) WithGroup

func (m MultiHandler) WithGroup(name string) slog.Handler

type PlanInstallSpan

type PlanInstallSpan struct {
	// contains filtered or unexported fields
}

PlanInstallSpan is an in-flight tacklr.plan.install span. Call End once.

func StartPlanInstallSpan

func StartPlanInstallSpan(ctx context.Context, sessionID string) (context.Context, *PlanInstallSpan)

StartPlanInstallSpan starts a plan-document install span.

func (*PlanInstallSpan) End

func (s *PlanInstallSpan) End(err error)

End ends the span. err nil means ok; non-nil means error.

type SpanHandler

type SpanHandler struct {
	// contains filtered or unexported fields
}

SpanHandler wraps a slog.Handler and, for records that carry a context with an active span, attaches trace_id/span_id so logs correlate with traces.

It does not mirror log records as span events — that floods the turn lifecycle view with operational noise. Use a log backend that joins on trace_id instead.

func NewSpanHandler

func NewSpanHandler(base slog.Handler) *SpanHandler

NewSpanHandler wraps base. base must not be nil.

func (*SpanHandler) Enabled

func (h *SpanHandler) Enabled(ctx context.Context, level slog.Level) bool

func (*SpanHandler) Handle

func (h *SpanHandler) Handle(ctx context.Context, r slog.Record) error

func (*SpanHandler) WithAttrs

func (h *SpanHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (*SpanHandler) WithGroup

func (h *SpanHandler) WithGroup(name string) slog.Handler

type StdioWatchDog

type StdioWatchDog struct{}

StdioWatchDog implements tacklr.AgentWatchDog via streaming.Message (type alias).

func NewStdioWatchDog

func NewStdioWatchDog() *StdioWatchDog

NewStdioWatchDog returns a watchdog that logs agent activity to slog.

func (*StdioWatchDog) RecordError

func (s *StdioWatchDog) RecordError(err error) error

func (*StdioWatchDog) RecordOutput

func (s *StdioWatchDog) RecordOutput(msg *streaming.Message) error

func (*StdioWatchDog) RecordThinking

func (s *StdioWatchDog) RecordThinking(msg *streaming.Message) error

func (*StdioWatchDog) RecordTokens

func (s *StdioWatchDog) RecordTokens(input, output int) error

func (*StdioWatchDog) RecordToolCalls

func (s *StdioWatchDog) RecordToolCalls(msg *streaming.Message) error

func (*StdioWatchDog) RecordToolResult

func (s *StdioWatchDog) RecordToolResult(msg *streaming.Message) error

type TokenUsage

type TokenUsage struct {
	Input     int
	Output    int
	Reasoning int
}

TokenUsage is provider-reported token consumption for one model invoke.

type ToolSpan

type ToolSpan struct {
	// contains filtered or unexported fields
}

ToolSpan is an in-flight tacklr.tool span. Call Finish once.

func StartToolSpan

func StartToolSpan(ctx context.Context, name, namespace string) (context.Context, *ToolSpan)

StartToolSpan starts a child tool span.

func (*ToolSpan) Finish

func (t *ToolSpan) Finish(status string, err error)

Finish ends the tool span and records metrics. status is success, error, interrupt, or similar.

type TurnAttrs

type TurnAttrs struct {
	AgentID     string
	ThreadID    string
	SessionID   string
	Kind        string // prompt | resume
	LoadSession bool
}

TurnAttrs are static attributes set when a turn starts.

type TurnSpan

type TurnSpan struct {
	// contains filtered or unexported fields
}

TurnSpan is the root tacklr.turn span. Call End once.

func StartTurnSpan

func StartTurnSpan(ctx context.Context, a TurnAttrs) (context.Context, *TurnSpan)

StartTurnSpan starts the root turn span and records turn-active. Uses TracerFromContext (set ContextWithTracer first).

func (*TurnSpan) End

func (t *TurnSpan) End(outcome string, err error)

End ends the turn span, emits turn.ended, and records metrics. outcome is OutcomeOK, OutcomeError, or OutcomeCancelled; empty derives from err.

type WindowShape

type WindowShape struct {
	Messages  int
	ToolPairs int
}

WindowShape is a low-cardinality snapshot of the context window for model spans.

Jump to

Keyboard shortcuts

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