Documentation
¶
Overview ¶
Package telemetry installs the process-wide OpenTelemetry trace pipeline that the Framework kernel's spans (STT routing, TTS, Voice Agent, server lifecycle) feed into. The kernel itself only ever calls otel.Tracer(...), which is a zero-cost no-op until ConfigureTracing installs a real TracerProvider here — so this package is the single, vendor-neutral seam between "SpeechKit emits OpenTelemetry" and "the spans actually go somewhere". It exports over OTLP/HTTP, so any OTLP receiver works (a local collector, Grafana Tempo, or Sentry's OTLP ingestion); nothing in here is vendor-specific beyond the endpoint URL + auth header the caller supplies.
Index ¶
- Constants
- func ConfigureTracing(ctx context.Context, opts TracingOptions) (func(context.Context) error, error)
- func DictationOutcomeTerminal(f speechkit.TranscriptionFinalization) bool
- func KeepLostOutcomes(base sdktrace.Sampler) sdktrace.Sampler
- func ReportDictationOutcome(ctx context.Context, mode string, f speechkit.TranscriptionFinalization)
- func ReportOutcome(ctx context.Context, name string, severity OutcomeSeverity, ...)
- type OutcomeSeverity
- type TracingOptions
Constants ¶
const ( AttrDictationRecognition = "speechkit.dictation.recognition" AttrDictationOutput = "speechkit.dictation.output" AttrDictationPersistence = "speechkit.dictation.persistence" // AttrMode separates dictation from assist, which share one transcription // worker. Losing words matters in both, and a single alert rule should be // able to say which surface it happened on. AttrMode = "speechkit.mode" )
Attribute keys carrying the three finalization states verbatim, so a triage session can see which stage failed without re-deriving it from the severity.
const ( AttrOutcomeSeverity = "speechkit.outcome.severity" AttrOutcomeName = "speechkit.outcome.name" )
Attribute keys. Fixed names so a dashboard or alert rule can be written once and keep working; a typo in a call site would otherwise create a second, silently empty series.
const DictationOutcomeName = "speechkit.dictation.finalized"
DictationOutcomeName is the single event name for a finished dictation. One name plus a severity attribute beats three names, because an alert rule can then say "rate of lost over total" without enumerating outcomes.
Variables ¶
This section is empty.
Functions ¶
func ConfigureTracing ¶
func ConfigureTracing(ctx context.Context, opts TracingOptions) (func(context.Context) error, error)
ConfigureTracing installs a process-global OTel TracerProvider that batches the framework's spans to opts.Endpoint over OTLP/HTTP. It returns a shutdown func that flushes pending spans and stops the provider; call it on graceful shutdown. When opts.Endpoint is empty it is a no-op: no provider is set, so otel.Tracer spans stay zero-cost and the prior (no-op) behaviour is kept.
func DictationOutcomeTerminal ¶ added in v0.69.31
func DictationOutcomeTerminal(f speechkit.TranscriptionFinalization) bool
DictationOutcomeTerminal reports whether f can still change.
An observer is called several times for one dictation — recognition, then the output result, then an optional history update — and reporting each call would multiply one dictation into three outcomes and make any rate wrong. It is terminal when no later callback can arrive:
- recognition failed: there is no text, so neither output nor history runs;
- history settled (saved or failed): history is the last step;
- history was never requested and output has settled: nothing follows.
Recognition being empty is terminal for the same reason as a failure when nothing else was requested, and is handled by the last clause.
func KeepLostOutcomes ¶ added in v0.69.31
KeepLostOutcomes wraps a sampler so an outcome that says the user lost their words is never dropped, whatever the head sampling ratio is.
This exists because of a real conflict between two correct settings. Production samples at 0.2, which is right for ordinary traffic and wrong for the one event that should page: at that ratio four out of five losses would never leave the machine, and the alert built on them would under-report by design while looking healthy.
It reads the severity from the attributes passed at span creation, not from the span name, so adding an outcome does not mean remembering to register it here.
func ReportDictationOutcome ¶ added in v0.69.31
func ReportDictationOutcome(ctx context.Context, mode string, f speechkit.TranscriptionFinalization)
ReportDictationOutcome grades f and records it, once, when it is terminal. Non-terminal callbacks are ignored rather than being the caller's problem, so a host can hand every finalization to it without tracking stages itself.
The parameter list is closed on purpose. It takes no variadic attributes, because that is exactly the hole through which transcript text would eventually reach an exporter: everything recorded here is a closed enumeration the caller cannot widen.
func ReportOutcome ¶ added in v0.69.31
func ReportOutcome(ctx context.Context, name string, severity OutcomeSeverity, attrs ...attribute.KeyValue)
ReportOutcome records a named outcome against the trace in ctx.
It attaches to the active span when there is one, so an outcome raised while serving a request stays attached to that request. With no active span — the desktop finalizes a dictation on its own goroutine, not inside a request — it opens a short span of its own, because an event with no span reaches no backend at all.
OutcomeLost additionally sets the span status to Error, which is what makes it visible to a backend's error view and to an alert rule, rather than being one more successful span with an unusual attribute.
Attributes must stay free of transcript text, audio, window titles and clipboard contents; the privacy invariant in AGENTS.md is binding and this path is exported to a third party by definition. Pass counts, states and enumerations, never content.
Types ¶
type OutcomeSeverity ¶ added in v0.69.31
type OutcomeSeverity string
OutcomeSeverity says how much the user lost, which is the only question alerting actually asks. It is deliberately not a log level: "warn" and "error" describe how loud a line is, not whether someone's words survived.
const ( // OutcomeOK is the thing working. Recorded so a rate can be computed; // nothing should ever page on it. OutcomeOK OutcomeSeverity = "ok" // OutcomeDegraded is a caveat the user can act on and recover from — the // text exists somewhere, even if not where they wanted it. OutcomeDegraded OutcomeSeverity = "degraded" // OutcomeLost is what should page: the user spoke and the words reached // neither the target application nor the history. Nothing is recoverable. OutcomeLost OutcomeSeverity = "lost" )
func ClassifyDictationOutcome ¶ added in v0.69.31
func ClassifyDictationOutcome(f speechkit.TranscriptionFinalization) OutcomeSeverity
ClassifyDictationOutcome grades a terminal finalization.
The line between degraded and lost is whether the words still exist anywhere the user can reach. Text that was submitted to the target application, or saved to history, is recoverable — the overlay offers copy and retry against exactly that. Text that reached neither is gone, and that is the only case worth waking someone for.
A recognition failure counts as lost rather than degraded: the user spoke and there is nothing to recover, which is indistinguishable to them from losing text that existed. An empty recognition does not, because the most common cause is that nothing was said, and paging on silence would train the alert to be ignored.
type TracingOptions ¶
type TracingOptions struct {
// Endpoint is the full OTLP/HTTP traces URL (scheme + host + path), e.g.
// https://oORG.ingest.de.sentry.io/api/PROJECT/otlp/v1/traces. Empty
// disables tracing entirely (ConfigureTracing becomes a no-op).
Endpoint string
// Headers are attached to every export request — e.g. an auth header such
// as {"x-sentry-auth": "sentry sentry_key=..."}.
Headers map[string]string
// SampleRate is the head sampling ratio in (0,1). Values <=0 or >=1 mean
// always-sample, the right default for a low-traffic dogfood deployment.
SampleRate float64
// ServiceName + Environment + Release tag the exported resource so a
// backend can separate services and deployments.
ServiceName string
Environment string
Release string
}
TracingOptions configures the OTLP/HTTP trace exporter and the global TracerProvider it backs.