diff --git a/frontend/__snapshots__/components-playlist--default--dark.png b/frontend/__snapshots__/components-playlist--default--dark.png index e4fd2ffed9c1e..98c69d7c60025 100644 Binary files a/frontend/__snapshots__/components-playlist--default--dark.png and b/frontend/__snapshots__/components-playlist--default--dark.png differ diff --git a/frontend/__snapshots__/components-playlist--default--light.png b/frontend/__snapshots__/components-playlist--default--light.png index 546d7f9249d3a..7195997207c9e 100644 Binary files a/frontend/__snapshots__/components-playlist--default--light.png and b/frontend/__snapshots__/components-playlist--default--light.png differ diff --git a/frontend/__snapshots__/components-playlist--multiple-sections--dark.png b/frontend/__snapshots__/components-playlist--multiple-sections--dark.png index 3cedfb43d7720..8de39c8bbd89e 100644 Binary files a/frontend/__snapshots__/components-playlist--multiple-sections--dark.png and b/frontend/__snapshots__/components-playlist--multiple-sections--dark.png differ diff --git a/frontend/__snapshots__/components-playlist--multiple-sections--light.png b/frontend/__snapshots__/components-playlist--multiple-sections--light.png index 73fd6c29c5e31..e342c362e1962 100644 Binary files a/frontend/__snapshots__/components-playlist--multiple-sections--light.png and b/frontend/__snapshots__/components-playlist--multiple-sections--light.png differ diff --git a/frontend/__snapshots__/components-playlist--with-footer--dark.png b/frontend/__snapshots__/components-playlist--with-footer--dark.png index e4fd2ffed9c1e..b7983dde1b6ca 100644 Binary files a/frontend/__snapshots__/components-playlist--with-footer--dark.png and b/frontend/__snapshots__/components-playlist--with-footer--dark.png differ diff --git a/frontend/__snapshots__/components-playlist--with-footer--light.png b/frontend/__snapshots__/components-playlist--with-footer--light.png index 546d7f9249d3a..bb230e59c025e 100644 Binary files a/frontend/__snapshots__/components-playlist--with-footer--light.png and b/frontend/__snapshots__/components-playlist--with-footer--light.png differ diff --git a/frontend/__snapshots__/replay-player-failure--recent-recordings-404--dark.png b/frontend/__snapshots__/replay-player-failure--recent-recordings-404--dark.png index 29d7d6dd6a123..c30360e3fcc2a 100644 Binary files a/frontend/__snapshots__/replay-player-failure--recent-recordings-404--dark.png and b/frontend/__snapshots__/replay-player-failure--recent-recordings-404--dark.png differ diff --git a/frontend/__snapshots__/replay-player-failure--recent-recordings-404--light.png b/frontend/__snapshots__/replay-player-failure--recent-recordings-404--light.png index 18f28d66e293f..b3a096d98b9d6 100644 Binary files a/frontend/__snapshots__/replay-player-failure--recent-recordings-404--light.png and b/frontend/__snapshots__/replay-player-failure--recent-recordings-404--light.png differ diff --git a/frontend/__snapshots__/replay-player-success--recent-recordings--dark.png b/frontend/__snapshots__/replay-player-success--recent-recordings--dark.png index 7ba256e7107f3..1775d58ae0e62 100644 Binary files a/frontend/__snapshots__/replay-player-success--recent-recordings--dark.png and b/frontend/__snapshots__/replay-player-success--recent-recordings--dark.png differ diff --git a/frontend/__snapshots__/replay-player-success--recent-recordings--light.png b/frontend/__snapshots__/replay-player-success--recent-recordings--light.png index be5daaf577676..81021b0f7998d 100644 Binary files a/frontend/__snapshots__/replay-player-success--recent-recordings--light.png and b/frontend/__snapshots__/replay-player-success--recent-recordings--light.png differ diff --git a/frontend/__snapshots__/replay-player-success--second-recording-in-list--dark.png b/frontend/__snapshots__/replay-player-success--second-recording-in-list--dark.png index 424631cab2d81..e009eb5272c06 100644 Binary files a/frontend/__snapshots__/replay-player-success--second-recording-in-list--dark.png and b/frontend/__snapshots__/replay-player-success--second-recording-in-list--dark.png differ diff --git a/frontend/__snapshots__/replay-player-success--second-recording-in-list--light.png b/frontend/__snapshots__/replay-player-success--second-recording-in-list--light.png index f50cfbfc0dc8d..b739379bc2bf2 100644 Binary files a/frontend/__snapshots__/replay-player-success--second-recording-in-list--light.png and b/frontend/__snapshots__/replay-player-success--second-recording-in-list--light.png differ diff --git a/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--dark.png b/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--dark.png index f0f97768a2eb8..51b5ebde2b91c 100644 Binary files a/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--dark.png and b/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--light.png b/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--light.png index ed5fcf71041eb..7990018d5bdf9 100644 Binary files a/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--light.png and b/frontend/__snapshots__/scenes-app-notebooks--recordings-playlist--light.png differ diff --git a/frontend/src/scenes/session-recordings/components/AiFilter/AiFilter.tsx b/frontend/src/scenes/session-recordings/components/AiFilter/AiFilter.tsx index 8af7092fc20b4..04306cc233f48 100644 --- a/frontend/src/scenes/session-recordings/components/AiFilter/AiFilter.tsx +++ b/frontend/src/scenes/session-recordings/components/AiFilter/AiFilter.tsx @@ -1,8 +1,8 @@ -import { LemonCollapse, LemonTag } from '@posthog/lemon-ui' import { useActions, useMountedLogic, useValues } from 'kea' import { sessionRecordingsPlaylistLogic } from 'scenes/session-recordings/playlist/sessionRecordingsPlaylistLogic' import { AiFilterInput } from './AiFilterInput' +import { AiFilterIntro } from './AiFilterIntro' import { aiFilterLogic } from './aiFilterLogic' import { AiFilterSuggestions } from './AiFilterSuggestions' import { AiFilterThread } from './AiFilterThread' @@ -14,35 +14,11 @@ export function AiFilter(): JSX.Element { const { messages } = useValues(filterLogic) return ( - <> - -

- Chat with your recording list ALPHA -

-
- Ask Max AI to find recordings matching your needs - like "show me recordings with - rage clicks" or "find recordings where users visited pricing" -
- - ), - content: ( - <> -
- - - {messages.length === 0 && } -
- - ), - }, - ]} - /> - +
+ {messages.length === 0 && } + + + {messages.length === 0 && } +
) } diff --git a/frontend/src/scenes/session-recordings/components/AiFilter/AiFilterInput.tsx b/frontend/src/scenes/session-recordings/components/AiFilter/AiFilterInput.tsx index 865122ea34b37..41a7ab55338f8 100644 --- a/frontend/src/scenes/session-recordings/components/AiFilter/AiFilterInput.tsx +++ b/frontend/src/scenes/session-recordings/components/AiFilter/AiFilterInput.tsx @@ -50,6 +50,10 @@ export function AiFilterInput(): JSX.Element { /> + + * Max AI currently only knows about PostHog default properties added by our SDKs. For your custom + properties, use the filters box below. + {messages.length > 0 && (
+
+ + + +
+
+

Chat with your recordings

+
+ I'm Max, here to help you to find recordings matching your needs. +
+
+ + ) +} diff --git a/frontend/src/scenes/session-recordings/components/AiFilter/aiFilterLogic.ts b/frontend/src/scenes/session-recordings/components/AiFilter/aiFilterLogic.ts index 1653c1d43b85c..41cd68d4be0f1 100644 --- a/frontend/src/scenes/session-recordings/components/AiFilter/aiFilterLogic.ts +++ b/frontend/src/scenes/session-recordings/components/AiFilter/aiFilterLogic.ts @@ -5,6 +5,7 @@ import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, } from 'openai/resources/chat/completions' +import posthog from 'posthog-js' import { RecordingUniversalFilters } from '~/types' @@ -67,6 +68,7 @@ export const aiFilterLogic = kea([ }), listeners(({ actions, values, props }) => ({ handleSend: () => { + posthog.capture('ai_filter_send') const newMessages = [ ...values.messages, { @@ -92,6 +94,7 @@ export const aiFilterLogic = kea([ if (content.hasOwnProperty('result')) { if (content.result === 'filter') { props.setFilters(content.data) + posthog.capture('ai_filter_success') } actions.setMessages([ @@ -110,6 +113,7 @@ export const aiFilterLogic = kea([ content: 'Sorry, I was unable to process your request. Please try again.', } as ChatCompletionAssistantMessageParam, ]) + posthog.capture('ai_filter_error') } actions.setIsLoading(false) @@ -117,6 +121,7 @@ export const aiFilterLogic = kea([ handleReset: () => { actions.setMessages([]) props.resetFilters() + posthog.capture('ai_filter_reset') }, })), ]) diff --git a/frontend/src/scenes/session-recordings/playlist/Playlist.tsx b/frontend/src/scenes/session-recordings/playlist/Playlist.tsx index c383b32f5c05c..dd5e7f5fcada0 100644 --- a/frontend/src/scenes/session-recordings/playlist/Playlist.tsx +++ b/frontend/src/scenes/session-recordings/playlist/Playlist.tsx @@ -1,12 +1,17 @@ import './Playlist.scss' -import { LemonCollapse, LemonSkeleton, Tooltip } from '@posthog/lemon-ui' +import { IconAIText, IconX } from '@posthog/icons' +import { LemonButton, LemonCollapse, LemonSkeleton, LemonTag, Tooltip } from '@posthog/lemon-ui' import clsx from 'clsx' +import { FlaggedFeature } from 'lib/components/FlaggedFeature' +import { FEATURE_FLAGS } from 'lib/constants' import { useResizeBreakpoints } from 'lib/hooks/useResizeObserver' import { LemonTableLoader } from 'lib/lemon-ui/LemonTable/LemonTableLoader' import { range } from 'lib/utils' +import posthog from 'posthog-js' import { ReactNode, useRef, useState } from 'react' import { DraggableToNotebook } from 'scenes/notebooks/AddToNotebook/DraggableToNotebook' +import { AiFilter } from 'scenes/session-recordings/components/AiFilter/AiFilter' import { SessionRecordingType } from '~/types' @@ -83,6 +88,8 @@ export function Playlist({ 750: 'medium', }) + const [isExpanded, setIsExpanded] = useState(false) + const onChangeActiveItem = (item: SessionRecordingType): void => { setControlledActiveItemId(item.id) onSelect?.(item) @@ -132,90 +139,139 @@ export function Playlist({ .flatMap((s) => s.items).length return ( -
+ <>
-
- {filterActions} - -
- -
-
- {title && } - {headerActions} -
- -
-
-
- {sectionCount > 1 ? ( - { - return { - key: s.key, - header: s.title ?? '', - content: ( - - ), - className: 'p-0', - } - })} - onChange={onChangeOpenSections} - multiple - embedded - size="small" - /> - ) : sectionCount === 1 ? ( - - ) : loading ? ( - - ) : ( - listEmptyState - )} -
-
- {footerActions} -
-
+
+ } + onClick={() => { + setIsExpanded(false) + posthog.capture('ai_filter_close') + }} + />
+
+
- {content && ( -
- {' '} - {typeof content === 'function' ? content({ activeItem }) : content} +
+ {!isExpanded && ( + +
+ } + onClick={() => { + setIsExpanded(true) + posthog.capture('ai_filter_open') + }} + > + Ask Max AI about recordings{' '} + + ALPHA + + +
+
+ )} +
+
+ {filterActions} + +
+ +
+
+ {title && } + {headerActions} +
+ +
+
+
+ {sectionCount > 1 ? ( + { + return { + key: s.key, + header: s.title ?? '', + content: ( + + ), + className: 'p-0', + } + })} + onChange={onChangeOpenSections} + multiple + embedded + size="small" + /> + ) : sectionCount === 1 ? ( + + ) : loading ? ( + + ) : ( + listEmptyState + )} +
+
+ {footerActions} +
+
+
- )} +
+
+ {content && ( +
+ {' '} + {typeof content === 'function' ? content({ activeItem }) : content} +
+ )} +
-
+ ) } diff --git a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx index 3ea8f77dca50d..45368f227d7fd 100644 --- a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx +++ b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx @@ -1,7 +1,6 @@ import { LemonBadge, LemonButton, Link, Spinner } from '@posthog/lemon-ui' import { BindLogic, useActions, useValues } from 'kea' import { EmptyMessage } from 'lib/components/EmptyMessage/EmptyMessage' -import { FlaggedFeature } from 'lib/components/FlaggedFeature' import { PropertyKeyInfo } from 'lib/components/PropertyKeyInfo' import { FEATURE_FLAGS } from 'lib/constants' import { LemonBanner } from 'lib/lemon-ui/LemonBanner' @@ -12,7 +11,6 @@ import { urls } from 'scenes/urls' import { ReplayTabs } from '~/types' -import { AiFilter } from '../components/AiFilter/AiFilter' import { RecordingsUniversalFilters } from '../filters/RecordingsUniversalFilters' import { SessionRecordingPlayer } from '../player/SessionRecordingPlayer' import { SessionRecordingPreview } from './SessionRecordingPreview' @@ -106,9 +104,6 @@ export function SessionRecordingsPlaylist({ return ( - - -
): boolean { + if (!filters || typeof filters !== 'object') { + return false + } + + if ('date_from' in filters && filters.date_from !== null && typeof filters.date_from !== 'string') { + return false + } + if ('date_to' in filters && filters.date_to !== null && typeof filters.date_to !== 'string') { + return false + } + + if ('filter_test_accounts' in filters && typeof filters.filter_test_accounts !== 'boolean') { + return false + } + + if ('duration' in filters) { + if (!Array.isArray(filters.duration)) { + return false + } + if ( + filters.duration.length > 0 && + (!filters.duration[0]?.type || !filters.duration[0]?.key || !filters.duration[0]?.operator) + ) { + return false + } + } + + if ('filter_group' in filters) { + const group = filters.filter_group + if (!group || typeof group !== 'object') { + return false + } + if (!('type' in group) || !('values' in group) || !Array.isArray(group.values)) { + return false + } + } + + if ('order' in filters && typeof filters.order !== 'string') { + return false + } + + return true +} + export function convertUniversalFiltersToRecordingsQuery(universalFilters: RecordingUniversalFilters): RecordingsQuery { const filters = filtersFromUniversalFilterGroups(universalFilters) @@ -418,6 +468,10 @@ export const sessionRecordingsPlaylistLogic = kea { + if (!isValidRecordingFilters(filters)) { + console.error('Invalid filters provided:', filters) + return state + } return { ...state, ...filters, diff --git a/posthog/session_recordings/ai_data/ai_filter_prompts.py b/posthog/session_recordings/ai_data/ai_filter_prompts.py index 2888b679323a8..6396e30d1d07a 100644 --- a/posthog/session_recordings/ai_data/ai_filter_prompts.py +++ b/posthog/session_recordings/ai_data/ai_filter_prompts.py @@ -1,3 +1,6 @@ +from posthog.taxonomy.taxonomy import CORE_FILTER_DEFINITIONS_BY_GROUP, CAMPAIGN_PROPERTIES +import json + AI_FILTER_INITIAL_PROMPT = """ Posthog (posthog.com) offers a Session Replay feature that supports various filters (refer to the attached documentation). Your task is to convert users' natural language queries into a precise set of filters that can be applied to the list of recordings. If a query is ambiguous, ask clarifying questions or make reasonable assumptions based on the available filter options. @@ -66,7 +69,7 @@ - Relative Date (Days): Use the format "-Nd" for the last N days (e.g., "last 5 days" becomes "-5d"). - Relative Date (Hours): Use the format "-Nh" for the last N hours (e.g., "last 5 hours" becomes "-5h"). - Custom Date: If a specific start date is provided, use the format "YYYY-MM-DD". - - Default Behavior: If the user does not specify a date range, default to the last 5 days (i.e., use "-5d"). + - Default Behavior: If the user does not specify a date range, default to the last 5 days (i.e., use "-5d"). date_from MUST be set. date_to: - Default Value: Set as null when the date range extends to today. - Custom Date: If a specific end date is required, use the format "YYYY-MM-DD". @@ -252,9 +255,11 @@ } ] } + + 5. Prefer event over session properties, and session properties over person properties where it isn't clear """ -AI_FILTER_PROPERTIES_PROMPT = """ +AI_FILTER_PROPERTIES_PROMPT = f""" Field - Purpose: @@ -306,786 +311,9 @@ - Event Filtering: When the query references an event (such as a user action or system event) by name, verify that the corresponds to an entry in the Event properties or the provided list of event names. - - Sample Use Cases: - - Mobile Device Example: - Query: "Show me recordings where people use mobile phone." - Interpretation: Filter on the person property $device_type. - Filter snippet: - json - { - "key": "$device_type", - "type": PropertyFilterType.Person, - "value": ["Mobile"], - "operator": PropertyOperator.Exact - } - - URL Filtering Example: - Query: "Show recordings for the landing page" (without specifying a URL). - Action: The agent should ask for clarification, e.g., "Could you please provide the specific URL for the landing page?" This ensures that the correct property ($current_url or similar) is used. - - - Event-Specific Example: - Query: "Show recordings of people who are frustrated." - Interpretation: Map this to rageclick events. - Filter snippet: Use the event key (e.g., $rageclick) to identify these events, ensuring that the filter is constructed with the appropriate property type and operator. - - Person properties array is below. You can use "name" field. You can guess the type of the property from the "property_type" field and meaning by the name. - [ - { - "name": "$browser", - "property_type": "String", - }, - { - "name": "$browser_version", - "property_type": "Numeric", - }, - { - "name": "$current_url", - "property_type": "String", - }, - { - "name": "$device_type", - "property_type": "String", - }, - { - "name": "$initial__kx", - "property_type": null, - }, - { - "name": "$initial_browser", - "property_type": "String", - }, - { - "name": "$initial_browser_version", - "property_type": "Numeric", - }, - { - "name": "$initial_current_url", - "property_type": "String", - }, - { - "name": "$initial_dclid", - "property_type": null, - }, - { - "name": "$initial_device_type", - "property_type": "String", - }, - { - "name": "$initial_fbclid", - "property_type": null, - }, - }, - { - "name": "$initial_gad_source", - "property_type": null, - }, - { - "name": "$initial_gbraid", - "property_type": null, - }, - { - "name": "$initial_gclid", - "property_type": null, - }, - { - "name": "$initial_gclsrc", - "property_type": null, - }, - { - "name": "$initial_host", - "property_type": "String", - }, - { - "name": "$initial_igshid", - "property_type": null, - }, - { - "name": "$initial_irclid", - "property_type": null, - }, - }, - { - "name": "$initial_li_fat_id", - "property_type": null, - }, - }, - { - "name": "$initial_mc_cid", - "property_type": null, - }, - { - "name": "$initial_msclkid", - "property_type": null, - }, - { - "name": "$initial_os", - "property_type": "String", - }, - { - "name": "$initial_os_version", - "property_type": "String", - }, - { - "name": "$initial_pathname", - "property_type": "String", - }, - { - "name": "$initial_rdt_cid", - "property_type": null, - }, - { - "name": "$initial_referrer", - "property_type": "String", - }, - { - "name": "$initial_referring_domain", - "property_type": "String", - }, - { - "name": "$initial_ttclid", - "property_type": null, - }, - { - "name": "$initial_twclid", - "property_type": null, - }, - { - "name": "$initial_utm_campaign", - "property_type": null, - }, - { - "name": "$initial_utm_content", - "property_type": null, - }, - { - "name": "$initial_utm_medium", - "property_type": null, - }, - { - "name": "$initial_utm_source", - "property_type": null, - }, - { - "name": "$initial_utm_term", - "property_type": null, - }, - { - "name": "$initial_wbraid", - "property_type": null, - }, - { - "name": "$os", - "property_type": "String", - }, - { - "name": "$os_version", - "property_type": "String", - }, - { - "name": "$pathname", - "property_type": "String", - }, - { - "name": "$referrer", - "property_type": "String", - }, - { - "name": "$referring_domain", - "property_type": "String", - }, - { - "name": "anonymize_data", - "property_type": "Boolean", - }, - { - "name": "completed_onboarding_once", - "property_type": "Boolean", - }, - { - "name": "current_organization_membership_level", - "property_type": "Numeric", - }, - { - "name": "email", - "property_type": "String", - }, - { - "name": "has_password_set", - "property_type": "Boolean", - }, - { - "name": "has_seen_product_intro_for", - "property_type": null, - }, - { - "name": "has_social_auth", - "property_type": "Boolean", - }, - { - "name": "instance_tag", - "property_type": "String", - }, - { - "name": "instance_url", - "property_type": "String", - }, - { - "name": "is_email_verified", - "property_type": "Boolean", - }, - { - "name": "is_signed_up", - "property_type": "Boolean" - }, - { - "name": "joined_at", - "property_type": "String" - }, - { - "name": "organization_count", - "property_type": "Numeric" - }, - { - "name": "organization_id", - "property_type": "String" - }, - { - "name": "project_count", - "property_type": "Numeric" - }, - { - "name": "project_id", - "property_type": "String" - }, - { - "name": "project_setup_complete", - "property_type": "Boolean" - }, - { - "name": "realm", - "property_type": "String" - }, - { - "name": "social_providers", - "property_type": null - }, - { - "name": "strapi_id", - "property_type": null - }, - { - "name": "team_member_count_all", - "property_type": "Numeric" - } - ] - - Session properties array is below. You can use "name" field. You can guess the type of the property from the "property_type" field and meaning by the name. - [ - { - "name": "$start_timestamp", - "property_type": "DateTime" - }, - { - "name": "$end_timestamp", - "property_type": "DateTime" - }, - { - "name": "$entry_current_url", - "property_type": "String" - }, - { - "name": "$entry_pathname", - "property_type": "String" - }, - { - "name": "$entry_hostname", - "property_type": "String" - }, - { - "name": "$end_current_url", - "property_type": "String" - }, - { - "name": "$end_pathname", - "property_type": "String" - }, - { - "name": "$end_hostname", - "property_type": "String" - }, - { - "name": "$entry_utm_source", - "property_type": "String" - }, - { - "name": "$entry_utm_campaign", - "property_type": "String" - }, - { - "name": "$entry_utm_medium", - "property_type": "String" - }, - { - "name": "$entry_utm_term", - "property_type": "String" - }, - { - "name": "$entry_utm_content", - "property_type": "String" - }, - { - "name": "$entry_referring_domain", - "property_type": "String" - }, - { - "name": "$entry_gclid", - "property_type": "String" - }, - { - "name": "$entry_fbclid", - "property_type": "String" - }, - { - "name": "$entry_gad_source", - "property_type": "String" - }, - { - "name": "$pageview_count", - "property_type": "Numeric" - }, - { - "name": "$autocapture_count", - "property_type": "Numeric" - }, - { - "name": "$screen_count", - "property_type": "Numeric" - }, - { - "name": "$channel_type", - "property_type": "String" - }, - { - "name": "$session_duration", - "property_type": "Duration" - }, - { - "name": "$is_bounce", - "property_type": "Boolean" - }, - { - "name": "$last_external_click_url", - "property_type": "String" - }, - { - "name": "$vitals_lcp", - "property_type": "Numeric" - } - ] - - Event properties. You can use "name" field. You can guess the type of the property from the "property_type" field and meaning by the name: - [ - { - "name": "$active_feature_flags", - "property_type": null - }, - { - "name": "$anon_distinct_id", - "property_type": "String" - }, - { - "name": "$autocapture_disabled_server_side", - "property_type": "Boolean" - }, - { - "name": "$browser", - "property_type": "String" - }, - { - "name": "$browser_language", - "property_type": "String" - }, - { - "name": "$browser_language_prefix", - "property_type": "String" - }, - { - "name": "$browser_type", - "property_type": "String" - }, - { - "name": "$browser_version", - "property_type": "Numeric" - }, - { - "name": "$ce_version", - "property_type": "Numeric" - }, - { - "name": "$configured_session_timeout_ms", - "property_type": "DateTime" - }, - { - "name": "$console_log_recording_enabled_server_side", - "property_type": "Boolean" - }, - { - "name": "$copy_type", - "property_type": "String" - }, - { - "name": "$current_url", - "property_type": "String" - } - { - "name": "$dead_clicks_enabled_server_side", - "property_type": "Boolean" - }, - { - "name": "$device_id", - "property_type": "String" - }, - { - "name": "$device_type", - "property_type": "String" - }, - { - "name": "$el_text", - "property_type": "String" - }, - { - "name": "$event_type", - "property_type": "String" - }, - { - "name": "$exception_capture_enabled_server_side", - "property_type": "Boolean" - }, - { - "name": "$external_click_url", - "property_type": "String" - }, - { - "name": "$feature_flag", - "property_type": "String" - }, - { - "name": "$feature_flag_bootstrapped_payload", - "property_type": null - }, - { - "name": "$feature_flag_bootstrapped_response", - "property_type": null - }, - { - "name": "$feature_flag_payload", - "property_type": null - }, - { - "name": "$feature_flag_payloads", - "property_type": null - }, - { - "name": "$feature_flag_response", - "property_type": "String" - }, - { - "name": "$geoip_disable", - "property_type": "Boolean" - }, - { - "name": "$had_persisted_distinct_id", - "property_type": "Boolean" - }, - { - "name": "$host", - "property_type": "String" - }, - { - "name": "$initial_person_info", - "property_type": null - }, - { - "name": "$insert_id", - "property_type": "String" - }, - { - "name": "$ip", - "property_type": "String" - }, - { - "name": "$is_identified", - "property_type": "Boolean" - }, - { - "name": "$lib", - "property_type": "String" - }, - { - "name": "$lib_custom_api_host", - "property_type": "String" - }, - { - "name": "$lib_rate_limit_remaining_tokens", - "property_type": "Numeric" - }, - { - "name": "$lib_version", - "property_type": "String" - }, - { - "name": "$os", - "property_type": "String" - }, - { - "name": "$os_version", - "property_type": "String" - }, - { - "name": "$pageview_id", - "property_type": "String" - }, - { - "name": "$pathname", - "property_type": "String" - }, - { - "name": "$plugins_failed", - "property_type": null - }, - { - "name": "$plugins_succeeded", - "property_type": null - }, - { - "name": "$prev_pageview_duration", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_id", - "property_type": "String" - }, - { - "name": "$prev_pageview_last_content", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_last_content_percentage", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_last_scroll", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_last_scroll_percentage", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_max_content", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_max_content_percentage", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_max_scroll", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_max_scroll_percentage", - "property_type": "Numeric" - }, - { - "name": "$prev_pageview_pathname", - "property_type": "String" - }, - { - "name": "$raw_user_agent", - "property_type": "String" - }, - { - "name": "$recording_status", - "property_type": "String" - }, - { - "name": "$referrer", - "property_type": "String" - }, - { - "name": "$referring_domain", - "property_type": "String" - }, - { - "name": "$replay_minimum_duration", - "property_type": null - }, - { - "name": "$replay_sample_rate", - "property_type": null - }, - { - "name": "$replay_script_config", - "property_type": null - }, - { - "name": "$screen_height", - "property_type": "Numeric" - }, - { - "name": "$screen_width", - "property_type": "Numeric" - }, - { - "name": "$selected_content", - "property_type": "String" - }, - { - "name": "$sent_at", - "property_type": "String" - }, - { - "name": "$session_id", - "property_type": "String" - }, - { - "name": "$session_recording_canvas_recording", - "property_type": null - }, - { - "name": "$session_recording_network_payload_capture", - "property_type": null - }, - { - "name": "$session_recording_start_reason", - "property_type": "String" - }, - { - "name": "$survey_id", - "property_type": "String" - }, - { - "name": "$survey_iteration", - "property_type": null - }, - { - "name": "$survey_iteration_start_date", - "property_type": null - }, - { - "name": "$survey_name", - "property_type": "String" - }, - { - "name": "$survey_questions", - "property_type": null - }, - { - "name": "$survey_response", - "property_type": "String" - }, - { - "name": "$time", - "property_type": "DateTime" - }, - { - "name": "$timezone", - "property_type": "String" - }, - { - "name": "$used_bootstrap_value", - "property_type": "Boolean" - }, - { - "name": "$user_id", - "property_type": "String" - }, - { - "name": "$viewport_height", - "property_type": "Numeric" - }, - { - "name": "$viewport_width", - "property_type": "Numeric" - }, - { - "name": "$web_vitals_CLS_event", - "property_type": null - }, - { - "name": "$web_vitals_CLS_value", - "property_type": "Numeric" - }, - { - "name": "$web_vitals_FCP_event", - "property_type": null - }, - { - "name": "$web_vitals_FCP_value", - "property_type": "Numeric" - }, - { - "name": "$web_vitals_INP_event", - "property_type": null - }, - { - "name": "$web_vitals_INP_value", - "property_type": "Numeric" - }, - { - "name": "$web_vitals_LCP_event", - "property_type": null - }, - { - "name": "$web_vitals_LCP_value", - "property_type": "Numeric" - }, - { - "name": "$web_vitals_allowed_metrics", - "property_type": null - }, - { - "name": "$web_vitals_enabled_server_side", - "property_type": "Boolean" - }, - { - "name": "$window_id", - "property_type": "String" - }, - { - "name": "action", - "property_type": "String" - }, - { - "name": "action_entity_count", - "property_type": "Numeric" - }, - { - "name": "aggregating_by_groups", - "property_type": "Boolean" - }, - { - "name": "api_response_bytes", - "property_type": "Numeric" - }, - { - "name": "automatic", - "property_type": "Boolean" - }, - { - "name": "blob_key", - "property_type": "String" - }, - { - "name": "buffer_time_ms", - "property_type": "DateTime" - }, - { - "name": "clickhouse_sql", - "property_type": "String" - } - ] + Full list of available properties and their definitions: + {json.dumps(CORE_FILTER_DEFINITIONS_BY_GROUP, indent=2)} - Events: - ["notebook node added", "$groupidentify", "recording list properties fetched", "definition hovered", "session recording snapshots v2 loaded", "recording analyzed", "$set", "session recording had unparseable lines", "viewed dashboard", "v2 session recording snapshots viewed", "recording list fetched", "should view onboarding product intro", "recording viewed", "recording loaded", "$web_vitals", "$pageview", "$autocapture", "$opt_in", "update user properties", "$feature_flag_called", "query completed", "timezone component viewed", "$pageleave", "recording list filters changed", "recording viewed with no playtime summary", "$rageclick", "recording next recording triggered", "session_recording_opt_in team setting updated", "recording viewed summary", "dashboard refreshed", "sidebar closed", "time to see data", "pay gate shown", "dashboard loading time", "survey viewed", "survey sent", "survey shown", "survey edited", "feature flag updated", "survey launched", "survey created", "sidebar opened", "insight analyzed", "insight viewed", "insight created", "stuck session player skipped forward", "feature flag created", "capture_console_log_opt_in team setting updated", "query failed", "element resized", "recording_has_no_full_snapshot", "recording cannot playback yet", "survey template clicked", "$copy_autocapture", "user updated", "cohort created", "client_request_failure", "recording_snapshots_v2_empty_response", "recording player speed changed", "recording player skip inactivity toggled", "demo warning dismissed", "user logged in", "reauthentication_modal_shown", "reauthentication_completed", "product cross sell interaction", "insight timeout message shown", "recording playlist created", "billing v2 shown", "billing CTA shown", "$identify", "autocapture_opt_out team setting updated", "product onboarding completed", "event definitions page load succeeded", "capture_performance_opt_in team setting updated", "notebook content changed", "autocapture_web_vitals_opt_in team setting updated", "heatmaps_opt_in team setting updated", "has_completed_onboarding_for team setting updated"] + Campaign properties: + {json.dumps(CAMPAIGN_PROPERTIES, indent=2)} """