Merge pull request #1524 from RooVetGit/checkpoint_telemetry

Add telemetry for checkpoint save/restore/diff
This commit is contained in:
Matt Rubens 2025-03-10 07:45:53 -04:00 committed by GitHub
commit 01b822e73f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 0 deletions

View file

@ -3798,6 +3798,8 @@ export class Cline {
return
}
telemetryService.captureCheckpointDiffed(this.taskId)
if (!previousCommitHash && mode === "checkpoint") {
const previousCheckpoint = this.clineMessages
.filter(({ say }) => say === "checkpoint_saved")
@ -3849,6 +3851,8 @@ export class Cline {
return
}
telemetryService.captureCheckpointCreated(this.taskId)
// Start the checkpoint process in the background.
service.saveCheckpoint(`Task: ${this.taskId}, Time: ${Date.now()}`).catch((err) => {
console.error("[Cline#checkpointSave] caught unexpected error, disabling checkpoints", err)
@ -3880,6 +3884,8 @@ export class Cline {
try {
await service.restoreCheckpoint(commitHash)
telemetryService.captureCheckpointRestored(this.taskId)
await this.providerRef.deref()?.postMessageToWebview({ type: "currentCheckpointUpdated", text: commitHash })
if (mode === "restore") {

View file

@ -2567,6 +2567,15 @@ export class ClineProvider implements vscode.WebviewViewProvider {
properties.apiProvider = apiConfiguration.apiProvider
}
// Add model ID if available
const currentCline = this.getCurrentCline()
if (currentCline?.api) {
const { id: modelId } = currentCline.api.getModel()
if (modelId) {
properties.modelId = modelId
}
}
return properties
}
}

View file

@ -1652,3 +1652,62 @@ describe("ContextProxy integration", () => {
expect(mockContextProxy.setValues).toBeDefined()
})
})
describe("getTelemetryProperties", () => {
let provider: ClineProvider
let mockContext: vscode.ExtensionContext
let mockOutputChannel: vscode.OutputChannel
let mockCline: any
beforeEach(() => {
// Reset mocks
jest.clearAllMocks()
// Setup basic mocks
mockContext = {
globalState: {
get: jest.fn().mockImplementation((key: string) => {
if (key === "mode") return "code"
if (key === "apiProvider") return "anthropic"
return undefined
}),
update: jest.fn(),
keys: jest.fn().mockReturnValue([]),
},
secrets: { get: jest.fn(), store: jest.fn(), delete: jest.fn() },
extensionUri: {} as vscode.Uri,
globalStorageUri: { fsPath: "/test/path" },
extension: { packageJSON: { version: "1.0.0" } },
} as unknown as vscode.ExtensionContext
mockOutputChannel = { appendLine: jest.fn() } as unknown as vscode.OutputChannel
provider = new ClineProvider(mockContext, mockOutputChannel)
// Setup Cline instance with mocked getModel method
const { Cline } = require("../../Cline")
mockCline = new Cline()
mockCline.api = {
getModel: jest.fn().mockReturnValue({
id: "claude-3-7-sonnet-20250219",
info: { contextWindow: 200000 },
}),
}
})
test("includes basic properties in telemetry", async () => {
const properties = await provider.getTelemetryProperties()
expect(properties).toHaveProperty("vscodeVersion")
expect(properties).toHaveProperty("platform")
expect(properties).toHaveProperty("appVersion", "1.0.0")
})
test("includes model ID from current Cline instance if available", async () => {
// Add mock Cline to stack
await provider.addClineToStack(mockCline)
const properties = await provider.getTelemetryProperties()
expect(properties).toHaveProperty("modelId", "claude-3-7-sonnet-20250219")
})
})

View file

@ -22,6 +22,9 @@ class PostHogClient {
CONVERSATION_MESSAGE: "Conversation Message",
MODE_SWITCH: "Mode Switched",
TOOL_USED: "Tool Used",
CHECKPOINT_CREATED: "Checkpoint Created",
CHECKPOINT_RESTORED: "Checkpoint Restored",
CHECKPOINT_DIFFED: "Checkpoint Diffed",
},
}
@ -246,6 +249,18 @@ class TelemetryService {
})
}
public captureCheckpointCreated(taskId: string): void {
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_CREATED, { taskId })
}
public captureCheckpointDiffed(taskId: string): void {
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_DIFFED, { taskId })
}
public captureCheckpointRestored(taskId: string): void {
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_RESTORED, { taskId })
}
/**
* Checks if telemetry is currently enabled
* @returns Whether telemetry is enabled