Skip to content

Commit bc227ec

Browse files
authored
Merge pull request #1331 from Kiln-AI/leonard/kil-601-posthog-analytics-for-chat
chore: add analytics to chat
2 parents 4378d8e + e338688 commit bc227ec

4 files changed

Lines changed: 45 additions & 3 deletions

File tree

app/web_ui/src/lib/chat/chat_session_store.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { writable, get, type Readable } from "svelte/store"
2+
import posthog from "posthog-js"
23
import {
34
streamChat,
45
chatGenerateId,
@@ -134,7 +135,7 @@ export function createChatSessionStore(
134135
}))
135136
}
136137

137-
function beginStreaming(text: string) {
138+
function beginStreaming(text: string, isRetry = false) {
138139
removeErrors()
139140
const currentMessages = get(persisted).messages
140141
const traceId =
@@ -165,6 +166,16 @@ export function createChatSessionStore(
165166
lastSentAppState: currentAppState,
166167
}))
167168

169+
posthog.capture("chat_message_sent", {
170+
is_new_conversation: !traceId && !isRetry,
171+
message_length: text.length,
172+
has_app_context_header: !!header,
173+
message_count: currentMessages.length,
174+
})
175+
if (!traceId && !isRetry) {
176+
posthog.capture("chat_conversation_started")
177+
}
178+
168179
combined.update((s) => ({
169180
...s,
170181
toolExecuting: false,
@@ -284,6 +295,7 @@ export function createChatSessionStore(
284295

285296
function stop(): void {
286297
if (abortController) {
298+
posthog.capture("chat_stopped")
287299
abortController.abort()
288300
}
289301
}
@@ -299,12 +311,13 @@ export function createChatSessionStore(
299311
}
300312
}
301313
if (lastUserIdx === -1) return
314+
posthog.capture("chat_retry")
302315
const userText = msgs[lastUserIdx].content ?? ""
303316
persisted.update((p) => ({
304317
...p,
305318
messages: p.messages.slice(0, lastUserIdx),
306319
}))
307-
beginStreaming(userText)
320+
beginStreaming(userText, true)
308321
}
309322

310323
function reset(): void {
@@ -390,8 +403,17 @@ export function createChatSessionStore(
390403
resolver(decisions)
391404
}
392405

406+
function toolNameForCallId(toolCallId: string): string | undefined {
407+
return get(combined).toolApprovalWaiter?.payload.items.find(
408+
(i) => i.toolCallId === toolCallId,
409+
)?.toolName
410+
}
411+
393412
function applyToolApprovalRun(toolCallId: string): void {
394413
if (!get(combined).toolApprovalWaiter) return
414+
posthog.capture("chat_tool_approval_run", {
415+
tool_name: toolNameForCallId(toolCallId),
416+
})
395417
combined.update((s) => ({
396418
...s,
397419
toolApprovalPicks: { ...s.toolApprovalPicks, [toolCallId]: true },
@@ -401,6 +423,9 @@ export function createChatSessionStore(
401423

402424
function applyToolApprovalSkip(toolCallId: string): void {
403425
if (!get(combined).toolApprovalWaiter) return
426+
posthog.capture("chat_tool_approval_skip", {
427+
tool_name: toolNameForCallId(toolCallId),
428+
})
404429
combined.update((s) => ({
405430
...s,
406431
toolApprovalPicks: { ...s.toolApprovalPicks, [toolCallId]: false },

app/web_ui/src/routes/(app)/chat/chat.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
22
import { onMount, onDestroy, tick } from "svelte"
3+
import { get } from "svelte/store"
34
import { fly } from "svelte/transition"
5+
import posthog from "posthog-js"
46
import ChatCostDisclaimer from "./chat_cost_disclaimer.svelte"
57
import type { ChatMessage, ChatMessagePart } from "$lib/chat/streaming_chat"
68
import { CHAT_CLIENT_VERSION_TOO_OLD } from "$lib/error_codes"
@@ -430,6 +432,9 @@
430432
}
431433
432434
export function newChat() {
435+
posthog.capture("chat_new_chat_clicked", {
436+
had_messages: get(store).messages.length > 0,
437+
})
433438
store.reset()
434439
}
435440

app/web_ui/src/routes/(app)/chat/chat_cost_disclaimer.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import posthog from "posthog-js"
23
import { chat_cost_disclaimer_acknowledged } from "$lib/stores"
34
import Dialog from "$lib/ui/dialog.svelte"
45
@@ -9,6 +10,7 @@
910
1011
export function prompt(): Promise<boolean> {
1112
if (pendingPromise) return pendingPromise
13+
posthog.capture("chat_cost_disclaimer_shown")
1214
pendingPromise = new Promise<boolean>((resolve) => {
1315
pendingResolve = resolve
1416
dialog.show()
@@ -17,6 +19,7 @@
1719
}
1820
1921
function approve(): boolean {
22+
posthog.capture("chat_cost_disclaimer_accepted")
2023
chat_cost_disclaimer_acknowledged.set(true)
2124
const resolve = pendingResolve
2225
pendingResolve = null
@@ -26,6 +29,8 @@
2629
}
2730
2831
function dismiss() {
32+
if (pendingResolve === null) return
33+
posthog.capture("chat_cost_disclaimer_declined")
2934
const resolve = pendingResolve
3035
pendingResolve = null
3136
pendingPromise = null

app/web_ui/src/routes/(app)/chat/chat_history.svelte

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import { createEventDispatcher } from "svelte"
3+
import posthog from "posthog-js"
34
import { client } from "$lib/api_client"
45
import { hydrateSessionFromSnapshot } from "$lib/chat/session_messages"
56
import type { LoadedChatSessionDetail } from "$lib/chat/chat_history_apply"
@@ -48,7 +49,9 @@
4849
}
4950
5051
export function open() {
51-
historyDialog?.show()
52+
if (!historyDialog) return
53+
historyDialog.show()
54+
posthog.capture("chat_history_opened")
5255
void loadSessionList()
5356
}
5457
@@ -77,6 +80,9 @@
7780
const { messages, continuationTraceId } =
7881
hydrateSessionFromSnapshot(snapshot)
7982
dispatch("apply", { messages, continuationTraceId })
83+
posthog.capture("chat_history_session_loaded", {
84+
message_count: messages.length,
85+
})
8086
close()
8187
} catch (e) {
8288
sessionsError = createKilnError(e)
@@ -97,6 +103,7 @@
97103
return
98104
}
99105
sessionRows = sessionRows.filter((r) => r.id !== sessionId)
106+
posthog.capture("chat_history_session_deleted")
100107
} catch (e) {
101108
sessionsError = createKilnError(e)
102109
} finally {

0 commit comments

Comments
 (0)