diff --git a/packages/kilo-vscode/docs/non-agent-features/telemetry.md b/packages/kilo-vscode/docs/non-agent-features/telemetry.md index f45fe7abb4..5ad8176fe2 100644 --- a/packages/kilo-vscode/docs/non-agent-features/telemetry.md +++ b/packages/kilo-vscode/docs/non-agent-features/telemetry.md @@ -111,11 +111,11 @@ All events are defined in `TelemetryEventName` enum (`packages/types/src/telemet ### 3.1 Task Lifecycle -| Event | Properties | Capture Method | -| ---------------------- | ----------------------------------- | ----------------------------------------------------------- | -| `Task Created` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_CREATED)` | -| `Task Reopened` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_RESTARTED)` | -| `Task Completed` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_COMPLETED)` | +| Event | Properties | Capture Method | +| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------- | +| `Task Created` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_CREATED)` | +| `Task Reopened` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_RESTARTED)` | +| `Task Completed` | `taskId` | `TelemetryProxy.capture(TelemetryEventName.TASK_COMPLETED)` | | `Conversation Message` | `taskId`, `source` (user/assistant) | `TelemetryProxy.capture(TelemetryEventName.TASK_CONVERSATION_MESSAGE)` | ### 3.2 LLM & AI diff --git a/packages/kilo-vscode/src/services/telemetry/telemetry-proxy.ts b/packages/kilo-vscode/src/services/telemetry/telemetry-proxy.ts index 9d15d19292..2ebe2e3789 100644 --- a/packages/kilo-vscode/src/services/telemetry/telemetry-proxy.ts +++ b/packages/kilo-vscode/src/services/telemetry/telemetry-proxy.ts @@ -1,7 +1,6 @@ import * as vscode from "vscode" import { TelemetryEventName, type TelemetryPropertiesProvider } from "./types" - /** * Singleton proxy that captures telemetry events and forwards them to the CLI * server via POST /telemetry/capture. The CLI handles PostHog delivery. diff --git a/packages/kilo-vscode/src/services/telemetry/types.ts b/packages/kilo-vscode/src/services/telemetry/types.ts index f82951eb58..5c7e106fd5 100644 --- a/packages/kilo-vscode/src/services/telemetry/types.ts +++ b/packages/kilo-vscode/src/services/telemetry/types.ts @@ -88,5 +88,3 @@ export enum TelemetryEventName { export interface TelemetryPropertiesProvider { getTelemetryProperties(): Record } - - diff --git a/packages/opencode/src/server/routes/telemetry.ts b/packages/opencode/src/server/routes/telemetry.ts index b0509598be..bd10432765 100644 --- a/packages/opencode/src/server/routes/telemetry.ts +++ b/packages/opencode/src/server/routes/telemetry.ts @@ -29,10 +29,7 @@ export const TelemetryRoutes = lazy(() => "json", z.object({ event: z.string().meta({ description: "Event name" }), - properties: z - .record(z.string(), z.any()) - .optional() - .meta({ description: "Event properties" }), + properties: z.record(z.string(), z.any()).optional().meta({ description: "Event properties" }), }), ), async (c) => { diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index e8d276034b..922c3045b0 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -149,6 +149,8 @@ import type { SessionUpdateErrors, SessionUpdateResponses, SubtaskPartInput, + TelemetryCaptureErrors, + TelemetryCaptureResponses, TextPartInput, ToolIdsErrors, ToolIdsResponses, @@ -2174,6 +2176,47 @@ export class Provider extends HeyApiClient { } } +export class Telemetry extends HeyApiClient { + /** + * Capture telemetry event + * + * Forward a telemetry event to PostHog via kilo-telemetry. + */ + public capture( + parameters?: { + directory?: string + event?: string + properties?: { + [key: string]: unknown + } + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "query", key: "directory" }, + { in: "body", key: "event" }, + { in: "body", key: "properties" }, + ], + }, + ], + ) + return (options?.client ?? this.client).post({ + url: "/telemetry/capture", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } +} + export class Organization extends HeyApiClient { /** * Update Kilo Gateway organization @@ -3391,6 +3434,11 @@ export class OpencodeClient extends HeyApiClient { return (this._provider ??= new Provider({ client: this.client })) } + private _telemetry?: Telemetry + get telemetry(): Telemetry { + return (this._telemetry ??= new Telemetry({ client: this.client })) + } + private _kilo?: Kilo get kilo(): Kilo { return (this._kilo ??= new Kilo({ client: this.client })) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index cbed55f524..31257c0948 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -4214,6 +4214,44 @@ export type ProviderOauthCallbackResponses = { export type ProviderOauthCallbackResponse = ProviderOauthCallbackResponses[keyof ProviderOauthCallbackResponses] +export type TelemetryCaptureData = { + body?: { + /** + * Event name + */ + event: string + /** + * Event properties + */ + properties?: { + [key: string]: unknown + } + } + path?: never + query?: { + directory?: string + } + url: "/telemetry/capture" +} + +export type TelemetryCaptureErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TelemetryCaptureError = TelemetryCaptureErrors[keyof TelemetryCaptureErrors] + +export type TelemetryCaptureResponses = { + /** + * Event captured + */ + 200: boolean +} + +export type TelemetryCaptureResponse = TelemetryCaptureResponses[keyof TelemetryCaptureResponses] + export type KiloProfileData = { body?: never path?: never diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index cb37503e0c..186d82d0be 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -4048,6 +4048,74 @@ ] } }, + "/telemetry/capture": { + "post": { + "operationId": "telemetry.capture", + "parameters": [ + { + "in": "query", + "name": "directory", + "schema": { + "type": "string" + } + } + ], + "summary": "Capture telemetry event", + "description": "Forward a telemetry event to PostHog via kilo-telemetry.", + "responses": { + "200": { + "description": "Event captured", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestError" + } + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "event": { + "description": "Event name", + "type": "string" + }, + "properties": { + "description": "Event properties", + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + } + }, + "required": ["event"] + } + } + } + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createOpencodeClient } from \"@kilocode/sdk\n\nconst client = createOpencodeClient()\nawait client.telemetry.capture({\n ...\n})" + } + ] + } + }, "/kilo/profile": { "get": { "operationId": "kilo.profile",