/** * @octomil/browser — Telemetry reporter (v2 OTLP envelope) * * Opt-in, batched, non-blocking telemetry. Events are queued in memory * and flushed periodically using `navigator.sendBeacon` (preferred) or * `fetch` with `keepalive: true`. * * V2 sends to `POST /api/v2/telemetry/events` with an OTLP-style resource * envelope wrapping each batch. */ import type { TelemetryEvent } from "./types.js"; import type { BrowserRouteEvent } from "./route-event.js"; export declare const DEFAULT_SDK_VERSION = "1.0.0"; /** OTLP-style resource descriptor included in every telemetry batch. */ export interface TelemetryResource { sdk: string; sdk_version: string; device_id: string; platform: string; org_id: string; } /** @deprecated Use ExportLogsServiceRequest instead. */ export interface TelemetryEnvelope { resource: TelemetryResource; events: TelemetryEvent[]; } export interface OtlpKeyValue { key: string; value: { stringValue?: string; intValue?: string; doubleValue?: number; boolValue?: boolean; }; } export interface OtlpResource { attributes: OtlpKeyValue[]; } export interface OtlpInstrumentationScope { name: string; version?: string; } export interface OtlpLogRecord { timeUnixNano: string; severityNumber?: number; severityText?: string; body?: { stringValue: string; }; attributes?: OtlpKeyValue[]; traceId?: string; spanId?: string; } export interface OtlpScopeLogs { scope: OtlpInstrumentationScope; logRecords: OtlpLogRecord[]; } export interface OtlpResourceLogs { resource: OtlpResource; scopeLogs: OtlpScopeLogs[]; } export interface ExportLogsServiceRequest { resourceLogs: OtlpResourceLogs[]; } export interface TelemetryReporterOptions { /** Endpoint to POST batched events to. */ url?: string; /** Flush interval in milliseconds. */ flushIntervalMs?: number; /** Maximum events per batch. */ maxBatchSize?: number; /** API key included in the `Authorization` header. */ apiKey?: string; /** Optional auth header provider for device-token-authenticated browser clients. */ authHeadersProvider?: () => Record | null; /** Organisation identifier included in the resource envelope. */ orgId?: string; /** Stable device identifier included in the resource envelope. */ deviceId?: string; /** SDK version string. Defaults to the package version. */ sdkVersion?: string; } export declare class TelemetryReporter { private readonly url; private readonly flushIntervalMs; private readonly maxBatchSize; private readonly apiKey; private readonly authHeadersProvider; private readonly resource; private queue; private timerId; private disposed; constructor(options?: TelemetryReporterOptions); /** * Merge additional fields into the telemetry resource. * Typically called with DeviceContext.telemetryResource() after * silent registration completes. */ updateResource(fields: Record): void; /** Enqueue a telemetry event. Non-blocking, never throws. */ track(event: TelemetryEvent): void; /** Flush all queued events immediately. */ flush(): Promise; batch(events: TelemetryEvent[]): Promise; /** Stop the flush timer and send remaining events. */ close(): void; reportInferenceStarted(modelId: string, attrs?: Record): void; reportInferenceCompleted(modelId: string, durationMs: number, attrs?: Record): void; reportInferenceFailed(modelId: string, errorType: string, errorMessage: string): void; reportInferenceChunk(modelId: string, attrs?: Record): void; /** * Report that a single chunk was produced during streaming inference. * * Emits `inference.chunk_produced` with the model ID and chunk index. */ reportChunkProduced(modelId: string, chunkIndex: number, attrs?: Record): void; reportTrainingStarted(modelId: string, version: string): void; reportTrainingCompleted(modelId: string, version: string, durationMs: number): void; reportTrainingFailed(modelId: string, version: string, errorType: string): void; reportWeightUpload(modelId: string, roundId: string, sampleCount: number): void; reportDeployStarted(modelId: string, version: string): void; reportDeployCompleted(modelId: string, version: string, durationMs: number): void; reportDeployRollback(modelId: string, fromVersion: string, toVersion: string, reason: string): void; reportExperimentAssigned(modelId: string, experimentId: string, variant: string): void; reportExperimentMetric(experimentId: string, metricName: string, metricValue: number): void; /** * Report a canonical route event. The event is privacy-sanitized before * being enqueued: any forbidden keys (prompt, output, audio, etc.) are * stripped at any nesting depth. * * This is the ONLY telemetry event uploaded for routing decisions. */ reportRouteEvent(routeEvent: BrowserRouteEvent): void; private makeEvent; private startAutoFlush; private buildEnvelope; private resourceToOtlpAttributes; private eventToLogRecord; private toOtlpValue; private send; private sendBeaconPayload; } export declare function initTelemetry(options?: TelemetryReporterOptions): TelemetryReporter; export declare function getTelemetry(): TelemetryReporter | null; export declare function closeTelemetry(): void; //# sourceMappingURL=telemetry.d.ts.map