fix: align telemetry client payload and dimensions with backend schema

Restructure the TelemetryClient to send the correct backend envelope
format ({app, schemaVersion, installId, events: [{name, occurredAt, dimensions}]})
instead of the old per-event format. Update all event dimension names
to match the backend registry (agent_role, adapter_type, error_code, etc.).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-03-31 12:30:15 -05:00
parent f16de6026d
commit 53dbcd185e
9 changed files with 49 additions and 48 deletions

View file

@ -1,8 +1,7 @@
import os from "node:os";
import { createHash } from "node:crypto";
import type {
TelemetryConfig,
TelemetryEventEnvelope,
TelemetryEvent,
TelemetryEventName,
TelemetryState,
} from "./types.js";
@ -12,11 +11,10 @@ const BATCH_SIZE = 50;
const SEND_TIMEOUT_MS = 5_000;
export class TelemetryClient {
private queue: TelemetryEventEnvelope[] = [];
private queue: TelemetryEvent[] = [];
private readonly config: TelemetryConfig;
private readonly stateFactory: () => TelemetryState;
private readonly version: string;
private readonly sessionId: string;
private state: TelemetryState | null = null;
private flushInterval: ReturnType<typeof setInterval> | null = null;
@ -24,22 +22,16 @@ export class TelemetryClient {
this.config = config;
this.stateFactory = stateFactory;
this.version = version;
this.sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}
track(eventName: TelemetryEventName, dimensions?: Record<string, string | number | boolean>): void {
if (!this.config.enabled) return;
const state = this.getState();
this.getState(); // ensure state is initialised (side-effect: creates state file on first call)
this.queue.push({
installId: state.installId,
sessionId: this.sessionId,
event: eventName,
name: eventName,
occurredAt: new Date().toISOString(),
dimensions: dimensions ?? {},
timestamp: new Date().toISOString(),
version: this.version,
os: os.platform(),
arch: os.arch(),
});
if (this.queue.length >= BATCH_SIZE) {
@ -51,7 +43,10 @@ export class TelemetryClient {
if (!this.config.enabled || this.queue.length === 0) return;
const events = this.queue.splice(0);
const state = this.getState();
const endpoint = this.config.endpoint ?? DEFAULT_ENDPOINT;
const app = this.config.app ?? "paperclip";
const schemaVersion = this.config.schemaVersion ?? "1";
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);
@ -59,7 +54,12 @@ export class TelemetryClient {
await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ events }),
body: JSON.stringify({
app,
schemaVersion,
installId: state.installId,
events,
}),
signal: controller.signal,
});
} catch {