diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAi.threadRuntime.test.ts b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAi.threadRuntime.test.ts index 17517cd06b4..6039771ad29 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAi.threadRuntime.test.ts +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAi.threadRuntime.test.ts @@ -790,6 +790,24 @@ describe('createThreadRuntime - SSE and hydration', () => { expect(mockPostMessage).toHaveBeenCalledTimes(1); }); + test('sendMessage tracks whether this is the first user message in the thread', async () => { + mockPostMessage.mockResolvedValue({ runId: 'run-1' }); + + await activeRuntime(registry).sendMessage('first'); + await activeRuntime(registry).sendMessage('second'); + + expect(mockTelemetryTrack).toHaveBeenNthCalledWith(1, 'User sent builder message', { + thread_id: activeThreadId, + instance_id: 'instance-1', + is_first_message: true, + }); + expect(mockTelemetryTrack).toHaveBeenNthCalledWith(2, 'User sent builder message', { + thread_id: activeThreadId, + instance_id: 'instance-1', + is_first_message: false, + }); + }); + test('sendMessage forwards pushRef to postMessage', async () => { mockPostMessage.mockResolvedValue({ runId: 'run-1' }); diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.threadRuntime.ts b/packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.threadRuntime.ts index 661a96ba934..3dfc111713b 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.threadRuntime.ts +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.threadRuntime.ts @@ -755,15 +755,11 @@ export function createThreadRuntime(threadId: string, hooks: ThreadRuntimeHooks) } } - function trackUserMessageSent(optimistic: InstanceAiMessage): void { - // The first user message in the array is the first the thread has ever - // seen. `find` short-circuits at the first match, so this is O(1) once - // the user has sent more than one message. - const firstUser = messages.value.find((m) => m.role === 'user'); + function trackUserMessageSent(isFirstMessage: boolean): void { telemetry.track('User sent builder message', { thread_id: threadId, instance_id: rootStore.instanceId, - is_first_message: firstUser === optimistic, + is_first_message: isFirstMessage, }); } @@ -815,8 +811,9 @@ export function createThreadRuntime(threadId: string, hooks: ThreadRuntimeHooks) pendingMessageCount.value += 1; try { ensureSSEConnected(); + const isFirstMessage = !messages.value.some((m) => m.role === 'user'); const optimistic = pushOptimisticUserMessage(message, attachments); - trackUserMessageSent(optimistic); + trackUserMessageSent(isFirstMessage); if (!(await dispatchUserMessage(message, attachments, pushRef))) { removeOptimisticMessage(optimistic);