frontend/src/scenes/max/README.md
Scene logics can expose a maxContext selector to provide relevant context to MaxAI.
To do so:
Import the necessary types and helpers:
import { MaxContextInput, createMaxContextHelpers } from 'scenes/max/maxTypes'
Add a maxContext selector that returns MaxContextInput[]:
selectors({
maxContext: [
(s) => [s.dashboard],
(dashboard): MaxContextInput[] => {
if (!dashboard) {
return []
}
return [createMaxContextHelpers.dashboard(dashboard)]
},
],
})
For multiple context items:
maxContext: [
(s) => [s.insight, s.events],
(insight, events): MaxContextInput[] => {
const context = []
if (insight) context.push(createMaxContextHelpers.insight(insight))
if (events?.length) context.push(...events.map(createMaxContextHelpers.event))
return context
},
]
The maxContextLogic will automatically detect and process these context items. Use the helper functions to ensure type safety and consistency.
Currently, these context entities are supported:
If you want to add new entities, you need to extend maxContextLogic.ts. Follow the established pattern:
maxTypes.ts// Add a new context type enum value
export enum MaxContextType {
// ... existing types
MY_ENTITY = 'my_entity',
}
// Add context interface (what gets sent to backend)
export interface MaxMyEntityContext {
type: MaxContextType.MY_ENTITY
id: string
name?: string | null
}
// Add context input type (what scene logics return)
type MaxMyEntityContextInput = {
type: MaxContextType.MY_ENTITY
data: { id: string; name?: string | null }
}
// Add to the union types
export type MaxContextItem /* existing types */ = MaxMyEntityContext
export type MaxContextInput /* existing types */ = MaxMyEntityContextInput
// Add helper function
export const createMaxContextHelpers = {
// ... existing helpers
myEntity: (entity: { id: string; name?: string | null }): MaxMyEntityContextInput => ({
type: MaxContextType.MY_ENTITY,
data: entity,
}),
}
maxContextLogic.tsactions({
// ... existing actions
addOrUpdateContextMyEntity: (data: { id: string; name?: string | null }) => ({ data }),
removeContextMyEntity: (id: string) => ({ id }),
}),
reducers({
// ... existing reducers
contextMyEntities: [
[] as MaxMyEntityContext[],
{
addOrUpdateContextMyEntity: (state, { data }) =>
addOrUpdateEntity(state, {
type: MaxContextType.MY_ENTITY,
id: data.id,
name: data.name,
}),
removeContextMyEntity: (state, { id }) => removeEntity(state, id),
resetContext: () => [],
},
],
}),
handleTaxonomicFilterChange// For direct selection from taxonomic filter
if (groupType === TaxonomicFilterGroupType.MyEntities) {
actions.addOrUpdateContextMyEntity(item as { id: string; name?: string })
return
}
// For selection from MaxAIContext (scene context items)
if (_item.type === MaxContextType.MY_ENTITY) {
actions.addOrUpdateContextMyEntity({
id: _item.value as string,
name: _item.name ?? null,
})
return null
}
sceneContext selectorcase MaxContextType.MY_ENTITY:
return {
type: MaxContextType.MY_ENTITY,
id: item.data.id,
name: item.data.name,
} as MaxMyEntityContext
contextOptions selector (for dropdown display)} else if (item.type == MaxContextType.MY_ENTITY) {
options.push({
id: item.id,
name: item.name || `Entity ${item.id}`,
value: item.id,
type: MaxContextType.MY_ENTITY,
icon: IconMyEntity,
})
}
taxonomicGroupTypes selectorgroupTypes.push(
// ... existing types
TaxonomicFilterGroupType.MyEntities
)
compiledContext selector// Add to selector dependencies
(s: any) => [/* existing deps */, s.contextMyEntities, s.sceneContext],
// Combine manual selections with auto-added scene context
const sceneMyEntities = sceneContext.filter(
(item): item is MaxMyEntityContext => item.type === MaxContextType.MY_ENTITY
)
const allMyEntities = [...contextMyEntities, ...sceneMyEntities]
if (allMyEntities.length > 0) {
const uniqueEntities = new Map<string, MaxMyEntityContext>()
allMyEntities.forEach((e) => uniqueEntities.set(e.id, e))
context.my_entities = Array.from(uniqueEntities.values())
}
hasData selectorInclude contextMyEntities in the array of states checked for data.
maxContext selector → auto-added to contextcompiledContextcontextOptions dropdown for user visibility/selectionCaveat: we currently support these types of insights: trends, funnels, retention, custom SQL. This means that if you expose a dashboard with custom queries, these will show up in the frontend logic, but won't be actually available to Max in the backend.
To add support for reading custom queries, refer to the README in ee/hogai
To add support for generating insights with custom queries, talk to the Max AI team