|
1 | 1 | import { useCallback } from "react"; |
2 | | -import { trackEvent, roundToBase2 } from "@/common/telemetry"; |
3 | | -import type { ErrorContext } from "@/common/telemetry/payload"; |
| 2 | +import { |
| 3 | + trackWorkspaceCreated, |
| 4 | + trackWorkspaceSwitched, |
| 5 | + trackMessageSent, |
| 6 | + trackStreamCompleted, |
| 7 | + trackProviderConfigured, |
| 8 | + trackCommandUsed, |
| 9 | + trackVoiceTranscription, |
| 10 | + trackErrorOccurred, |
| 11 | +} from "@/common/telemetry"; |
| 12 | +import type { |
| 13 | + ErrorContext, |
| 14 | + TelemetryRuntimeType, |
| 15 | + TelemetryThinkingLevel, |
| 16 | + TelemetryCommandType, |
| 17 | +} from "@/common/telemetry/payload"; |
4 | 18 |
|
5 | 19 | /** |
6 | 20 | * Hook for clean telemetry integration in React components |
7 | 21 | * |
8 | | - * Provides type-safe telemetry tracking. Base properties (version, platform, etc.) |
9 | | - * are automatically added by the backend TelemetryService. |
| 22 | + * Provides stable callback references for telemetry tracking. |
| 23 | + * All numeric values are automatically rounded for privacy. |
10 | 24 | * |
11 | 25 | * Usage: |
12 | 26 | * |
13 | 27 | * ```tsx |
14 | 28 | * const telemetry = useTelemetry(); |
15 | 29 | * |
16 | | - * // Track workspace switch |
17 | 30 | * telemetry.workspaceSwitched(fromId, toId); |
18 | | - * |
19 | | - * // Track workspace creation |
20 | | - * telemetry.workspaceCreated(workspaceId); |
21 | | - * |
22 | | - * // Track message sent |
23 | | - * telemetry.messageSent(model, mode, messageLength); |
24 | | - * |
25 | | - * // Track error |
| 31 | + * telemetry.workspaceCreated(workspaceId, runtimeType); |
| 32 | + * telemetry.messageSent(model, mode, messageLength, runtimeType, thinkingLevel); |
| 33 | + * telemetry.streamCompleted(model, wasInterrupted, durationSecs, outputTokens); |
| 34 | + * telemetry.providerConfigured(provider, keyType); |
| 35 | + * telemetry.commandUsed(commandType); |
| 36 | + * telemetry.voiceTranscription(audioDurationSecs, success); |
26 | 37 | * telemetry.errorOccurred(errorType, context); |
27 | 38 | * ``` |
28 | 39 | */ |
29 | 40 | export function useTelemetry() { |
30 | 41 | const workspaceSwitched = useCallback((fromWorkspaceId: string, toWorkspaceId: string) => { |
31 | | - console.debug("[useTelemetry] workspaceSwitched called", { fromWorkspaceId, toWorkspaceId }); |
32 | | - trackEvent({ |
33 | | - event: "workspace_switched", |
34 | | - properties: { |
35 | | - fromWorkspaceId, |
36 | | - toWorkspaceId, |
37 | | - }, |
38 | | - }); |
| 42 | + trackWorkspaceSwitched(fromWorkspaceId, toWorkspaceId); |
| 43 | + }, []); |
| 44 | + |
| 45 | + const workspaceCreated = useCallback((workspaceId: string, runtimeType: TelemetryRuntimeType) => { |
| 46 | + trackWorkspaceCreated(workspaceId, runtimeType); |
| 47 | + }, []); |
| 48 | + |
| 49 | + const messageSent = useCallback( |
| 50 | + ( |
| 51 | + model: string, |
| 52 | + mode: string, |
| 53 | + messageLength: number, |
| 54 | + runtimeType: TelemetryRuntimeType, |
| 55 | + thinkingLevel: TelemetryThinkingLevel |
| 56 | + ) => { |
| 57 | + trackMessageSent(model, mode, messageLength, runtimeType, thinkingLevel); |
| 58 | + }, |
| 59 | + [] |
| 60 | + ); |
| 61 | + |
| 62 | + const streamCompleted = useCallback( |
| 63 | + (model: string, wasInterrupted: boolean, durationSecs: number, outputTokens: number) => { |
| 64 | + trackStreamCompleted(model, wasInterrupted, durationSecs, outputTokens); |
| 65 | + }, |
| 66 | + [] |
| 67 | + ); |
| 68 | + |
| 69 | + const providerConfigured = useCallback((provider: string, keyType: string) => { |
| 70 | + trackProviderConfigured(provider, keyType); |
39 | 71 | }, []); |
40 | 72 |
|
41 | | - const workspaceCreated = useCallback((workspaceId: string) => { |
42 | | - console.debug("[useTelemetry] workspaceCreated called", { workspaceId }); |
43 | | - trackEvent({ |
44 | | - event: "workspace_created", |
45 | | - properties: { |
46 | | - workspaceId, |
47 | | - }, |
48 | | - }); |
| 73 | + const commandUsed = useCallback((command: TelemetryCommandType) => { |
| 74 | + trackCommandUsed(command); |
49 | 75 | }, []); |
50 | 76 |
|
51 | | - const messageSent = useCallback((model: string, mode: string, messageLength: number) => { |
52 | | - console.debug("[useTelemetry] messageSent called", { model, mode, messageLength }); |
53 | | - trackEvent({ |
54 | | - event: "message_sent", |
55 | | - properties: { |
56 | | - model, |
57 | | - mode, |
58 | | - message_length_b2: roundToBase2(messageLength), |
59 | | - }, |
60 | | - }); |
| 77 | + const voiceTranscription = useCallback((audioDurationSecs: number, success: boolean) => { |
| 78 | + trackVoiceTranscription(audioDurationSecs, success); |
61 | 79 | }, []); |
62 | 80 |
|
63 | 81 | const errorOccurred = useCallback((errorType: string, context: ErrorContext) => { |
64 | | - console.debug("[useTelemetry] errorOccurred called", { errorType, context }); |
65 | | - trackEvent({ |
66 | | - event: "error_occurred", |
67 | | - properties: { |
68 | | - errorType, |
69 | | - context, |
70 | | - }, |
71 | | - }); |
| 82 | + trackErrorOccurred(errorType, context); |
72 | 83 | }, []); |
73 | 84 |
|
74 | 85 | return { |
75 | 86 | workspaceSwitched, |
76 | 87 | workspaceCreated, |
77 | 88 | messageSent, |
| 89 | + streamCompleted, |
| 90 | + providerConfigured, |
| 91 | + commandUsed, |
| 92 | + voiceTranscription, |
78 | 93 | errorOccurred, |
79 | 94 | }; |
80 | 95 | } |
0 commit comments