From fd44d5911b0724dadd4eac7182a565feb515f37a Mon Sep 17 00:00:00 2001 From: Romeo Balta <7095569+romeobalta@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:56:37 +0000 Subject: [PATCH] feat(editor): Track AI credit balance clicks (no-changelog) (#36194) --- .../@n8n/telemetry/src/events/instance-ai.ts | 6 ++++ .../Agent/CreditsSettingsDropdown.test.ts | 32 ++++++++++++++++++- .../Agent/CreditsSettingsDropdown.vue | 4 +++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/@n8n/telemetry/src/events/instance-ai.ts b/packages/@n8n/telemetry/src/events/instance-ai.ts index b29553b5ed5..121fc900097 100644 --- a/packages/@n8n/telemetry/src/events/instance-ai.ts +++ b/packages/@n8n/telemetry/src/events/instance-ai.ts @@ -3,6 +3,12 @@ import { z } from 'zod/v4'; import { defineTelemetryEvents } from '../define'; export const INSTANCE_AI_TELEMETRY = defineTelemetryEvents({ + USER_CLICKED_AI_CREDIT_BALANCE: { + name: 'User clicked AI credit balance', + description: + 'The user clicked the AI Assistant credit balance button to open or close the balance dropdown.', + properties: z.object({}), + }, BUILDER_SPECCED_TEMPLATED_CRED: { name: 'Builder specced templated cred', description: diff --git a/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.test.ts b/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.test.ts index 3e2898ca290..efd33b4e9ff 100644 --- a/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.test.ts +++ b/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.test.ts @@ -1,7 +1,14 @@ -import { describe, it, expect, vi } from 'vitest'; +import { beforeEach, describe, it, expect, vi } from 'vitest'; import { mount } from '@vue/test-utils'; +import { TELEMETRY_EVENT } from '@n8n/telemetry'; import CreditsSettingsDropdown from './CreditsSettingsDropdown.vue'; +const { telemetryTrack } = vi.hoisted(() => ({ telemetryTrack: vi.fn() })); + +vi.mock('@n8n/composables/useTelemetry', () => ({ + useTelemetry: () => ({ track: telemetryTrack }), +})); + vi.mock('@n8n/i18n', () => { const baseText = (key: string, options?: { interpolate?: Record }) => { if (options?.interpolate) { @@ -28,6 +35,29 @@ function mountOpen(props: { } describe('CreditsSettingsDropdown', () => { + beforeEach(() => { + telemetryTrack.mockClear(); + }); + + it('tracks every credit balance button click', async () => { + const wrapper = mount(CreditsSettingsDropdown, { + props: { + creditsRemaining: 50, + creditsQuota: 100, + isLowCredits: false, + }, + }); + const button = wrapper.get('[data-test-id="credits-dropdown-button"]'); + + await button.trigger('click'); + await button.trigger('click'); + + expect(telemetryTrack.mock.calls).toEqual([ + [TELEMETRY_EVENT.INSTANCE_AI.USER_CLICKED_AI_CREDIT_BALANCE, {}], + [TELEMETRY_EVENT.INSTANCE_AI.USER_CLICKED_AI_CREDIT_BALANCE, {}], + ]); + }); + it('rounds creditsRemaining to two decimal places', async () => { const wrapper = mountOpen({ creditsRemaining: 97.357, diff --git a/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.vue b/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.vue index b7a25c59119..87cabbbe3b5 100644 --- a/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.vue +++ b/packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/CreditsSettingsDropdown.vue @@ -1,7 +1,9 @@