Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/calm-hogs-sample.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Reduce repetitive autocomplete error telemetry while retaining a diagnostic sample.
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import { TelemetryEventName } from "./types"

const FAILURE_SAMPLE_RATE = 0.1

/**
* Build the merged properties object for a telemetry event.
* Provider properties are included first so event-specific properties can override them.
* Retain 10% of autocomplete failures, tagging the rate for weighted reporting.
* Return null for dropped events so no request reaches the CLI or PostHog.
*/
export function buildTelemetryPayload(
event: string,
properties: Record<string, unknown> | undefined,
providerProperties: Record<string, unknown> | undefined,
): { event: string; properties: Record<string, unknown> } {
): { event: string; properties: Record<string, unknown> } | null {
const sampled = event === TelemetryEventName.AUTOCOMPLETE_LLM_REQUEST_FAILED
if (sampled && Math.random() >= FAILURE_SAMPLE_RATE) return null
Comment thread
pedroheyerdahl marked this conversation as resolved.
Resolved

return {
event,
properties: { ...providerProperties, ...properties },
properties: {
...providerProperties,
...properties,
...(sampled && { autocomplete_failure_sample_rate: FAILURE_SAMPLE_RATE }),
},
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class TelemetryProxy {
if (!this.url || !this.password) return

const built = buildTelemetryPayload(event, properties, this.provider?.getTelemetryProperties())
if (!built) return
const payload = JSON.stringify(built)
const auth = buildTelemetryAuthHeader(this.password)

Expand Down
14 changes: 7 additions & 7 deletions packages/kilo-vscode/tests/unit/telemetry-proxy-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@ import { buildTelemetryPayload, buildTelemetryAuthHeader } from "../../src/servi
describe("buildTelemetryPayload", () => {
it("includes event name in payload", () => {
const result = buildTelemetryPayload("test.event", {}, undefined)
expect(result.event).toBe("test.event")
expect(result?.event).toBe("test.event")
})

it("merges provider properties with event properties", () => {
const result = buildTelemetryPayload("test.event", { eventProp: "value" }, { providerProp: "providerValue" })
expect(result.properties.eventProp).toBe("value")
expect(result.properties.providerProp).toBe("providerValue")
expect(result?.properties.eventProp).toBe("value")
expect(result?.properties.providerProp).toBe("providerValue")
})

it("event properties override provider properties", () => {
const result = buildTelemetryPayload("test.event", { shared: "from-event" }, { shared: "from-provider" })
expect(result.properties.shared).toBe("from-event")
expect(result?.properties.shared).toBe("from-event")
})

it("handles undefined event properties", () => {
const result = buildTelemetryPayload("test.event", undefined, { providerProp: "x" })
expect(result.properties.providerProp).toBe("x")
expect(result?.properties.providerProp).toBe("x")
})

it("handles undefined provider properties", () => {
const result = buildTelemetryPayload("test.event", { key: "val" }, undefined)
expect(result.properties.key).toBe("val")
expect(result?.properties.key).toBe("val")
})

it("handles both undefined", () => {
const result = buildTelemetryPayload("test.event", undefined, undefined)
expect(result.properties).toEqual({})
expect(result?.properties).toEqual({})
})
})

Expand Down
Loading