Skip to content

Commit da6bdd0

Browse files
andrewm4894claudegithub-actions[bot]
authored
feat(llm-analytics): add early adopters feature flag (#42101)
Co-authored-by: Claude <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent eaa5665 commit da6bdd0

File tree

8 files changed

+58
-19
lines changed

8 files changed

+58
-19
lines changed

frontend/src/lib/constants.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export const FEATURE_FLAGS = {
197197
QUERY_CACHE_USE_S3: 'query-cache-use-s3', // owner: @aspicer #team-product-analytics
198198
DASHBOARD_THREADS: 'dashboard-threads', // owner: @aspicer #team-product-analytics
199199
BATCH_EXPORTS_POSTHOG_HTTP: 'posthog-http-batch-exports',
200+
LLM_ANALYTICS_EARLY_ADOPTERS: 'llm-analytics-early-adopters', // owner: #team-llm-analytics
200201
LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD: 'llm-analytics-customizable-dashboard', // owner: #team-llm-analytics
201202
LLM_ANALYTICS_DISCUSSIONS: 'llm-analytics-discussions', // owner: #team-llm-analytics
202203
BATCH_EXPORTS_DATABRICKS: 'databricks-batch-exports', // owner: @rossgray #team-batch-exports

products/llm_analytics/backend/api/summarization.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
from posthog.models import User
3030
from posthog.rate_limit import ClickHouseBurstRateThrottle, ClickHouseSustainedRateThrottle
3131

32-
from products.llm_analytics.backend.summarization.constants import SUMMARIZATION_FEATURE_FLAG
32+
from products.llm_analytics.backend.summarization.constants import (
33+
EARLY_ADOPTERS_FEATURE_FLAG,
34+
SUMMARIZATION_FEATURE_FLAG,
35+
)
3336
from products.llm_analytics.backend.summarization.llm import summarize
3437
from products.llm_analytics.backend.text_repr.formatters import (
3538
FormatterOptions,
@@ -115,9 +118,10 @@ def _validate_feature_access(self, request: Request) -> None:
115118
return
116119

117120
# Check feature flag using user's distinct_id to match against person-based cohorts
118-
if not posthoganalytics.feature_enabled(
119-
SUMMARIZATION_FEATURE_FLAG,
120-
str(request.user.distinct_id),
121+
distinct_id = str(request.user.distinct_id)
122+
if not (
123+
posthoganalytics.feature_enabled(SUMMARIZATION_FEATURE_FLAG, distinct_id)
124+
or posthoganalytics.feature_enabled(EARLY_ADOPTERS_FEATURE_FLAG, distinct_id)
121125
):
122126
raise exceptions.PermissionDenied("LLM trace summarization is not enabled for this user")
123127

products/llm_analytics/backend/summarization/constants.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
SUMMARIZATION_MODEL = "gpt-4.1-mini"
55
SUMMARIZATION_TIMEOUT = 120 # 2 minutes
66

7-
# Feature flag
7+
# Feature flags
88
SUMMARIZATION_FEATURE_FLAG = "llm-analytics-summarization"
9+
EARLY_ADOPTERS_FEATURE_FLAG = "llm-analytics-early-adopters"

products/llm_analytics/frontend/LLMAnalyticsReloadAction.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ export function LLMAnalyticsReloadAction(): JSX.Element {
2323
const { activeTab, selectedDashboardId, isRefreshing: oldTilesRefreshing } = useValues(llmAnalyticsLogic)
2424
const { refreshAllDashboardItems } = useActions(llmAnalyticsLogic)
2525

26-
const useCustomizableDashboard = featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD]
26+
const useCustomizableDashboard =
27+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD] ||
28+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
2729

2830
const shouldUseDashboardLogic = selectedDashboardId && useCustomizableDashboard && activeTab === 'dashboard'
2931
const dashboardLogicInstance = dashboardLogic({

products/llm_analytics/frontend/LLMAnalyticsScene.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ const Filters = ({ hidePropertyFilters = false }: { hidePropertyFilters?: boolea
9191
const dateFrom = activeTab === 'dashboard' ? dashboardDateFilter.dateFrom : dateFilter.dateFrom
9292
const dateTo = activeTab === 'dashboard' ? dashboardDateFilter.dateTo : dateFilter.dateTo
9393

94-
const useCustomizableDashboard = featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD]
94+
const useCustomizableDashboard =
95+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD] ||
96+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
9597

9698
return (
9799
<div className="flex gap-x-4 gap-y-2 items-center flex-wrap py-4 -mt-4 mb-4 border-b">
@@ -152,7 +154,9 @@ function LLMAnalyticsDashboard(): JSX.Element {
152154
const { selectedDashboardId, availableDashboardsLoading, dashboardDateFilter, propertyFilters } =
153155
useValues(llmAnalyticsLogic)
154156

155-
const useCustomizableDashboard = featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD]
157+
const useCustomizableDashboard =
158+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD] ||
159+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
156160
const dashboardLogicInstance = React.useMemo(
157161
() =>
158162
selectedDashboardId
@@ -656,7 +660,10 @@ export function LLMAnalyticsScene(): JSX.Element {
656660
},
657661
]
658662

659-
if (featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_ERRORS_TAB]) {
663+
if (
664+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_ERRORS_TAB] ||
665+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
666+
) {
660667
tabs.push({
661668
key: 'errors',
662669
label: (
@@ -677,7 +684,10 @@ export function LLMAnalyticsScene(): JSX.Element {
677684
})
678685
}
679686

680-
if (featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW]) {
687+
if (
688+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW] ||
689+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
690+
) {
681691
tabs.push({
682692
key: 'sessions',
683693
label: (

products/llm_analytics/frontend/LLMAnalyticsTraceScene.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ function TraceSceneWrapper(): JSX.Element {
123123
/>
124124
<div className="flex flex-wrap justify-end items-center gap-x-2 gap-y-1">
125125
<DisplayOptionsSelect />
126-
{featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS] && (
126+
{(featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS] ||
127+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]) && (
127128
<LemonButton
128129
type="secondary"
129130
size="xsmall"
@@ -212,7 +213,10 @@ function TraceMetadata({
212213
const { featureFlags } = useValues(featureFlagLogic)
213214

214215
const getSessionUrl = (sessionId: string): string => {
215-
if (featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW]) {
216+
if (
217+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW] ||
218+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
219+
) {
216220
return urls.llmAnalyticsSession(sessionId)
217221
}
218222
// Fallback to filtering traces by session when feature flag is off
@@ -239,7 +243,8 @@ function TraceMetadata({
239243
{trace.aiSessionId && (
240244
<Chip
241245
title={
242-
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW]
246+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SESSIONS_VIEW] ||
247+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
243248
? 'AI Session ID - Click to view session details'
244249
: 'AI Session ID - Click to filter traces by this session'
245250
}
@@ -685,7 +690,9 @@ const EventContent = React.memo(
685690

686691
const showEvalsTab = isGenerationEvent && featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EVALUATIONS]
687692

688-
const showSummaryTab = featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SUMMARIZATION]
693+
const showSummaryTab =
694+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_SUMMARIZATION] ||
695+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
689696

690697
// Load AI data for the current event
691698
const { input: loadedInput, output: loadedOutput } = useAIData(event)
@@ -811,7 +818,8 @@ const EventContent = React.memo(
811818
content: (
812819
<>
813820
{displayOption === DisplayOption.TextView &&
814-
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_TEXT_VIEW] ? (
821+
(featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_TEXT_VIEW] ||
822+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]) ? (
815823
isLLMEvent(event) &&
816824
(event.event === '$ai_generation' ||
817825
event.event === '$ai_span' ||
@@ -1024,7 +1032,8 @@ function DisplayOptionsSelect(): JSX.Element {
10241032
label: 'Collapse except output and last input',
10251033
tooltip: 'Focus on the most recent input and final output',
10261034
},
1027-
...(featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_TEXT_VIEW]
1035+
...(featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_TEXT_VIEW] ||
1036+
featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
10281037
? [
10291038
{
10301039
value: DisplayOption.TextView,

products/llm_analytics/frontend/llmAnalyticsLogic.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,10 @@ export const llmAnalyticsLogic = kea<llmAnalyticsLogicType>([
13821382
afterMount(({ actions, values }) => {
13831383
actions.loadAIEventDefinition()
13841384

1385-
if (values.featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD]) {
1385+
if (
1386+
values.featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_CUSTOMIZABLE_DASHBOARD] ||
1387+
values.featureFlags[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
1388+
) {
13861389
actions.loadLLMDashboards()
13871390
}
13881391
}),

products/llm_analytics/frontend/llmAnalyticsTraceLogic.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,13 @@ export const llmAnalyticsTraceLogic = kea<llmAnalyticsTraceLogicType>([
177177
0,
178178
{
179179
loadCommentCount: async (_, breakpoint) => {
180-
if (!values.traceId || !values.featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS]) {
180+
if (
181+
!values.traceId ||
182+
!(
183+
values.featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS] ||
184+
values.featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
185+
)
186+
) {
181187
return 0
182188
}
183189

@@ -262,7 +268,10 @@ export const llmAnalyticsTraceLogic = kea<llmAnalyticsTraceLogicType>([
262268
return {
263269
activity_scope: ActivityScope.LLM_TRACE,
264270
activity_item_id: traceId || '',
265-
discussions_disabled: !featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS],
271+
discussions_disabled: !(
272+
featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_DISCUSSIONS] ||
273+
featureFlags?.[FEATURE_FLAGS.LLM_ANALYTICS_EARLY_ADOPTERS]
274+
),
266275
activity_item_context: { trace_id: traceId || '' },
267276
}
268277
},

0 commit comments

Comments
 (0)