drizzle-cube 0.4.21 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/charts.js +12 -12
- package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js → RetentionCombinedChart-BK3NPsHP.js} +2 -2
- package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js.map → RetentionCombinedChart-BK3NPsHP.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-3z9fHE2F.js → analysis-builder-DVrv9Q4n.js} +9 -9
- package/dist/client/chunks/{analysis-builder-3z9fHE2F.js.map → analysis-builder-DVrv9Q4n.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js → analysis-builder-shared-CrENEvEk.js} +6 -6
- package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js.map → analysis-builder-shared-CrENEvEk.js.map} +1 -1
- package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js → chart-activity-grid-OG6he4YS.js} +2 -2
- package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js.map → chart-activity-grid-OG6he4YS.js.map} +1 -1
- package/dist/client/chunks/{chart-area-ByJQ7NZd.js → chart-area-TawAd2k9.js} +3 -3
- package/dist/client/chunks/{chart-area-ByJQ7NZd.js.map → chart-area-TawAd2k9.js.map} +1 -1
- package/dist/client/chunks/{chart-bar-dj14frMt.js → chart-bar-D3vtCNQG.js} +2 -2
- package/dist/client/chunks/{chart-bar-dj14frMt.js.map → chart-bar-D3vtCNQG.js.map} +1 -1
- package/dist/client/chunks/{chart-box-plot-ZatBpatq.js → chart-box-plot-BXwN2rO5.js} +2 -2
- package/dist/client/chunks/{chart-box-plot-ZatBpatq.js.map → chart-box-plot-BXwN2rO5.js.map} +1 -1
- package/dist/client/chunks/{chart-bubble-CemotLx-.js → chart-bubble-ZfNe8t5k.js} +2 -2
- package/dist/client/chunks/{chart-bubble-CemotLx-.js.map → chart-bubble-ZfNe8t5k.js.map} +1 -1
- package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js → chart-candlestick-DmF3haFu.js} +2 -2
- package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js.map → chart-candlestick-DmF3haFu.js.map} +1 -1
- package/dist/client/chunks/{chart-data-table-BsAjHe7o.js → chart-data-table-DJZPkArt.js} +4 -4
- package/dist/client/chunks/{chart-data-table-BsAjHe7o.js.map → chart-data-table-DJZPkArt.js.map} +1 -1
- package/dist/client/chunks/{chart-funnel-dofnhD24.js → chart-funnel-CE9x0Io9.js} +2 -2
- package/dist/client/chunks/{chart-funnel-dofnhD24.js.map → chart-funnel-CE9x0Io9.js.map} +1 -1
- package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js → chart-gauge-Djs5FWxB.js} +2 -2
- package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js.map → chart-gauge-Djs5FWxB.js.map} +1 -1
- package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js → chart-heat-map-CqtMkdxd.js} +2 -2
- package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js.map → chart-heat-map-CqtMkdxd.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js → chart-kpi-delta-DEzA74cL.js} +4 -4
- package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js.map → chart-kpi-delta-DEzA74cL.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js → chart-kpi-number-Bab-BZtX.js} +3 -3
- package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js.map → chart-kpi-number-Bab-BZtX.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js → chart-kpi-text-BkTgckDJ.js} +3 -3
- package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js.map → chart-kpi-text-BkTgckDJ.js.map} +1 -1
- package/dist/client/chunks/{chart-line-DzyZkugh.js → chart-line-DhM-Hvu0.js} +3 -3
- package/dist/client/chunks/{chart-line-DzyZkugh.js.map → chart-line-DhM-Hvu0.js.map} +1 -1
- package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js → chart-measure-profile-4vQxFm69.js} +3 -3
- package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js.map → chart-measure-profile-4vQxFm69.js.map} +1 -1
- package/dist/client/chunks/{chart-pie-akbfRfb9.js → chart-pie-B86KRcHI.js} +2 -2
- package/dist/client/chunks/{chart-pie-akbfRfb9.js.map → chart-pie-B86KRcHI.js.map} +1 -1
- package/dist/client/chunks/{chart-radar-BaN-Kjww.js → chart-radar-BhDBmJRh.js} +2 -2
- package/dist/client/chunks/{chart-radar-BaN-Kjww.js.map → chart-radar-BhDBmJRh.js.map} +1 -1
- package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js → chart-radial-bar-Brugya8X.js} +2 -2
- package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js.map → chart-radial-bar-Brugya8X.js.map} +1 -1
- package/dist/client/chunks/{chart-sankey-CG-3hHmX.js → chart-sankey-D2L8ympI.js} +2 -2
- package/dist/client/chunks/{chart-sankey-CG-3hHmX.js.map → chart-sankey-D2L8ympI.js.map} +1 -1
- package/dist/client/chunks/{chart-scatter-l_yTVxF3.js → chart-scatter-CAkbBDkK.js} +2 -2
- package/dist/client/chunks/{chart-scatter-l_yTVxF3.js.map → chart-scatter-CAkbBDkK.js.map} +1 -1
- package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js → chart-sunburst-DaxJ-cob.js} +2 -2
- package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js.map → chart-sunburst-DaxJ-cob.js.map} +1 -1
- package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js → chart-tree-map-CrDJAvZU.js} +2 -2
- package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js.map → chart-tree-map-CrDJAvZU.js.map} +1 -1
- package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js → chart-waterfall-BBwSfEKT.js} +3 -3
- package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js.map → chart-waterfall-BBwSfEKT.js.map} +1 -1
- package/dist/client/chunks/{charts-core-CU9u_HtL.js → charts-core-B4Rbfdcn.js} +2 -2
- package/dist/client/chunks/{charts-core-CU9u_HtL.js.map → charts-core-B4Rbfdcn.js.map} +1 -1
- package/dist/client/chunks/{charts-loader-B3tt5oKG.js → charts-loader-DbrwgvCK.js} +25 -25
- package/dist/client/chunks/{charts-loader-B3tt5oKG.js.map → charts-loader-DbrwgvCK.js.map} +1 -1
- package/dist/client/chunks/{components-CMGGxqOB.js → components-GzooQM5J.js} +9 -9
- package/dist/client/chunks/{components-CMGGxqOB.js.map → components-GzooQM5J.js.map} +1 -1
- package/dist/client/chunks/{core-D_8mkGpQ.js → core-Y9e-sNfb.js} +2 -2
- package/dist/client/chunks/{core-D_8mkGpQ.js.map → core-Y9e-sNfb.js.map} +1 -1
- package/dist/client/chunks/{icons-M7shurcH.js → icons-DFJw-2HU.js} +6 -6
- package/dist/client/chunks/{icons-M7shurcH.js.map → icons-DFJw-2HU.js.map} +1 -1
- package/dist/client/chunks/{providers-CgxXm6Ll.js → providers-CCw8Kjlc.js} +2 -2
- package/dist/client/chunks/{providers-CgxXm6Ll.js.map → providers-CCw8Kjlc.js.map} +1 -1
- package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js → syntaxHighlighting-DAMSW_A6.js} +2 -2
- package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js.map → syntaxHighlighting-DAMSW_A6.js.map} +1 -1
- package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js → useDirtyStateTracking-CjhwBXRw.js} +20 -20
- package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js.map → useDirtyStateTracking-CjhwBXRw.js.map} +1 -1
- package/dist/client/chunks/useExplainAI-IiW55BaQ.js +182 -0
- package/dist/client/chunks/useExplainAI-IiW55BaQ.js.map +1 -0
- package/dist/client/chunks/{vendor-AVsJ2ni0.js → vendor-B2EH3V58.js} +7 -7
- package/dist/client/chunks/{vendor-AVsJ2ni0.js.map → vendor-B2EH3V58.js.map} +1 -1
- package/dist/client/components.js +1 -1
- package/dist/client/hooks/useNotebookLayout.d.ts +8 -0
- package/dist/client/hooks.d.ts +2 -0
- package/dist/client/hooks.js +51 -190
- package/dist/client/hooks.js.map +1 -1
- package/dist/client/icons.js +1 -1
- package/dist/client/index.js +871 -742
- package/dist/client/index.js.map +1 -1
- package/dist/client/providers.js +1 -1
- package/dist/client/styles.css +1 -1
- package/dist/client/utils.js +7 -7
- package/dist/client-bundle-stats.html +1 -1
- package/package.json +1 -1
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/client/stores/notebookStore.tsx","../../src/client/components/AgenticNotebook/NotebookPortletBlock.tsx","../../src/client/components/AgenticNotebook/NotebookMarkdownBlock.tsx","../../src/client/components/AgenticNotebook/NotebookCanvas.tsx","../../src/client/hooks/useAgentChat.ts","../../src/client/components/AgenticNotebook/ChatMessage.tsx","../../src/client/components/AgenticNotebook/ChatInput.tsx","../../src/client/components/AgenticNotebook/AgentChatPanel.tsx","../../src/client/components/AgenticNotebook/index.tsx","../../src/client/components/AnalyticsPage.tsx","../../src/client/components/DashboardThumbnailPlaceholder.tsx"],"sourcesContent":["/**\n * Notebook Zustand Store (Instance-based)\n *\n * State management for the AgenticNotebook component, consolidating:\n * - Notebook blocks (portlets + markdown)\n * - Chat messages\n * - Session state\n * - UI state\n *\n * KEY ARCHITECTURE: Instance-based stores\n * - Each AgenticNotebook gets its own store instance via Context\n * - No server state (data fetching is handled by portlets via TanStack Query)\n * - State is per-notebook session\n *\n * Uses Zustand's createStore (factory) instead of create (singleton).\n * Store is provided via React Context.\n */\n\nimport { createContext, useContext, useRef, type ReactNode } from 'react'\nimport { createStore, useStore, type StoreApi } from 'zustand'\nimport { devtools, subscribeWithSelector } from 'zustand/middleware'\nimport type {\n ChartType,\n ChartAxisConfig,\n ChartDisplayConfig,\n} from '../types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A portlet block in the notebook\n */\nexport interface PortletBlock {\n id: string\n type: 'portlet'\n title: string\n query: string\n chartType: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n}\n\n/**\n * A markdown text block in the notebook\n */\nexport interface MarkdownBlock {\n id: string\n type: 'markdown'\n title?: string\n content: string\n}\n\n/**\n * A block in the notebook canvas\n */\nexport type NotebookBlock = PortletBlock | MarkdownBlock\n\n/**\n * A tool call record for display in chat messages\n */\nexport interface ToolCallRecord {\n id: string\n name: string\n input?: unknown\n result?: unknown\n status: 'running' | 'complete' | 'error'\n}\n\n/**\n * A chat message\n */\nexport interface ChatMessage {\n id: string\n role: 'user' | 'assistant'\n content: string\n error?: string\n toolCalls?: ToolCallRecord[]\n timestamp: number\n}\n\n/**\n * Serializable notebook config for save/load\n */\nexport interface NotebookConfig {\n blocks: NotebookBlock[]\n messages: ChatMessage[]\n}\n\n// ============================================================================\n// Store State\n// ============================================================================\n\nexport interface NotebookStoreState {\n /** Ordered array of notebook blocks */\n blocks: NotebookBlock[]\n\n /** Chat message history */\n messages: ChatMessage[]\n\n /** Whether the agent is currently streaming a response */\n isStreaming: boolean\n\n /** Agent SDK session ID for multi-turn conversations */\n sessionId: string | null\n\n /** Chat input value */\n inputValue: string\n}\n\n// ============================================================================\n// Store Actions\n// ============================================================================\n\nexport interface NotebookStoreActions {\n // Block actions\n addBlock: (block: NotebookBlock) => void\n removeBlock: (id: string) => void\n moveBlock: (id: string, direction: 'up' | 'down') => void\n updateBlock: (id: string, updates: Partial<Omit<PortletBlock, 'id' | 'type'>>) => void\n\n // Chat actions\n addMessage: (message: ChatMessage) => void\n appendToLastAssistantMessage: (text: string) => void\n setLastAssistantError: (error: string) => void\n addToolCallToLastAssistant: (toolCall: ToolCallRecord) => void\n updateLastToolCall: (update: Partial<ToolCallRecord>) => void\n\n // Session/UI actions\n setIsStreaming: (streaming: boolean) => void\n setSessionId: (id: string | null) => void\n setInputValue: (value: string) => void\n\n // Persistence\n save: () => NotebookConfig\n load: (config: NotebookConfig) => void\n\n // Reset\n reset: () => void\n}\n\n/**\n * Combined store type\n */\nexport type NotebookStore = NotebookStoreState & NotebookStoreActions\n\n// ============================================================================\n// Initial State\n// ============================================================================\n\nconst createDefaultState = (): NotebookStoreState => ({\n blocks: [],\n messages: [],\n isStreaming: false,\n sessionId: null,\n inputValue: '',\n})\n\n// ============================================================================\n// Store Factory\n// ============================================================================\n\nfunction createStoreActions(\n set: (\n partial:\n | Partial<NotebookStore>\n | ((state: NotebookStore) => Partial<NotebookStore>)\n ) => void,\n get: () => NotebookStore\n): NotebookStoreActions {\n return {\n // Block actions\n addBlock: (block) =>\n set((state) => ({\n blocks: [...state.blocks, block],\n })),\n\n removeBlock: (id) =>\n set((state) => ({\n blocks: state.blocks.filter((b) => b.id !== id),\n })),\n\n moveBlock: (id, direction) =>\n set((state) => {\n const idx = state.blocks.findIndex((b) => b.id === id)\n if (idx === -1) return {}\n if (direction === 'up' && idx === 0) return {}\n if (direction === 'down' && idx === state.blocks.length - 1) return {}\n\n const newBlocks = [...state.blocks]\n const swapIdx = direction === 'up' ? idx - 1 : idx + 1\n ;[newBlocks[idx], newBlocks[swapIdx]] = [newBlocks[swapIdx], newBlocks[idx]]\n return { blocks: newBlocks }\n }),\n\n updateBlock: (id, updates) =>\n set((state) => ({\n blocks: state.blocks.map((b) =>\n b.id === id && b.type === 'portlet' ? { ...b, ...updates } : b\n ),\n })),\n\n // Chat actions\n addMessage: (message) =>\n set((state) => ({\n messages: [...state.messages, message],\n })),\n\n appendToLastAssistantMessage: (text) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = {\n ...lastMsg,\n content: lastMsg.content + text,\n }\n }\n return { messages }\n }),\n\n setLastAssistantError: (error) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = { ...lastMsg, error }\n }\n return { messages }\n }),\n\n addToolCallToLastAssistant: (toolCall) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = {\n ...lastMsg,\n toolCalls: [...(lastMsg.toolCalls || []), toolCall],\n }\n }\n return { messages }\n }),\n\n updateLastToolCall: (update) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg?.role === 'assistant' && lastMsg.toolCalls?.length) {\n const toolCalls = [...lastMsg.toolCalls]\n // Find by ID if provided, otherwise fall back to last\n const idx = update.id\n ? toolCalls.findIndex((tc) => tc.id === update.id)\n : toolCalls.length - 1\n if (idx !== -1) {\n toolCalls[idx] = { ...toolCalls[idx], ...update }\n messages[messages.length - 1] = { ...lastMsg, toolCalls }\n }\n }\n return { messages }\n }),\n\n // Session/UI actions\n setIsStreaming: (streaming) => set({ isStreaming: streaming }),\n setSessionId: (id) => set({ sessionId: id }),\n setInputValue: (value) => set({ inputValue: value }),\n\n // Persistence\n save: () => {\n const state = get()\n return {\n blocks: state.blocks,\n messages: state.messages,\n }\n },\n\n load: (config) =>\n set({\n blocks: config.blocks || [],\n messages: config.messages || [],\n }),\n\n // Reset\n reset: () => set(createDefaultState()),\n }\n}\n\n/**\n * Create a new notebook store instance\n */\nexport function createNotebookStore() {\n const initialState = createDefaultState()\n\n return createStore<NotebookStore>()(\n devtools(\n subscribeWithSelector((set, get) => ({\n ...initialState,\n ...createStoreActions(set, get),\n })),\n { name: 'NotebookStore' }\n )\n )\n}\n\n// ============================================================================\n// React Context & Provider\n// ============================================================================\n\nconst NotebookStoreContext = createContext<StoreApi<NotebookStore> | null>(null)\n\nexport interface NotebookStoreProviderProps {\n children: ReactNode\n /** Initial config to load */\n initialConfig?: NotebookConfig\n}\n\n/**\n * Provider component that creates a store instance per AgenticNotebook\n */\nexport function NotebookStoreProvider({\n children,\n initialConfig,\n}: NotebookStoreProviderProps) {\n const storeRef = useRef<StoreApi<NotebookStore> | null>(null)\n\n if (!storeRef.current) {\n const store = createNotebookStore()\n if (initialConfig) {\n store.getState().load(initialConfig)\n }\n storeRef.current = store\n }\n\n return (\n <NotebookStoreContext.Provider value={storeRef.current}>\n {children}\n </NotebookStoreContext.Provider>\n )\n}\n\n/**\n * Hook to access the notebook store from context\n * @throws Error if used outside of provider\n */\nexport function useNotebookStore<T>(selector: (state: NotebookStore) => T): T {\n const store = useContext(NotebookStoreContext)\n if (!store) {\n throw new Error('useNotebookStore must be used within NotebookStoreProvider')\n }\n return useStore(store, selector)\n}\n\n// ============================================================================\n// Selectors\n// ============================================================================\n\nexport const selectBlocks = (state: NotebookStore) => state.blocks\nexport const selectMessages = (state: NotebookStore) => state.messages\nexport const selectIsStreaming = (state: NotebookStore) => state.isStreaming\nexport const selectSessionId = (state: NotebookStore) => state.sessionId\nexport const selectInputValue = (state: NotebookStore) => state.inputValue\n\nexport const selectChatState = (state: NotebookStore) => ({\n messages: state.messages,\n isStreaming: state.isStreaming,\n inputValue: state.inputValue,\n})\n\nexport const selectChatActions = (state: NotebookStore) => ({\n addMessage: state.addMessage,\n appendToLastAssistantMessage: state.appendToLastAssistantMessage,\n setLastAssistantError: state.setLastAssistantError,\n addToolCallToLastAssistant: state.addToolCallToLastAssistant,\n updateLastToolCall: state.updateLastToolCall,\n setIsStreaming: state.setIsStreaming,\n setInputValue: state.setInputValue,\n setSessionId: state.setSessionId,\n})\n\nexport const selectBlockActions = (state: NotebookStore) => ({\n addBlock: state.addBlock,\n removeBlock: state.removeBlock,\n moveBlock: state.moveBlock,\n updateBlock: state.updateBlock,\n})\n","/**\n * NotebookPortletBlock - Wraps AnalyticsPortlet for notebook display\n *\n * Uses the same header pattern as DashboardPortletCard for consistency:\n * - Title on the left with DebugModal inline\n * - Action buttons on the right (move, edit, delete)\n */\n\nimport React, { useState, useCallback } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { PortletBlock } from '../../stores/notebookStore'\nimport type { ChartAxisConfig, ChartDisplayConfig, ChartType } from '../../types'\nimport type { FlowChartData } from '../../types/flow'\nimport type { RetentionChartData } from '../../types/retention'\nimport { getIcon } from '../../icons/registry'\nimport AnalyticsPortlet from '../AnalyticsPortlet'\nimport DebugModal from '../DebugModal'\n\nconst ICON_STYLE: CSSProperties = { width: '16px', height: '16px', color: 'currentColor' }\n\ninterface DebugData {\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n queryObject: unknown\n data: unknown[] | FlowChartData | RetentionChartData\n chartType: ChartType\n cacheInfo?: { hit: true; cachedAt: string; ttlMs: number; ttlRemainingMs: number } | null\n drillState?: unknown\n}\n\ninterface NotebookPortletBlockProps {\n block: PortletBlock\n onRemove: (id: string) => void\n onMoveUp: (id: string) => void\n onMoveDown: (id: string) => void\n onEdit: (block: PortletBlock) => void\n isFirst: boolean\n isLast: boolean\n}\n\nconst ChevronUpIcon = getIcon('chevronUp')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst EditIcon = getIcon('edit')\nconst DeleteIcon = getIcon('delete')\n\nconst NotebookPortletBlock = React.memo(function NotebookPortletBlock({\n block,\n onRemove,\n onMoveUp,\n onMoveDown,\n onEdit,\n isFirst,\n isLast,\n}: NotebookPortletBlockProps) {\n const [debugData, setDebugData] = useState<DebugData | null>(null)\n\n const handleDebugDataReady = useCallback((data: DebugData) => {\n setDebugData(data)\n }, [])\n\n return (\n <div className=\"dc:relative dc:mb-4 bg-dc-surface dc:border border-dc-border dc:rounded-lg dc:flex dc:flex-col\">\n {/* Header - same pattern as DashboardPortletCard */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-3 dc:py-1.5 dc:border-b border-dc-border dc:shrink-0 bg-dc-surface-secondary dc:rounded-t-lg\">\n <div className=\"dc:flex dc:items-center dc:gap-2 dc:flex-1 dc:min-w-0\">\n <h3 className=\"dc:font-semibold dc:text-sm text-dc-text dc:truncate\">\n {block.title || 'Untitled'}\n </h3>\n {debugData && (\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n cacheInfo={debugData.cacheInfo ?? undefined}\n />\n )}\n </div>\n <div className=\"dc:flex dc:items-center dc:gap-1 dc:shrink-0 dc:ml-4 dc:-mr-2\">\n {!isFirst && (\n <button\n onClick={() => onMoveUp(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move up\"\n >\n <ChevronUpIcon style={ICON_STYLE} />\n </button>\n )}\n {!isLast && (\n <button\n onClick={() => onMoveDown(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move down\"\n >\n <ChevronDownIcon style={ICON_STYLE} />\n </button>\n )}\n <button\n onClick={() => onEdit(block)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Edit visualization\"\n >\n <EditIcon style={ICON_STYLE} />\n </button>\n <button\n onClick={() => onRemove(block.id)}\n className=\"dc:p-1 dc:mr-0.5 dc:bg-transparent dc:border-none dc:rounded-sm dc:cursor-pointer dc:hover:bg-dc-danger-bg text-dc-danger dc:transition-colors\"\n title=\"Remove\"\n >\n <DeleteIcon style={ICON_STYLE} />\n </button>\n </div>\n </div>\n\n {/* Portlet body */}\n <div className=\"dc:flex-1 dc:min-h-0\">\n <AnalyticsPortlet\n query={block.query}\n chartType={block.chartType}\n chartConfig={block.chartConfig}\n displayConfig={block.displayConfig}\n height={400}\n eagerLoad={true}\n onDebugDataReady={handleDebugDataReady}\n />\n </div>\n </div>\n )\n})\n\nexport default NotebookPortletBlock\n","/**\n * NotebookMarkdownBlock - Renders a markdown text block in the notebook\n * Uses markdown-to-jsx for full GFM support including tables\n *\n * Header matches NotebookPortletBlock pattern for visual consistency.\n */\n\nimport React from 'react'\nimport type { CSSProperties } from 'react'\nimport Markdown from 'markdown-to-jsx'\nimport type { MarkdownBlock } from '../../stores/notebookStore'\nimport { getIcon } from '../../icons/registry'\n\nconst ICON_STYLE: CSSProperties = { width: '16px', height: '16px', color: 'currentColor' }\n\nconst DocumentTextIcon = getIcon('documentText')\nconst ChevronUpIcon = getIcon('chevronUp')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst DeleteIcon = getIcon('delete')\n\ninterface NotebookMarkdownBlockProps {\n block: MarkdownBlock\n onRemove: (id: string) => void\n onMoveUp: (id: string) => void\n onMoveDown: (id: string) => void\n isFirst: boolean\n isLast: boolean\n}\n\n/** markdown-to-jsx options with dc: themed overrides */\nconst markdownOptions = {\n overrides: {\n h1: { props: { className: 'dc:text-lg dc:font-bold text-dc-text dc:mb-2 dc:mt-3' } },\n h2: { props: { className: 'dc:text-base dc:font-semibold text-dc-text dc:mb-2 dc:mt-3' } },\n h3: { props: { className: 'dc:text-sm dc:font-semibold text-dc-text dc:mb-2 dc:mt-3' } },\n p: { props: { className: 'dc:text-sm dc:leading-relaxed text-dc-text dc:mb-2' } },\n strong: { props: { className: 'dc:font-semibold' } },\n a: { props: { className: 'text-dc-accent dc:hover:underline', target: '_blank', rel: 'noopener noreferrer' } },\n code: { props: { className: 'dc:px-1 dc:py-0.5 dc:rounded dc:text-xs bg-dc-surface-secondary text-dc-accent dc:font-mono' } },\n pre: { props: { className: 'dc:rounded-lg dc:p-3 dc:my-2 dc:overflow-x-auto dc:text-xs bg-dc-surface-secondary text-dc-text dc:font-mono' } },\n ul: { props: { className: 'dc:list-disc dc:ml-5 dc:mb-2 dc:text-sm text-dc-text dc:space-y-1' } },\n ol: { props: { className: 'dc:list-decimal dc:ml-5 dc:mb-2 dc:text-sm text-dc-text dc:space-y-1' } },\n li: { props: { className: 'dc:text-sm text-dc-text' } },\n hr: { props: { className: 'dc:my-3 border-dc-border' } },\n blockquote: { props: { className: 'dc:border-l-4 border-dc-accent dc:pl-3 dc:my-2 dc:italic text-dc-text-secondary dc:text-sm' } },\n table: { props: { className: 'dc:w-full dc:border-collapse dc:my-2 dc:text-sm' } },\n thead: { props: { className: 'bg-dc-surface-secondary' } },\n th: { props: { className: 'dc:px-3 dc:py-2 dc:text-left dc:font-semibold dc:text-xs text-dc-text-secondary dc:uppercase dc:tracking-wider border-dc-border dc:border-b' } },\n td: { props: { className: 'dc:px-3 dc:py-2 dc:text-sm text-dc-text border-dc-border dc:border-b' } },\n tr: { props: { className: 'dc:hover:opacity-80' } },\n },\n}\n\nconst NotebookMarkdownBlock = React.memo(function NotebookMarkdownBlock({\n block,\n onRemove,\n onMoveUp,\n onMoveDown,\n isFirst,\n isLast,\n}: NotebookMarkdownBlockProps) {\n return (\n <div className=\"dc:relative dc:mb-4 bg-dc-surface dc:border border-dc-border dc:rounded-lg dc:flex dc:flex-col\">\n {/* Header - same pattern as NotebookPortletBlock / DashboardPortletCard */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-3 dc:py-1.5 dc:border-b border-dc-border dc:shrink-0 bg-dc-surface-secondary dc:rounded-t-lg\">\n <div className=\"dc:flex dc:items-center dc:gap-2 dc:flex-1 dc:min-w-0\">\n <DocumentTextIcon style={ICON_STYLE} />\n <h3 className=\"dc:font-semibold dc:text-sm text-dc-text dc:truncate\">\n {block.title || 'Markdown'}\n </h3>\n </div>\n <div className=\"dc:flex dc:items-center dc:gap-1 dc:shrink-0 dc:ml-4 dc:-mr-2\">\n {!isFirst && (\n <button\n onClick={() => onMoveUp(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move up\"\n >\n <ChevronUpIcon style={ICON_STYLE} />\n </button>\n )}\n {!isLast && (\n <button\n onClick={() => onMoveDown(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move down\"\n >\n <ChevronDownIcon style={ICON_STYLE} />\n </button>\n )}\n <button\n onClick={() => onRemove(block.id)}\n className=\"dc:p-1 dc:mr-0.5 dc:bg-transparent dc:border-none dc:rounded-sm dc:cursor-pointer dc:hover:bg-dc-danger-bg text-dc-danger dc:transition-colors\"\n title=\"Remove\"\n >\n <DeleteIcon style={ICON_STYLE} />\n </button>\n </div>\n </div>\n\n {/* Markdown content */}\n <div className=\"dc:p-4\">\n <Markdown options={markdownOptions}>\n {block.content}\n </Markdown>\n </div>\n </div>\n )\n})\n\nexport default NotebookMarkdownBlock\n","/**\n * NotebookCanvas - Left panel displaying notebook blocks\n */\n\nimport React, { useCallback, useRef, useEffect, useState } from 'react'\nimport { useShallow } from 'zustand/react/shallow'\nimport { useNotebookStore, selectBlocks, selectBlockActions } from '../../stores/notebookStore'\nimport type { PortletBlock } from '../../stores/notebookStore'\nimport type { PortletConfig } from '../../types'\nimport { ensureAnalysisConfig } from '../../utils/configMigration'\nimport NotebookPortletBlock from './NotebookPortletBlock'\nimport NotebookMarkdownBlock from './NotebookMarkdownBlock'\nimport PortletAnalysisModal from '../PortletAnalysisModal'\n\nconst NotebookCanvas = React.memo(function NotebookCanvas() {\n const blocks = useNotebookStore(selectBlocks)\n const { removeBlock, moveBlock, updateBlock } = useNotebookStore(useShallow(selectBlockActions))\n const endRef = useRef<HTMLDivElement>(null)\n\n // Edit modal state\n const [editingBlock, setEditingBlock] = useState<PortletBlock | null>(null)\n\n // Auto-scroll only when NEW blocks are added (not on initial load)\n const prevCountRef = useRef(blocks.length)\n useEffect(() => {\n if (blocks.length > prevCountRef.current) {\n endRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n prevCountRef.current = blocks.length\n }, [blocks.length])\n\n const handleRemove = useCallback((id: string) => removeBlock(id), [removeBlock])\n const handleMoveUp = useCallback((id: string) => moveBlock(id, 'up'), [moveBlock])\n const handleMoveDown = useCallback((id: string) => moveBlock(id, 'down'), [moveBlock])\n const handleEdit = useCallback((block: PortletBlock) => setEditingBlock(block), [])\n\n const handleEditSave = useCallback((portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => {\n if (!editingBlock) return\n\n // Normalize to ensure analysisConfig exists\n const normalized = ensureAnalysisConfig(portletData as PortletConfig)\n const { analysisConfig } = normalized\n\n if (analysisConfig) {\n const chartModeConfig = analysisConfig.charts[analysisConfig.analysisType]\n updateBlock(editingBlock.id, {\n title: portletData.title,\n query: JSON.stringify(analysisConfig.query),\n chartType: chartModeConfig?.chartType || 'bar',\n chartConfig: chartModeConfig?.chartConfig,\n displayConfig: chartModeConfig?.displayConfig,\n })\n }\n\n setEditingBlock(null)\n }, [editingBlock, updateBlock])\n\n if (blocks.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:h-full\">\n <div className=\"dc:text-center dc:max-w-sm dc:px-6\">\n <h3 className=\"dc:text-base dc:font-semibold text-dc-text dc:mb-2\">\n Your notebook is empty\n </h3>\n <p className=\"dc:text-sm text-dc-text-secondary\">\n Ask the AI assistant a question about your data.\n Charts and insights will appear here as the assistant analyzes your data.\n </p>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:h-full dc:overflow-y-auto dc:p-4\">\n {blocks.map((block, index) => {\n const isFirst = index === 0\n const isLast = index === blocks.length - 1\n\n if (block.type === 'portlet') {\n return (\n <NotebookPortletBlock\n key={block.id}\n block={block}\n onRemove={handleRemove}\n onMoveUp={handleMoveUp}\n onMoveDown={handleMoveDown}\n onEdit={handleEdit}\n isFirst={isFirst}\n isLast={isLast}\n />\n )\n }\n\n if (block.type === 'markdown') {\n return (\n <NotebookMarkdownBlock\n key={block.id}\n block={block}\n onRemove={handleRemove}\n onMoveUp={handleMoveUp}\n onMoveDown={handleMoveDown}\n isFirst={isFirst}\n isLast={isLast}\n />\n )\n }\n\n return null\n })}\n <div ref={endRef} />\n\n {/* Edit modal */}\n <PortletAnalysisModal\n isOpen={!!editingBlock}\n onClose={() => setEditingBlock(null)}\n onSave={handleEditSave}\n portlet={editingBlock ? {\n id: editingBlock.id,\n title: editingBlock.title,\n query: editingBlock.query,\n chartType: editingBlock.chartType,\n chartConfig: editingBlock.chartConfig,\n displayConfig: editingBlock.displayConfig,\n w: 5, h: 4, x: 0, y: 0,\n } : null}\n title=\"Edit Visualization\"\n submitText=\"Update\"\n />\n </div>\n )\n})\n\nexport default NotebookCanvas\n","/**\n * useAgentChat Hook\n * SSE streaming hook for the agentic notebook chat interface\n */\n\nimport { useRef, useCallback, useState } from 'react'\nimport { useCubeApi } from '../providers/CubeProvider'\nimport type { PortletBlock, MarkdownBlock } from '../stores/notebookStore'\n\n/** Clean up raw API errors into user-friendly messages */\nfunction formatUserFacingError(message: string): string {\n // Detect raw JSON error payloads (e.g. from Anthropic API)\n if (message.startsWith('{') || message.includes('\"type\":\"error\"')) {\n try {\n const parsed = JSON.parse(message.replace(/^Error:\\s*/, ''))\n const errorType = parsed.error?.type || parsed.type || ''\n const friendly: Record<string, string> = {\n overloaded_error: 'The AI service is temporarily busy. Please try again in a moment.',\n rate_limit_error: 'Too many requests. Please wait a moment and try again.',\n api_error: 'The AI service encountered an error. Please try again.',\n authentication_error: 'Authentication failed. Please check your configuration.',\n }\n return friendly[errorType] || 'The AI service encountered an error. Please try again.'\n } catch {\n return 'The AI service encountered an error. Please try again.'\n }\n }\n // HTTP status errors\n if (message.startsWith('Agent request failed:')) {\n const status = message.match(/\\d+/)?.[0]\n if (status === '429') return 'Too many requests. Please wait a moment and try again.'\n if (status === '503' || status === '529') return 'The AI service is temporarily busy. Please try again in a moment.'\n return 'The AI service is temporarily unavailable. Please try again.'\n }\n return message\n}\n\ninterface AgentSSEEvent {\n type: 'text_delta' | 'tool_use_start' | 'tool_use_result' | 'add_portlet' | 'add_markdown' | 'dashboard_saved' | 'turn_complete' | 'done' | 'error'\n data: any\n}\n\nexport interface UseAgentChatOptions {\n /** Override default agent endpoint (default: apiUrl + '/agent/chat') */\n agentEndpoint?: string\n /** Client-side API key for demo/try-site use */\n agentApiKey?: string\n /** Override LLM provider (anthropic | openai | google) */\n agentProvider?: string\n /** Override LLM model (e.g. 'gpt-4o', 'gemini-2.0-flash') */\n agentModel?: string\n /** Override provider endpoint URL (for OpenAI-compatible services) */\n agentProviderEndpoint?: string\n /** Called when agent adds a portlet to the notebook */\n onAddPortlet: (data: PortletBlock) => void\n /** Called when agent adds a markdown block to the notebook */\n onAddMarkdown: (data: MarkdownBlock) => void\n /** Called when the agent saves a dashboard configuration */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when streaming text arrives */\n onTextDelta: (text: string) => void\n /** Called when a tool call starts */\n onToolStart: (id: string, name: string, input?: unknown) => void\n /** Called when a tool call completes */\n onToolResult: (id: string, name: string, result?: unknown, isError?: boolean) => void\n /** Called when the agent completes with session ID and optional trace ID */\n onDone: (sessionId: string, traceId?: string) => void\n /** Called when a turn completes (between agentic turns) */\n onTurnComplete?: () => void\n /** Called on error */\n onError: (message: string) => void\n}\n\n/** Simplified message format for sending conversation history */\nexport interface AgentHistoryMessage {\n role: 'user' | 'assistant'\n content: string\n toolCalls?: Array<{\n id: string\n name: string\n input?: unknown\n result?: unknown\n status: 'running' | 'complete' | 'error'\n }>\n}\n\nexport interface UseAgentChatResult {\n /** Send a message to the agent, optionally with prior conversation history */\n sendMessage: (content: string, sessionId?: string | null, history?: AgentHistoryMessage[]) => Promise<void>\n /** Whether the agent is currently streaming */\n isStreaming: boolean\n /** Abort the current stream */\n abort: () => void\n}\n\n/**\n * Hook for streaming chat with the agentic notebook backend.\n * Uses fetch() with ReadableStream to consume SSE events.\n */\nexport function useAgentChat(options: UseAgentChatOptions): UseAgentChatResult {\n const { agentEndpoint, agentApiKey, agentProvider, agentModel, agentProviderEndpoint } = options\n\n const { cubeApi } = useCubeApi()\n const abortControllerRef = useRef<AbortController | null>(null)\n const [isStreaming, setIsStreaming] = useState(false)\n\n // Store callbacks in a ref so handleEvent always reads the latest\n // without causing sendMessage to be recreated on every render\n const callbacksRef = useRef(options)\n callbacksRef.current = options\n\n const sendMessage = useCallback(async (content: string, sessionId?: string | null, history?: AgentHistoryMessage[]) => {\n function handleEvent(event: AgentSSEEvent) {\n const cb = callbacksRef.current\n switch (event.type) {\n case 'text_delta':\n cb.onTextDelta(event.data)\n break\n case 'tool_use_start':\n cb.onToolStart(event.data.id, event.data.name, event.data.input)\n break\n case 'tool_use_result':\n cb.onToolResult(event.data.id, event.data.name, event.data.result, event.data.isError)\n break\n case 'add_portlet':\n cb.onAddPortlet({\n ...event.data,\n type: 'portlet',\n })\n break\n case 'add_markdown':\n cb.onAddMarkdown({\n ...event.data,\n type: 'markdown',\n })\n break\n case 'dashboard_saved':\n cb.onDashboardSaved?.(event.data)\n break\n case 'turn_complete':\n cb.onTurnComplete?.()\n break\n case 'done':\n cb.onDone(event.data.sessionId, event.data.traceId)\n break\n case 'error':\n cb.onError(event.data.message)\n break\n }\n }\n\n // Abort any existing stream\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n }\n\n const controller = new AbortController()\n abortControllerRef.current = controller\n setIsStreaming(true)\n\n try {\n // Build endpoint URL from CubeClient's API URL\n const apiUrl = (cubeApi as any).apiUrl || '/cubejs-api/v1'\n const endpoint = agentEndpoint || `${apiUrl}/agent/chat`\n\n // Build headers matching CubeClient's auth pattern\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(cubeApi as any).headers,\n }\n\n // Add agent API key if provided\n if (agentApiKey) {\n headers['X-Agent-Api-Key'] = agentApiKey\n }\n if (agentProvider) {\n headers['X-Agent-Provider'] = agentProvider\n }\n if (agentModel) {\n headers['X-Agent-Model'] = agentModel\n }\n if (agentProviderEndpoint) {\n headers['X-Agent-Provider-Endpoint'] = agentProviderEndpoint\n }\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n credentials: (cubeApi as any).credentials ?? 'include',\n body: JSON.stringify({\n message: content,\n ...(sessionId ? { sessionId } : {}),\n ...(history && history.length > 0 ? { history } : {}),\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(errorData.error || `Agent request failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('No response body received')\n }\n\n // Read SSE stream\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process complete SSE events (delimited by double newline)\n const events = buffer.split('\\n\\n')\n buffer = events.pop() || '' // Keep incomplete last chunk\n\n for (const eventStr of events) {\n const lines = eventStr.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event: AgentSSEEvent = JSON.parse(line.slice(6))\n handleEvent(event)\n } catch {\n // Skip malformed events\n }\n }\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n const lines = buffer.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event: AgentSSEEvent = JSON.parse(line.slice(6))\n handleEvent(event)\n } catch {\n // Skip malformed events\n }\n }\n }\n }\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n const raw = error instanceof Error ? error.message : 'Stream failed'\n callbacksRef.current.onError(formatUserFacingError(raw))\n }\n } finally {\n setIsStreaming(false)\n abortControllerRef.current = null\n }\n }, [cubeApi, agentEndpoint, agentApiKey, agentProvider, agentModel, agentProviderEndpoint])\n\n const abort = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n abortControllerRef.current = null\n setIsStreaming(false)\n }\n }, [])\n\n return {\n sendMessage,\n isStreaming,\n abort,\n }\n}\n","/**\n * ChatMessage - Renders individual user and assistant messages\n */\n\nimport React, { useState } from 'react'\nimport type { ChatMessage as ChatMessageType, ToolCallRecord } from '../../stores/notebookStore'\nimport LoadingIndicator from '../LoadingIndicator'\n\n/** Simple inline markdown parser for bold, italic, and code in chat text */\nfunction renderInlineMarkdown(text: string): React.ReactNode[] {\n const nodes: React.ReactNode[] = []\n let remaining = text\n let key = 0\n\n while (remaining) {\n // Code inline `text`\n const codeMatch = remaining.match(/^(.*?)`([^`]+)`(.*)$/)\n if (codeMatch) {\n const [, before, code, after] = codeMatch\n if (before) nodes.push(<span key={key++}>{before}</span>)\n nodes.push(\n <code key={key++} className=\"dc:px-1 dc:py-0.5 dc:rounded dc:text-xs bg-dc-surface dc:font-mono\">\n {code}\n </code>\n )\n remaining = after\n continue\n }\n\n // Bold **text**\n const boldMatch = remaining.match(/^(.*?)\\*\\*([^*]+)\\*\\*(.*)$/)\n if (boldMatch) {\n const [, before, bold, after] = boldMatch\n if (before) nodes.push(<span key={key++}>{before}</span>)\n nodes.push(<strong key={key++} className=\"dc:font-semibold\">{bold}</strong>)\n remaining = after\n continue\n }\n\n // Plain text\n nodes.push(<span key={key}>{remaining}</span>)\n break\n }\n\n return nodes\n}\n\ninterface ChatMessageProps {\n message: ChatMessageType\n /** Custom loading indicator for tool call spinners */\n loadingComponent?: React.ReactNode\n}\n\n/** Tool call label mapping for user-friendly display */\nconst TOOL_LABELS: Record<string, string> = {\n discover_cubes: 'Discovering cubes',\n get_cube_metadata: 'Reading metadata',\n execute_query: 'Executing query',\n add_portlet: 'Adding visualization',\n add_markdown: 'Adding explanation',\n}\n\nfunction ToolCallIndicator({ toolCall, loadingComponent }: { toolCall: ToolCallRecord; loadingComponent?: React.ReactNode }) {\n const [expanded, setExpanded] = useState(false)\n const label = TOOL_LABELS[toolCall.name] || toolCall.name\n const isRunning = toolCall.status === 'running'\n\n return (\n <div className=\"dc:my-1 dc:text-xs\">\n <button\n onClick={() => setExpanded(!expanded)}\n className=\"dc:flex dc:items-center dc:gap-1.5 text-dc-text-secondary dc:hover:opacity-80 dc:transition-opacity\"\n >\n {isRunning ? (\n loadingComponent\n ? <span className=\"dc:inline-flex dc:items-center dc:justify-center dc:h-3 dc:w-3\">{loadingComponent}</span>\n : <LoadingIndicator size=\"xs\" />\n ) : (\n <span className=\"dc:text-xs\">\n {toolCall.status === 'error' ? '\\u2717' : '\\u2713'}\n </span>\n )}\n <span>{label}{isRunning ? '...' : ''}</span>\n {!isRunning && (\n <span className=\"dc:text-[10px] dc:opacity-60\">\n {expanded ? '\\u25B2' : '\\u25BC'}\n </span>\n )}\n </button>\n {expanded && toolCall.result != null && (\n <pre className=\"dc:mt-1 dc:p-2 dc:rounded dc:text-[11px] dc:overflow-x-auto dc:max-h-32 dc:overflow-y-auto bg-dc-surface-secondary text-dc-text-secondary\">\n {typeof toolCall.result === 'string'\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2)}\n </pre>\n )}\n </div>\n )\n}\n\nconst MSG_FADE_IN: React.CSSProperties = {\n animation: 'dc-msg-in 100ms ease-out',\n}\n\nconst ChatMessage = React.memo(function ChatMessage({ message, loadingComponent }: ChatMessageProps) {\n const isUser = message.role === 'user'\n const hasContent = !!message.content?.trim()\n const hasError = !!message.error\n const hasToolCalls = message.toolCalls && message.toolCalls.length > 0\n\n // Don't render empty assistant messages\n if (!isUser && !hasContent && !hasError && !hasToolCalls) return null\n\n return (\n <div\n className={`dc:flex dc:mb-3 ${isUser ? 'dc:justify-end' : 'dc:justify-start'}`}\n style={MSG_FADE_IN}\n >\n <div\n className={`dc:max-w-[85%] dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm ${\n isUser\n ? 'bg-dc-accent text-dc-accent-text dc:rounded-br-sm'\n : hasError && !hasContent\n ? 'bg-dc-warning-bg text-dc-text dc:rounded-bl-sm'\n : 'bg-dc-surface-secondary text-dc-text dc:rounded-bl-sm'\n }`}\n >\n {/* Message text */}\n {hasContent && (\n <div className=\"dc:whitespace-pre-wrap dc:break-words\">\n {isUser ? message.content : renderInlineMarkdown(message.content)}\n </div>\n )}\n\n {/* Error display */}\n {hasError && (\n <div className={`dc:flex dc:items-start dc:gap-2 ${hasContent ? 'dc:mt-2 dc:pt-2 dc:border-t dc:border-current dc:border-opacity-10' : ''}`}>\n <span className=\"dc:text-base dc:leading-none dc:mt-0.5 text-dc-warning dc:flex-shrink-0\">{'\\u26A0'}</span>\n <span className=\"text-dc-text-secondary\">{message.error}</span>\n </div>\n )}\n\n {/* Tool call indicators */}\n {hasToolCalls && (\n <div className={hasContent || hasError ? 'dc:mt-1 dc:border-t dc:border-current dc:border-opacity-10 dc:pt-1' : ''}>\n {message.toolCalls!.map((tc, i) => (\n <ToolCallIndicator key={tc.id || i} toolCall={tc} loadingComponent={loadingComponent} />\n ))}\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default ChatMessage\n","/**\n * ChatInput - Text input for sending messages to the agent\n */\n\nimport React, { useCallback, useRef, useEffect } from 'react'\n\ninterface ChatInputProps {\n value: string\n onChange: (value: string) => void\n onSend: () => void\n onStop?: () => void\n onContinue?: () => void\n isStreaming?: boolean\n showContinue?: boolean\n disabled?: boolean\n placeholder?: string\n}\n\nconst ChatInput = React.memo(function ChatInput({\n value,\n onChange,\n onSend,\n onStop,\n onContinue,\n isStreaming = false,\n showContinue = false,\n disabled = false,\n placeholder = 'Ask about your data...',\n}: ChatInputProps) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n // Auto-resize textarea\n useEffect(() => {\n const textarea = textareaRef.current\n if (textarea) {\n textarea.style.height = 'auto'\n textarea.style.height = `${Math.min(textarea.scrollHeight, 150)}px`\n }\n }, [value])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n if (!disabled && value.trim()) {\n onSend()\n }\n }\n },\n [disabled, value, onSend]\n )\n\n return (\n <div className=\"dc:flex dc:gap-2 dc:items-end dc:p-3 border-dc-border dc:border-t\">\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n className=\"dc:flex-1 dc:resize-none dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm bg-dc-surface-secondary text-dc-text border-dc-border dc:border dc:outline-none dc:focus:ring-1 focus:ring-dc-accent dc:disabled:opacity-50\"\n />\n {isStreaming ? (\n <button\n onClick={onStop}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors text-dc-error border-dc-border dc:border dc:hover:opacity-80 dc:shrink-0\"\n >\n Stop\n </button>\n ) : (\n <>\n {showContinue && !value.trim() && (\n <button\n onClick={() => {\n onContinue?.()\n textareaRef.current?.focus()\n }}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors border-dc-border dc:border text-dc-text-secondary dc:hover:opacity-80 dc:shrink-0\"\n >\n Continue\n </button>\n )}\n <button\n onClick={onSend}\n disabled={disabled || !value.trim()}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors bg-dc-accent text-dc-accent-text dc:hover:opacity-90 dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:shrink-0\"\n >\n Send\n </button>\n </>\n )}\n </div>\n )\n})\n\nexport default ChatInput\n","/**\n * AgentChatPanel - Right panel containing chat messages and input\n */\n\nimport React, { useRef, useEffect, useCallback, useState } from 'react'\nimport { useShallow } from 'zustand/react/shallow'\nimport { useNotebookStore, selectChatState, selectChatActions } from '../../stores/notebookStore'\nimport { useAgentChat } from '../../hooks/useAgentChat'\nimport type { PortletBlock, MarkdownBlock, ChatMessage as ChatMessageType } from '../../stores/notebookStore'\nimport ChatMessage from './ChatMessage'\nimport ChatInput from './ChatInput'\nimport LoadingIndicator from '../LoadingIndicator'\nimport { getIcon } from '../../icons'\n\nconst ThumbUpIcon = getIcon('thumbUp')\nconst ThumbDownIcon = getIcon('thumbDown')\n\ninterface AgentChatPanelProps {\n agentEndpoint?: string\n agentApiKey?: string\n agentProvider?: string\n agentModel?: string\n agentProviderEndpoint?: string\n onClear?: () => void\n /** Called when the agent saves a dashboard. Presence enables the \"Save as Dashboard\" button. */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when user submits feedback (thumbs up/down) */\n onScore?: (data: { traceId: string; value: number; comment?: string }) => void\n /** Custom loading indicator for tool call spinners */\n loadingComponent?: React.ReactNode\n /** Initial prompt to auto-send on mount */\n initialPrompt?: string\n}\n\nconst AgentChatPanel = React.memo(function AgentChatPanel({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onClear,\n onDashboardSaved,\n onScore,\n loadingComponent,\n initialPrompt,\n}: AgentChatPanelProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const initialPromptSentRef = useRef(false)\n const [lastTraceId, setLastTraceId] = useState<string | null>(null)\n const [scoredTraceIds, setScoredTraceIds] = useState<Set<string>>(new Set())\n const [isThinking, setIsThinking] = useState(false)\n\n // Track whether the next content should start a new assistant message\n // (set after turn_complete, cleared when first content of new turn arrives)\n const needsNewMessageRef = useRef(false)\n\n // Store state\n const { messages, isStreaming, inputValue } = useNotebookStore(useShallow(selectChatState))\n const {\n addMessage,\n appendToLastAssistantMessage,\n setLastAssistantError,\n addToolCallToLastAssistant,\n updateLastToolCall,\n setIsStreaming,\n setInputValue,\n setSessionId,\n } = useNotebookStore(useShallow(selectChatActions))\n\n const sessionId = useNotebookStore((s) => s.sessionId)\n const addBlock = useNotebookStore((s) => s.addBlock)\n const reset = useNotebookStore((s) => s.reset)\n const portletBlockCount = useNotebookStore((s) => s.blocks.filter((b) => b.type === 'portlet').length)\n\n // Refs for values doSend reads at call-time (avoids recreating callbacks on every text delta)\n const messagesRef = useRef(messages)\n messagesRef.current = messages\n const isStreamingRef = useRef(isStreaming)\n isStreamingRef.current = isStreaming\n const sessionIdRef = useRef(sessionId)\n sessionIdRef.current = sessionId\n\n // Lazily create a new assistant message when needed (between turns)\n const ensureNewMessage = useCallback(() => {\n if (needsNewMessageRef.current) {\n needsNewMessageRef.current = false\n addMessage({\n id: `msg-${Date.now()}`,\n role: 'assistant',\n content: '',\n toolCalls: [],\n timestamp: Date.now(),\n })\n }\n }, [addMessage])\n\n // Auto-scroll only when NEW messages arrive or thinking starts (not on initial load)\n const prevMsgCountRef = useRef(messages.length)\n useEffect(() => {\n if (messages.length > prevMsgCountRef.current) {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n prevMsgCountRef.current = messages.length\n }, [messages])\n\n useEffect(() => {\n if (isThinking) {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [isThinking])\n\n // Agent chat hook\n const { sendMessage, abort } = useAgentChat({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onTextDelta: useCallback((text: string) => {\n setIsThinking(false)\n ensureNewMessage()\n appendToLastAssistantMessage(text)\n }, [ensureNewMessage, appendToLastAssistantMessage]),\n onToolStart: useCallback((id: string, name: string, input?: unknown) => {\n setIsThinking(false)\n ensureNewMessage()\n addToolCallToLastAssistant({ id, name, input, status: 'running' })\n }, [ensureNewMessage, addToolCallToLastAssistant]),\n onToolResult: useCallback((id: string, _name: string, result?: unknown, isError?: boolean) => {\n updateLastToolCall({ id, status: isError ? 'error' : 'complete', result })\n }, [updateLastToolCall]),\n onAddPortlet: useCallback((data: PortletBlock) => {\n addBlock(data)\n }, [addBlock]),\n onAddMarkdown: useCallback((data: MarkdownBlock) => {\n addBlock(data)\n }, [addBlock]),\n onDashboardSaved,\n onTurnComplete: useCallback(() => {\n // Don't create a new message yet — just flag that the next turn\n // should start a new bubble (created lazily by ensureNewMessage)\n needsNewMessageRef.current = true\n setIsThinking(true)\n }, []),\n onDone: useCallback((sid: string, traceId?: string) => {\n needsNewMessageRef.current = false\n setSessionId(sid)\n setIsStreaming(false)\n setIsThinking(false)\n if (traceId) setLastTraceId(traceId)\n }, [setSessionId, setIsStreaming]),\n onError: useCallback((message: string) => {\n setIsThinking(false)\n ensureNewMessage()\n setLastAssistantError(message)\n setIsStreaming(false)\n }, [ensureNewMessage, setLastAssistantError, setIsStreaming]),\n })\n\n // Send a message (used by both Send and Continue)\n // Reads messages/isStreaming/sessionId from refs to avoid recreating on every text delta\n const doSend = useCallback((content: string) => {\n if (!content || isStreamingRef.current) return\n\n needsNewMessageRef.current = false\n\n // Capture current messages as history BEFORE adding the new ones\n const history = messagesRef.current.map((m: ChatMessageType) => ({\n role: m.role,\n content: m.content,\n ...(m.toolCalls && m.toolCalls.length > 0 ? { toolCalls: m.toolCalls } : {}),\n }))\n\n // Add user message\n addMessage({\n id: `msg-${Date.now()}`,\n role: 'user',\n content,\n timestamp: Date.now(),\n })\n\n // Create empty assistant message for first turn's streaming\n addMessage({\n id: `msg-${Date.now() + 1}`,\n role: 'assistant',\n content: '',\n toolCalls: [],\n timestamp: Date.now(),\n })\n\n setInputValue('')\n setIsStreaming(true)\n setIsThinking(true)\n\n // Send to agent with conversation history for session continuity\n sendMessage(content, sessionIdRef.current, history)\n }, [addMessage, setInputValue, setIsStreaming, sendMessage])\n\n // Auto-send initial prompt on mount (doSend is stable so this won't re-trigger)\n // Reset ref on cleanup so React StrictMode's double-mount doesn't block the real mount\n useEffect(() => {\n if (initialPrompt && !initialPromptSentRef.current && messages.length === 0) {\n initialPromptSentRef.current = true\n // Small delay to ensure chat hook is fully initialized\n const timer = setTimeout(() => doSend(initialPrompt), 100)\n return () => {\n clearTimeout(timer)\n initialPromptSentRef.current = false\n }\n }\n }, [initialPrompt, messages.length, doSend])\n\n const inputValueRef = useRef(inputValue)\n inputValueRef.current = inputValue\n\n const handleSend = useCallback(() => {\n doSend(inputValueRef.current.trim())\n }, [doSend])\n\n const handleStop = useCallback(() => {\n abort()\n setIsStreaming(false)\n }, [abort, setIsStreaming])\n\n const handleContinue = useCallback(() => {\n // Just set placeholder text — user types their own follow-up and sends\n setInputValue('')\n }, [setInputValue])\n\n const handleClear = useCallback(() => {\n abort()\n setIsStreaming(false)\n setIsThinking(false)\n reset()\n setLastTraceId(null)\n setScoredTraceIds(new Set())\n onClear?.()\n }, [abort, setIsStreaming, reset, onClear])\n\n const handleSaveAsDashboard = useCallback(() => {\n doSend(\n 'Save the current notebook as a dashboard with a professional layout, section headers, and appropriate filters.'\n )\n }, [doSend])\n\n const handleScore = useCallback((value: number) => {\n if (!lastTraceId || !onScore) return\n onScore({ traceId: lastTraceId, value })\n setScoredTraceIds(prev => new Set(prev).add(lastTraceId))\n }, [lastTraceId, onScore])\n\n const showSaveAsDashboard = !!onDashboardSaved && !isStreaming && portletBlockCount > 0 && messages.length > 0\n const showFeedback = !!onScore && !isStreaming && lastTraceId && messages.length > 0 && !scoredTraceIds.has(lastTraceId)\n const lastScored = lastTraceId ? scoredTraceIds.has(lastTraceId) : false\n\n return (\n <div className=\"dc:flex dc:flex-col dc:h-full bg-dc-surface\">\n {/* Header */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-4 dc:py-3 border-dc-border dc:border-b\">\n <h3 className=\"dc:text-sm dc:font-semibold text-dc-text\">AI Assistant</h3>\n <div className=\"dc:flex dc:items-center dc:gap-1\">\n {showSaveAsDashboard && (\n <button\n onClick={handleSaveAsDashboard}\n className=\"dc:text-xs dc:px-2 dc:py-1 dc:rounded text-dc-accent dc:hover:opacity-80\"\n title=\"Save notebook as a dashboard\"\n >\n Save as Dashboard\n </button>\n )}\n {(messages.length > 0) && (\n <button\n onClick={handleClear}\n disabled={isStreaming}\n className=\"dc:text-xs dc:px-2 dc:py-1 dc:rounded text-dc-text-secondary dc:hover:opacity-80 dc:disabled:opacity-40\"\n title=\"Clear notebook and chat\"\n >\n Clear\n </button>\n )}\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"dc:flex-1 dc:overflow-y-auto dc:px-4 dc:py-3\">\n {messages.length === 0 ? (\n <EmptyState />\n ) : (\n messages.map((msg) => (\n <ChatMessage\n key={msg.id}\n message={msg}\n loadingComponent={loadingComponent}\n />\n ))\n )}\n {/* Thinking indicator (between turns or waiting for first response) */}\n {isThinking && <ThinkingBubble loadingComponent={loadingComponent} />}\n\n {/* Feedback (thumbs up/down) */}\n {(showFeedback || lastScored) && (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:gap-3 dc:py-4 dc:mt-2\">\n {lastScored ? (\n <span className=\"dc:text-sm text-dc-text-secondary\">Thanks for your feedback!</span>\n ) : (\n <>\n <span className=\"dc:text-sm text-dc-text-secondary\">Was this helpful?</span>\n <div className=\"dc:flex dc:items-center dc:gap-2\">\n <button\n onClick={() => handleScore(1)}\n className=\"dc:flex dc:items-center dc:gap-1.5 dc:px-3 dc:py-1.5 dc:rounded-lg dc:text-sm dc:font-medium border-dc-border dc:border text-dc-success hover:bg-dc-success-bg dc:transition-colors bg-dc-surface dc:cursor-pointer\"\n >\n <ThumbUpIcon className=\"dc:w-4 dc:h-4\" />\n Yes\n </button>\n <button\n onClick={() => handleScore(0)}\n className=\"dc:flex dc:items-center dc:gap-1.5 dc:px-3 dc:py-1.5 dc:rounded-lg dc:text-sm dc:font-medium border-dc-border dc:border text-dc-error hover:bg-dc-danger-bg dc:transition-colors bg-dc-surface dc:cursor-pointer\"\n >\n <ThumbDownIcon className=\"dc:w-4 dc:h-4\" />\n No\n </button>\n </div>\n </>\n )}\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input */}\n <ChatInput\n value={inputValue}\n onChange={setInputValue}\n onSend={handleSend}\n onStop={handleStop}\n onContinue={handleContinue}\n isStreaming={isStreaming}\n showContinue={!isStreaming && messages.length > 0}\n />\n </div>\n )\n})\n\nfunction ThinkingBubble({ loadingComponent }: { loadingComponent?: React.ReactNode }) {\n return (\n <div\n className=\"dc:flex dc:mb-3 dc:justify-start\"\n style={{ animation: 'dc-msg-in 100ms ease-out' }}\n >\n <div className=\"dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm bg-dc-surface-secondary text-dc-text-secondary dc:rounded-bl-sm dc:flex dc:items-center dc:gap-2\">\n {loadingComponent\n ? <span className=\"dc:inline-flex dc:items-center dc:justify-center dc:h-4 dc:w-4\">{loadingComponent}</span>\n : <LoadingIndicator size=\"xs\" />}\n <span>Thinking...</span>\n </div>\n </div>\n )\n}\n\nfunction EmptyState() {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:h-full\">\n <div className=\"dc:text-center dc:max-w-xs\">\n <div className=\"dc:text-lg dc:font-semibold text-dc-text dc:mb-2\">\n Data Analysis Assistant\n </div>\n <p className=\"dc:text-sm text-dc-text-secondary dc:mb-4\">\n Ask me about your data and I'll create visualizations and insights.\n </p>\n <div className=\"dc:space-y-2 dc:text-xs text-dc-text-muted\">\n <p>\"Show me employee productivity trends\"</p>\n <p>\"What are the top departments by headcount?\"</p>\n <p>\"Compare revenue across product categories\"</p>\n </div>\n </div>\n </div>\n )\n}\n\nexport default AgentChatPanel\n","/**\n * AgenticNotebook - AI-powered data analysis notebook\n *\n * Top-level component combining a notebook canvas (left) with a chat panel (right).\n * The AI agent discovers available data, executes queries, creates visualizations,\n * and explains findings within a single conversational flow.\n *\n * Requires:\n * - CubeProvider wrapping this component\n * - Server configured with `agent` option in HonoAdapterOptions\n * - @anthropic-ai/claude-agent-sdk installed on the server\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n NotebookStoreProvider,\n useNotebookStore,\n type NotebookConfig,\n} from '../../stores/notebookStore'\nimport NotebookCanvas from './NotebookCanvas'\nimport AgentChatPanel from './AgentChatPanel'\nimport type { ColorPalette } from '../../types'\nimport type { ReactNode } from 'react'\n\nexport interface AgenticNotebookProps {\n /** Initial config to restore (saved notebooks) */\n config?: NotebookConfig\n /** Override default agent endpoint (default: apiUrl + '/agent/chat') */\n agentEndpoint?: string\n /** Client-side API key (for demo/try-site use) */\n agentApiKey?: string\n /** Override LLM provider (anthropic | openai | google) */\n agentProvider?: string\n /** Override LLM model (e.g. 'gpt-4o', 'gemini-2.0-flash') */\n agentModel?: string\n /** Override provider endpoint URL (for OpenAI-compatible services) */\n agentProviderEndpoint?: string\n /** Callback when notebook state changes (for persistence) */\n onSave?: (config: NotebookConfig) => void | Promise<void>\n /** Callback when dirty state changes */\n onDirtyStateChange?: (isDirty: boolean) => void\n /** Color palette for charts */\n colorPalette?: ColorPalette\n /** Called when the agent saves a dashboard. Presence enables the \"Save as Dashboard\" button. */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when user submits feedback (thumbs up/down). Receives traceId from the last agent response. */\n onScore?: (data: { traceId: string; value: number; comment?: string }) => void\n /** Custom loading indicator for tool call spinners (defaults to LoadingIndicator) */\n loadingComponent?: ReactNode\n /** Additional CSS class name */\n className?: string\n /** Initial prompt to auto-send on mount */\n initialPrompt?: string\n}\n\n/**\n * Inner component that uses the notebook store (must be inside provider)\n */\nfunction AgenticNotebookInner({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onSave,\n onDirtyStateChange,\n onDashboardSaved,\n onScore,\n loadingComponent,\n className,\n initialPrompt,\n}: Omit<AgenticNotebookProps, 'config' | 'colorPalette'>) {\n const [dividerPosition, setDividerPosition] = useState(60) // 60% left, 40% right\n const containerRef = useRef<HTMLDivElement>(null)\n const isDraggingRef = useRef(false)\n\n const blockCount = useNotebookStore((s) => s.blocks.length)\n const messageCount = useNotebookStore((s) => s.messages.length)\n const isStreaming = useNotebookStore((s) => s.isStreaming)\n const save = useNotebookStore((s) => s.save)\n\n // Track dirty state\n const initialRef = useRef({ blockCount, msgCount: messageCount })\n useEffect(() => {\n const isDirty =\n blockCount !== initialRef.current.blockCount ||\n messageCount !== initialRef.current.msgCount\n onDirtyStateChange?.(isDirty)\n }, [blockCount, messageCount, onDirtyStateChange])\n\n // Debounced save - fires 1s after blocks/messages count stabilizes\n // Waits until streaming completes to avoid saving partial content\n const saveTimeoutRef = useRef<ReturnType<typeof setTimeout>>()\n const pendingSaveRef = useRef(false)\n const onSaveRef = useRef(onSave)\n onSaveRef.current = onSave\n // Track whether we've ever had content (so we save empty state on Clear but not on initial mount)\n const hasHadContentRef = useRef(blockCount > 0 || messageCount > 0)\n useEffect(() => {\n if (blockCount > 0 || messageCount > 0) {\n hasHadContentRef.current = true\n }\n if (!onSaveRef.current || !hasHadContentRef.current) return\n\n if (isStreaming) {\n // Mark that a save is needed once streaming completes\n pendingSaveRef.current = true\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n return\n }\n\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n saveTimeoutRef.current = setTimeout(() => {\n pendingSaveRef.current = false\n const config = save()\n onSaveRef.current?.(config)\n }, 1000)\n\n return () => {\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n }\n }, [blockCount, messageCount, isStreaming, save])\n\n // Flush pending save when streaming ends\n useEffect(() => {\n if (!isStreaming && pendingSaveRef.current && onSaveRef.current && hasHadContentRef.current) {\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n saveTimeoutRef.current = setTimeout(() => {\n pendingSaveRef.current = false\n const config = save()\n onSaveRef.current?.(config)\n }, 1000)\n }\n }, [isStreaming, save])\n\n // Explicit clear handler — save immediately with empty state\n const handleClear = useCallback(() => {\n if (onSaveRef.current) {\n // Cancel any pending debounced save\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n onSaveRef.current({ blocks: [], messages: [] })\n }\n }, [])\n\n // Divider drag handlers\n const handleDividerMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n isDraggingRef.current = true\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (!isDraggingRef.current || !containerRef.current) return\n const rect = containerRef.current.getBoundingClientRect()\n const newPos = ((moveEvent.clientX - rect.left) / rect.width) * 100\n setDividerPosition(Math.min(Math.max(newPos, 30), 80))\n }\n\n const handleMouseUp = () => {\n isDraggingRef.current = false\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n }\n\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n }, [])\n\n return (\n <div\n ref={containerRef}\n className={`dc:flex dc:h-full dc:w-full dc:overflow-hidden bg-dc-surface-secondary ${className || ''}`}\n >\n {/* Left: Notebook Canvas */}\n <div\n className=\"dc:h-full dc:overflow-hidden\"\n style={{ width: `${dividerPosition}%` }}\n >\n <NotebookCanvas />\n </div>\n\n {/* Resizable Divider */}\n <div\n className=\"dc:w-1 dc:h-full dc:cursor-col-resize dc:flex-shrink-0 dc:transition-colors bg-dc-border dc:hover:bg-dc-accent\"\n onMouseDown={handleDividerMouseDown}\n />\n\n {/* Right: Chat Panel */}\n <div\n className=\"dc:h-full dc:overflow-hidden\"\n style={{ width: `${100 - dividerPosition}%` }}\n >\n <AgentChatPanel\n agentEndpoint={agentEndpoint}\n agentApiKey={agentApiKey}\n agentProvider={agentProvider}\n agentModel={agentModel}\n agentProviderEndpoint={agentProviderEndpoint}\n onClear={handleClear}\n onDashboardSaved={onDashboardSaved}\n onScore={onScore}\n loadingComponent={loadingComponent}\n initialPrompt={initialPrompt}\n />\n </div>\n </div>\n )\n}\n\n/**\n * AgenticNotebook - AI-powered data analysis notebook\n *\n * @example\n * ```tsx\n * <CubeProvider apiOptions={{ apiUrl: '/api/cubejs-api/v1' }} token={token}>\n * <AgenticNotebook\n * agentApiKey=\"sk-...\"\n * onSave={(config) => saveToDatabase(config)}\n * />\n * </CubeProvider>\n * ```\n */\nconst AgenticNotebook = React.memo(function AgenticNotebook({\n config,\n ...props\n}: AgenticNotebookProps) {\n return (\n <NotebookStoreProvider initialConfig={config}>\n <AgenticNotebookInner {...props} />\n </NotebookStoreProvider>\n )\n})\n\nexport default AgenticNotebook\n","// Placeholder component - will be implemented in Phase 4\nexport function AnalyticsPage() {\n return <div>Analytics Page - Coming in Phase 4</div>\n}","/**\n * DashboardThumbnailPlaceholder\n *\n * A placeholder component shown when a dashboard thumbnail doesn't exist\n * but the thumbnail feature is enabled. Displays a simple grid icon\n * with \"No preview\" text.\n */\n\nimport { getIcon } from '../icons'\n\nconst GridIcon = getIcon('segment')\n\nexport interface DashboardThumbnailPlaceholderProps {\n /** Additional CSS classes */\n className?: string\n}\n\nexport function DashboardThumbnailPlaceholder({\n className = ''\n}: DashboardThumbnailPlaceholderProps) {\n return (\n <div\n className={`dc:flex dc:items-center dc:justify-center bg-dc-bg-secondary ${className}`}\n >\n <div className=\"dc:text-center\">\n <GridIcon\n className=\"dc:w-8 dc:h-8 dc:mx-auto dc:mb-2 text-dc-text-muted dc:opacity-50\"\n />\n <span className=\"dc:text-xs text-dc-text-muted\">No preview</span>\n </div>\n </div>\n )\n}\n\nexport default DashboardThumbnailPlaceholder\n"],"names":["createDefaultState","createStoreActions","set","get","block","state","id","b","direction","idx","newBlocks","swapIdx","updates","message","text","messages","lastMsg","error","toolCall","update","toolCalls","tc","streaming","value","config","createNotebookStore","initialState","createStore","devtools","subscribeWithSelector","NotebookStoreContext","createContext","NotebookStoreProvider","children","initialConfig","storeRef","useRef","store","useNotebookStore","selector","useContext","useStore","selectBlocks","selectMessages","selectIsStreaming","selectSessionId","selectInputValue","selectChatState","selectChatActions","selectBlockActions","ICON_STYLE","ChevronUpIcon","getIcon","ChevronDownIcon","EditIcon","DeleteIcon","NotebookPortletBlock","React","onRemove","onMoveUp","onMoveDown","onEdit","isFirst","isLast","debugData","setDebugData","useState","handleDebugDataReady","useCallback","data","jsxs","jsx","DebugModal","AnalyticsPortlet","DocumentTextIcon","markdownOptions","NotebookMarkdownBlock","Markdown","NotebookCanvas","blocks","removeBlock","moveBlock","updateBlock","useShallow","endRef","editingBlock","setEditingBlock","prevCountRef","useEffect","handleRemove","handleMoveUp","handleMoveDown","handleEdit","handleEditSave","portletData","normalized","ensureAnalysisConfig","analysisConfig","chartModeConfig","index","PortletAnalysisModal","formatUserFacingError","parsed","errorType","status","useAgentChat","options","agentEndpoint","agentApiKey","agentProvider","agentModel","agentProviderEndpoint","cubeApi","useCubeApi","abortControllerRef","isStreaming","setIsStreaming","callbacksRef","sendMessage","content","sessionId","history","handleEvent","event","cb","controller","apiUrl","endpoint","headers","response","errorData","reader","decoder","buffer","done","events","eventStr","lines","line","raw","abort","renderInlineMarkdown","nodes","remaining","key","codeMatch","before","code","after","boldMatch","bold","TOOL_LABELS","ToolCallIndicator","loadingComponent","expanded","setExpanded","label","isRunning","LoadingIndicator","MSG_FADE_IN","ChatMessage","isUser","hasContent","hasError","hasToolCalls","ChatInput","onChange","onSend","onStop","onContinue","showContinue","disabled","placeholder","textareaRef","textarea","handleKeyDown","e","Fragment","ThumbUpIcon","ThumbDownIcon","AgentChatPanel","onClear","onDashboardSaved","onScore","initialPrompt","messagesEndRef","initialPromptSentRef","lastTraceId","setLastTraceId","scoredTraceIds","setScoredTraceIds","isThinking","setIsThinking","needsNewMessageRef","inputValue","addMessage","appendToLastAssistantMessage","setLastAssistantError","addToolCallToLastAssistant","updateLastToolCall","setInputValue","setSessionId","s","addBlock","reset","portletBlockCount","messagesRef","isStreamingRef","sessionIdRef","ensureNewMessage","prevMsgCountRef","name","input","_name","result","isError","sid","traceId","doSend","m","timer","inputValueRef","handleSend","handleStop","handleContinue","handleClear","handleSaveAsDashboard","handleScore","prev","showSaveAsDashboard","showFeedback","lastScored","EmptyState","msg","ThinkingBubble","AgenticNotebookInner","onSave","onDirtyStateChange","className","dividerPosition","setDividerPosition","containerRef","isDraggingRef","blockCount","messageCount","save","initialRef","isDirty","saveTimeoutRef","pendingSaveRef","onSaveRef","hasHadContentRef","handleDividerMouseDown","handleMouseMove","moveEvent","rect","newPos","handleMouseUp","AgenticNotebook","props","AnalyticsPage","GridIcon","DashboardThumbnailPlaceholder"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/client/stores/notebookStore.tsx","../../src/client/components/AgenticNotebook/NotebookPortletBlock.tsx","../../src/client/components/AgenticNotebook/NotebookMarkdownBlock.tsx","../../src/client/components/AgenticNotebook/NotebookCanvas.tsx","../../src/client/hooks/useAgentChat.ts","../../src/client/components/AgenticNotebook/ChatMessage.tsx","../../src/client/components/AgenticNotebook/ChatInput.tsx","../../src/client/components/AgenticNotebook/AgentChatPanel.tsx","../../src/client/components/AgenticNotebook/index.tsx","../../src/client/components/AnalyticsPage.tsx","../../src/client/components/DashboardThumbnailPlaceholder.tsx"],"sourcesContent":["/**\n * Notebook Zustand Store (Instance-based)\n *\n * State management for the AgenticNotebook component, consolidating:\n * - Notebook blocks (portlets + markdown)\n * - Chat messages\n * - Session state\n * - UI state\n *\n * KEY ARCHITECTURE: Instance-based stores\n * - Each AgenticNotebook gets its own store instance via Context\n * - No server state (data fetching is handled by portlets via TanStack Query)\n * - State is per-notebook session\n *\n * Uses Zustand's createStore (factory) instead of create (singleton).\n * Store is provided via React Context.\n */\n\nimport { createContext, useContext, useRef, type ReactNode } from 'react'\nimport { createStore, useStore, type StoreApi } from 'zustand'\nimport { devtools, subscribeWithSelector } from 'zustand/middleware'\nimport type {\n ChartType,\n ChartAxisConfig,\n ChartDisplayConfig,\n} from '../types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A portlet block in the notebook\n */\nexport interface PortletBlock {\n id: string\n type: 'portlet'\n title: string\n query: string\n chartType: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n}\n\n/**\n * A markdown text block in the notebook\n */\nexport interface MarkdownBlock {\n id: string\n type: 'markdown'\n title?: string\n content: string\n}\n\n/**\n * A block in the notebook canvas\n */\nexport type NotebookBlock = PortletBlock | MarkdownBlock\n\n/**\n * A tool call record for display in chat messages\n */\nexport interface ToolCallRecord {\n id: string\n name: string\n input?: unknown\n result?: unknown\n status: 'running' | 'complete' | 'error'\n}\n\n/**\n * A chat message\n */\nexport interface ChatMessage {\n id: string\n role: 'user' | 'assistant'\n content: string\n error?: string\n toolCalls?: ToolCallRecord[]\n timestamp: number\n}\n\n/**\n * Serializable notebook config for save/load\n */\nexport interface NotebookConfig {\n blocks: NotebookBlock[]\n messages: ChatMessage[]\n}\n\n// ============================================================================\n// Store State\n// ============================================================================\n\nexport interface NotebookStoreState {\n /** Ordered array of notebook blocks */\n blocks: NotebookBlock[]\n\n /** Chat message history */\n messages: ChatMessage[]\n\n /** Whether the agent is currently streaming a response */\n isStreaming: boolean\n\n /** Agent SDK session ID for multi-turn conversations */\n sessionId: string | null\n\n /** Chat input value */\n inputValue: string\n}\n\n// ============================================================================\n// Store Actions\n// ============================================================================\n\nexport interface NotebookStoreActions {\n // Block actions\n addBlock: (block: NotebookBlock) => void\n removeBlock: (id: string) => void\n moveBlock: (id: string, direction: 'up' | 'down') => void\n updateBlock: (id: string, updates: Partial<Omit<PortletBlock, 'id' | 'type'>>) => void\n\n // Chat actions\n addMessage: (message: ChatMessage) => void\n appendToLastAssistantMessage: (text: string) => void\n setLastAssistantError: (error: string) => void\n addToolCallToLastAssistant: (toolCall: ToolCallRecord) => void\n updateLastToolCall: (update: Partial<ToolCallRecord>) => void\n\n // Session/UI actions\n setIsStreaming: (streaming: boolean) => void\n setSessionId: (id: string | null) => void\n setInputValue: (value: string) => void\n\n // Persistence\n save: () => NotebookConfig\n load: (config: NotebookConfig) => void\n\n // Reset\n reset: () => void\n}\n\n/**\n * Combined store type\n */\nexport type NotebookStore = NotebookStoreState & NotebookStoreActions\n\n// ============================================================================\n// Initial State\n// ============================================================================\n\nconst createDefaultState = (): NotebookStoreState => ({\n blocks: [],\n messages: [],\n isStreaming: false,\n sessionId: null,\n inputValue: '',\n})\n\n// ============================================================================\n// Store Factory\n// ============================================================================\n\nfunction createStoreActions(\n set: (\n partial:\n | Partial<NotebookStore>\n | ((state: NotebookStore) => Partial<NotebookStore>)\n ) => void,\n get: () => NotebookStore\n): NotebookStoreActions {\n return {\n // Block actions\n addBlock: (block) =>\n set((state) => ({\n blocks: [...state.blocks, block],\n })),\n\n removeBlock: (id) =>\n set((state) => ({\n blocks: state.blocks.filter((b) => b.id !== id),\n })),\n\n moveBlock: (id, direction) =>\n set((state) => {\n const idx = state.blocks.findIndex((b) => b.id === id)\n if (idx === -1) return {}\n if (direction === 'up' && idx === 0) return {}\n if (direction === 'down' && idx === state.blocks.length - 1) return {}\n\n const newBlocks = [...state.blocks]\n const swapIdx = direction === 'up' ? idx - 1 : idx + 1\n ;[newBlocks[idx], newBlocks[swapIdx]] = [newBlocks[swapIdx], newBlocks[idx]]\n return { blocks: newBlocks }\n }),\n\n updateBlock: (id, updates) =>\n set((state) => ({\n blocks: state.blocks.map((b) =>\n b.id === id && b.type === 'portlet' ? { ...b, ...updates } : b\n ),\n })),\n\n // Chat actions\n addMessage: (message) =>\n set((state) => ({\n messages: [...state.messages, message],\n })),\n\n appendToLastAssistantMessage: (text) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = {\n ...lastMsg,\n content: lastMsg.content + text,\n }\n }\n return { messages }\n }),\n\n setLastAssistantError: (error) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = { ...lastMsg, error }\n }\n return { messages }\n }),\n\n addToolCallToLastAssistant: (toolCall) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg && lastMsg.role === 'assistant') {\n messages[messages.length - 1] = {\n ...lastMsg,\n toolCalls: [...(lastMsg.toolCalls || []), toolCall],\n }\n }\n return { messages }\n }),\n\n updateLastToolCall: (update) =>\n set((state) => {\n const messages = [...state.messages]\n const lastMsg = messages[messages.length - 1]\n if (lastMsg?.role === 'assistant' && lastMsg.toolCalls?.length) {\n const toolCalls = [...lastMsg.toolCalls]\n // Find by ID if provided, otherwise fall back to last\n const idx = update.id\n ? toolCalls.findIndex((tc) => tc.id === update.id)\n : toolCalls.length - 1\n if (idx !== -1) {\n toolCalls[idx] = { ...toolCalls[idx], ...update }\n messages[messages.length - 1] = { ...lastMsg, toolCalls }\n }\n }\n return { messages }\n }),\n\n // Session/UI actions\n setIsStreaming: (streaming) => set({ isStreaming: streaming }),\n setSessionId: (id) => set({ sessionId: id }),\n setInputValue: (value) => set({ inputValue: value }),\n\n // Persistence\n save: () => {\n const state = get()\n return {\n blocks: state.blocks,\n messages: state.messages,\n }\n },\n\n load: (config) =>\n set({\n blocks: config.blocks || [],\n messages: config.messages || [],\n }),\n\n // Reset\n reset: () => set(createDefaultState()),\n }\n}\n\n/**\n * Create a new notebook store instance\n */\nexport function createNotebookStore() {\n const initialState = createDefaultState()\n\n return createStore<NotebookStore>()(\n devtools(\n subscribeWithSelector((set, get) => ({\n ...initialState,\n ...createStoreActions(set, get),\n })),\n { name: 'NotebookStore' }\n )\n )\n}\n\n// ============================================================================\n// React Context & Provider\n// ============================================================================\n\nconst NotebookStoreContext = createContext<StoreApi<NotebookStore> | null>(null)\n\nexport interface NotebookStoreProviderProps {\n children: ReactNode\n /** Initial config to load */\n initialConfig?: NotebookConfig\n}\n\n/**\n * Provider component that creates a store instance per AgenticNotebook\n */\nexport function NotebookStoreProvider({\n children,\n initialConfig,\n}: NotebookStoreProviderProps) {\n const storeRef = useRef<StoreApi<NotebookStore> | null>(null)\n\n if (!storeRef.current) {\n const store = createNotebookStore()\n if (initialConfig) {\n store.getState().load(initialConfig)\n }\n storeRef.current = store\n }\n\n return (\n <NotebookStoreContext.Provider value={storeRef.current}>\n {children}\n </NotebookStoreContext.Provider>\n )\n}\n\n/**\n * Hook to access the notebook store from context\n * @throws Error if used outside of provider\n */\nexport function useNotebookStore<T>(selector: (state: NotebookStore) => T): T {\n const store = useContext(NotebookStoreContext)\n if (!store) {\n throw new Error('useNotebookStore must be used within NotebookStoreProvider')\n }\n return useStore(store, selector)\n}\n\n// ============================================================================\n// Selectors\n// ============================================================================\n\nexport const selectBlocks = (state: NotebookStore) => state.blocks\nexport const selectMessages = (state: NotebookStore) => state.messages\nexport const selectIsStreaming = (state: NotebookStore) => state.isStreaming\nexport const selectSessionId = (state: NotebookStore) => state.sessionId\nexport const selectInputValue = (state: NotebookStore) => state.inputValue\n\nexport const selectChatState = (state: NotebookStore) => ({\n messages: state.messages,\n isStreaming: state.isStreaming,\n inputValue: state.inputValue,\n})\n\nexport const selectChatActions = (state: NotebookStore) => ({\n addMessage: state.addMessage,\n appendToLastAssistantMessage: state.appendToLastAssistantMessage,\n setLastAssistantError: state.setLastAssistantError,\n addToolCallToLastAssistant: state.addToolCallToLastAssistant,\n updateLastToolCall: state.updateLastToolCall,\n setIsStreaming: state.setIsStreaming,\n setInputValue: state.setInputValue,\n setSessionId: state.setSessionId,\n})\n\nexport const selectBlockActions = (state: NotebookStore) => ({\n addBlock: state.addBlock,\n removeBlock: state.removeBlock,\n moveBlock: state.moveBlock,\n updateBlock: state.updateBlock,\n})\n","/**\n * NotebookPortletBlock - Wraps AnalyticsPortlet for notebook display\n *\n * Uses the same header pattern as DashboardPortletCard for consistency:\n * - Title on the left with DebugModal inline\n * - Action buttons on the right (move, edit, delete)\n */\n\nimport React, { useState, useCallback } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { PortletBlock } from '../../stores/notebookStore'\nimport type { ChartAxisConfig, ChartDisplayConfig, ChartType } from '../../types'\nimport type { FlowChartData } from '../../types/flow'\nimport type { RetentionChartData } from '../../types/retention'\nimport { getIcon } from '../../icons/registry'\nimport AnalyticsPortlet from '../AnalyticsPortlet'\nimport DebugModal from '../DebugModal'\n\nconst ICON_STYLE: CSSProperties = { width: '16px', height: '16px', color: 'currentColor' }\n\ninterface DebugData {\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n queryObject: unknown\n data: unknown[] | FlowChartData | RetentionChartData\n chartType: ChartType\n cacheInfo?: { hit: true; cachedAt: string; ttlMs: number; ttlRemainingMs: number } | null\n drillState?: unknown\n}\n\ninterface NotebookPortletBlockProps {\n block: PortletBlock\n onRemove: (id: string) => void\n onMoveUp: (id: string) => void\n onMoveDown: (id: string) => void\n onEdit: (block: PortletBlock) => void\n isFirst: boolean\n isLast: boolean\n}\n\nconst ChevronUpIcon = getIcon('chevronUp')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst EditIcon = getIcon('edit')\nconst DeleteIcon = getIcon('delete')\n\nconst NotebookPortletBlock = React.memo(function NotebookPortletBlock({\n block,\n onRemove,\n onMoveUp,\n onMoveDown,\n onEdit,\n isFirst,\n isLast,\n}: NotebookPortletBlockProps) {\n const [debugData, setDebugData] = useState<DebugData | null>(null)\n\n const handleDebugDataReady = useCallback((data: DebugData) => {\n setDebugData(data)\n }, [])\n\n return (\n <div className=\"dc:relative dc:mb-4 bg-dc-surface dc:border border-dc-border dc:rounded-lg dc:flex dc:flex-col\">\n {/* Header - same pattern as DashboardPortletCard */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-3 dc:py-1.5 dc:border-b border-dc-border dc:shrink-0 bg-dc-surface-secondary dc:rounded-t-lg\">\n <div className=\"dc:flex dc:items-center dc:gap-2 dc:flex-1 dc:min-w-0\">\n <h3 className=\"dc:font-semibold dc:text-sm text-dc-text dc:truncate\">\n {block.title || 'Untitled'}\n </h3>\n {debugData && (\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n cacheInfo={debugData.cacheInfo ?? undefined}\n />\n )}\n </div>\n <div className=\"dc:flex dc:items-center dc:gap-1 dc:shrink-0 dc:ml-4 dc:-mr-2\">\n {!isFirst && (\n <button\n onClick={() => onMoveUp(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move up\"\n >\n <ChevronUpIcon style={ICON_STYLE} />\n </button>\n )}\n {!isLast && (\n <button\n onClick={() => onMoveDown(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move down\"\n >\n <ChevronDownIcon style={ICON_STYLE} />\n </button>\n )}\n <button\n onClick={() => onEdit(block)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Edit visualization\"\n >\n <EditIcon style={ICON_STYLE} />\n </button>\n <button\n onClick={() => onRemove(block.id)}\n className=\"dc:p-1 dc:mr-0.5 dc:bg-transparent dc:border-none dc:rounded-sm dc:cursor-pointer dc:hover:bg-dc-danger-bg text-dc-danger dc:transition-colors\"\n title=\"Remove\"\n >\n <DeleteIcon style={ICON_STYLE} />\n </button>\n </div>\n </div>\n\n {/* Portlet body */}\n <div className=\"dc:flex-1 dc:min-h-0\">\n <AnalyticsPortlet\n query={block.query}\n chartType={block.chartType}\n chartConfig={block.chartConfig}\n displayConfig={block.displayConfig}\n height={400}\n eagerLoad={true}\n onDebugDataReady={handleDebugDataReady}\n />\n </div>\n </div>\n )\n})\n\nexport default NotebookPortletBlock\n","/**\n * NotebookMarkdownBlock - Renders a markdown text block in the notebook\n * Uses markdown-to-jsx for full GFM support including tables\n *\n * Header matches NotebookPortletBlock pattern for visual consistency.\n */\n\nimport React from 'react'\nimport type { CSSProperties } from 'react'\nimport Markdown from 'markdown-to-jsx'\nimport type { MarkdownBlock } from '../../stores/notebookStore'\nimport { getIcon } from '../../icons/registry'\n\nconst ICON_STYLE: CSSProperties = { width: '16px', height: '16px', color: 'currentColor' }\n\nconst DocumentTextIcon = getIcon('documentText')\nconst ChevronUpIcon = getIcon('chevronUp')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst DeleteIcon = getIcon('delete')\n\ninterface NotebookMarkdownBlockProps {\n block: MarkdownBlock\n onRemove: (id: string) => void\n onMoveUp: (id: string) => void\n onMoveDown: (id: string) => void\n isFirst: boolean\n isLast: boolean\n}\n\n/** Scrollable table wrapper so wide tables don't overflow the block */\nfunction ScrollableTable({ children, ...props }: React.HTMLAttributes<HTMLTableElement>) {\n return (\n <div className=\"dc:overflow-x-auto dc:my-2\">\n <table {...props}>{children}</table>\n </div>\n )\n}\n\n/** markdown-to-jsx options with dc: themed overrides */\nconst markdownOptions = {\n overrides: {\n h1: { props: { className: 'dc:text-lg dc:font-bold text-dc-text dc:mb-2 dc:mt-3' } },\n h2: { props: { className: 'dc:text-base dc:font-semibold text-dc-text dc:mb-2 dc:mt-3' } },\n h3: { props: { className: 'dc:text-sm dc:font-semibold text-dc-text dc:mb-2 dc:mt-3' } },\n p: { props: { className: 'dc:text-sm dc:leading-relaxed text-dc-text dc:mb-2' } },\n strong: { props: { className: 'dc:font-semibold' } },\n a: { props: { className: 'text-dc-accent dc:hover:underline', target: '_blank', rel: 'noopener noreferrer' } },\n code: { props: { className: 'dc:px-1 dc:py-0.5 dc:rounded dc:text-xs bg-dc-surface-secondary text-dc-accent dc:font-mono' } },\n pre: { props: { className: 'dc:rounded-lg dc:p-3 dc:my-2 dc:overflow-x-auto dc:text-xs bg-dc-surface-secondary text-dc-text dc:font-mono' } },\n ul: { props: { className: 'dc:list-disc dc:ml-5 dc:mb-2 dc:text-sm text-dc-text dc:space-y-1' } },\n ol: { props: { className: 'dc:list-decimal dc:ml-5 dc:mb-2 dc:text-sm text-dc-text dc:space-y-1' } },\n li: { props: { className: 'dc:text-sm text-dc-text' } },\n hr: { props: { className: 'dc:my-3 border-dc-border' } },\n blockquote: { props: { className: 'dc:border-l-4 border-dc-accent dc:pl-3 dc:my-2 dc:italic text-dc-text-secondary dc:text-sm' } },\n table: { component: ScrollableTable, props: { className: 'dc:w-full dc:border-collapse dc:text-sm' } },\n thead: { props: { className: 'bg-dc-surface-secondary' } },\n th: { props: { className: 'dc:px-3 dc:py-2 dc:text-left dc:font-semibold dc:text-xs text-dc-text-secondary dc:uppercase dc:tracking-wider border-dc-border dc:border-b' } },\n td: { props: { className: 'dc:px-3 dc:py-2 dc:text-sm text-dc-text border-dc-border dc:border-b' } },\n tr: { props: { className: 'dc:hover:opacity-80' } },\n },\n}\n\nconst NotebookMarkdownBlock = React.memo(function NotebookMarkdownBlock({\n block,\n onRemove,\n onMoveUp,\n onMoveDown,\n isFirst,\n isLast,\n}: NotebookMarkdownBlockProps) {\n return (\n <div className=\"dc:relative dc:mb-4 bg-dc-surface dc:border border-dc-border dc:rounded-lg dc:flex dc:flex-col\">\n {/* Header - same pattern as NotebookPortletBlock / DashboardPortletCard */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-3 dc:py-1.5 dc:border-b border-dc-border dc:shrink-0 bg-dc-surface-secondary dc:rounded-t-lg\">\n <div className=\"dc:flex dc:items-center dc:gap-2 dc:flex-1 dc:min-w-0\">\n <DocumentTextIcon style={ICON_STYLE} />\n <h3 className=\"dc:font-semibold dc:text-sm text-dc-text dc:truncate\">\n {block.title || 'Markdown'}\n </h3>\n </div>\n <div className=\"dc:flex dc:items-center dc:gap-1 dc:shrink-0 dc:ml-4 dc:-mr-2\">\n {!isFirst && (\n <button\n onClick={() => onMoveUp(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move up\"\n >\n <ChevronUpIcon style={ICON_STYLE} />\n </button>\n )}\n {!isLast && (\n <button\n onClick={() => onMoveDown(block.id)}\n className=\"dc:p-1 dc:bg-transparent dc:border-none dc:rounded-sm text-dc-text-secondary dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Move down\"\n >\n <ChevronDownIcon style={ICON_STYLE} />\n </button>\n )}\n <button\n onClick={() => onRemove(block.id)}\n className=\"dc:p-1 dc:mr-0.5 dc:bg-transparent dc:border-none dc:rounded-sm dc:cursor-pointer dc:hover:bg-dc-danger-bg text-dc-danger dc:transition-colors\"\n title=\"Remove\"\n >\n <DeleteIcon style={ICON_STYLE} />\n </button>\n </div>\n </div>\n\n {/* Markdown content */}\n <div className=\"dc:p-4 dc:min-w-0 dc:overflow-hidden\">\n <Markdown options={markdownOptions}>\n {block.content}\n </Markdown>\n </div>\n </div>\n )\n})\n\nexport default NotebookMarkdownBlock\n","/**\n * NotebookCanvas - Left panel displaying notebook blocks\n */\n\nimport React, { useCallback, useRef, useEffect, useState } from 'react'\nimport { useShallow } from 'zustand/react/shallow'\nimport { useNotebookStore, selectBlocks, selectBlockActions } from '../../stores/notebookStore'\nimport type { PortletBlock } from '../../stores/notebookStore'\nimport type { PortletConfig } from '../../types'\nimport { ensureAnalysisConfig } from '../../utils/configMigration'\nimport NotebookPortletBlock from './NotebookPortletBlock'\nimport NotebookMarkdownBlock from './NotebookMarkdownBlock'\nimport PortletAnalysisModal from '../PortletAnalysisModal'\n\nconst NotebookCanvas = React.memo(function NotebookCanvas() {\n const blocks = useNotebookStore(selectBlocks)\n const { removeBlock, moveBlock, updateBlock } = useNotebookStore(useShallow(selectBlockActions))\n const endRef = useRef<HTMLDivElement>(null)\n\n // Edit modal state\n const [editingBlock, setEditingBlock] = useState<PortletBlock | null>(null)\n\n // Auto-scroll only when NEW blocks are added (not on initial load)\n const prevCountRef = useRef(blocks.length)\n useEffect(() => {\n if (blocks.length > prevCountRef.current) {\n endRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n prevCountRef.current = blocks.length\n }, [blocks.length])\n\n const handleRemove = useCallback((id: string) => removeBlock(id), [removeBlock])\n const handleMoveUp = useCallback((id: string) => moveBlock(id, 'up'), [moveBlock])\n const handleMoveDown = useCallback((id: string) => moveBlock(id, 'down'), [moveBlock])\n const handleEdit = useCallback((block: PortletBlock) => setEditingBlock(block), [])\n\n const handleEditSave = useCallback((portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => {\n if (!editingBlock) return\n\n // Normalize to ensure analysisConfig exists\n const normalized = ensureAnalysisConfig(portletData as PortletConfig)\n const { analysisConfig } = normalized\n\n if (analysisConfig) {\n const chartModeConfig = analysisConfig.charts[analysisConfig.analysisType]\n updateBlock(editingBlock.id, {\n title: portletData.title,\n query: JSON.stringify(analysisConfig.query),\n chartType: chartModeConfig?.chartType || 'bar',\n chartConfig: chartModeConfig?.chartConfig,\n displayConfig: chartModeConfig?.displayConfig,\n })\n }\n\n setEditingBlock(null)\n }, [editingBlock, updateBlock])\n\n if (blocks.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:h-full\">\n <div className=\"dc:text-center dc:max-w-sm dc:px-6\">\n <h3 className=\"dc:text-base dc:font-semibold text-dc-text dc:mb-2\">\n Your notebook is empty\n </h3>\n <p className=\"dc:text-sm text-dc-text-secondary\">\n Ask the AI assistant a question about your data.\n Charts and insights will appear here as the assistant analyzes your data.\n </p>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:h-full dc:overflow-y-auto dc:p-4\">\n {blocks.map((block, index) => {\n const isFirst = index === 0\n const isLast = index === blocks.length - 1\n\n if (block.type === 'portlet') {\n return (\n <NotebookPortletBlock\n key={block.id}\n block={block}\n onRemove={handleRemove}\n onMoveUp={handleMoveUp}\n onMoveDown={handleMoveDown}\n onEdit={handleEdit}\n isFirst={isFirst}\n isLast={isLast}\n />\n )\n }\n\n if (block.type === 'markdown') {\n return (\n <NotebookMarkdownBlock\n key={block.id}\n block={block}\n onRemove={handleRemove}\n onMoveUp={handleMoveUp}\n onMoveDown={handleMoveDown}\n isFirst={isFirst}\n isLast={isLast}\n />\n )\n }\n\n return null\n })}\n <div ref={endRef} />\n\n {/* Edit modal */}\n <PortletAnalysisModal\n isOpen={!!editingBlock}\n onClose={() => setEditingBlock(null)}\n onSave={handleEditSave}\n portlet={editingBlock ? {\n id: editingBlock.id,\n title: editingBlock.title,\n query: editingBlock.query,\n chartType: editingBlock.chartType,\n chartConfig: editingBlock.chartConfig,\n displayConfig: editingBlock.displayConfig,\n w: 5, h: 4, x: 0, y: 0,\n } : null}\n title=\"Edit Visualization\"\n submitText=\"Update\"\n />\n </div>\n )\n})\n\nexport default NotebookCanvas\n","/**\n * useAgentChat Hook\n * SSE streaming hook for the agentic notebook chat interface\n */\n\nimport { useRef, useCallback, useState } from 'react'\nimport { useCubeApi } from '../providers/CubeProvider'\nimport type { PortletBlock, MarkdownBlock } from '../stores/notebookStore'\n\n/** Clean up raw API errors into user-friendly messages */\nfunction formatUserFacingError(message: string): string {\n // Detect raw JSON error payloads (e.g. from Anthropic API)\n if (message.startsWith('{') || message.includes('\"type\":\"error\"')) {\n try {\n const parsed = JSON.parse(message.replace(/^Error:\\s*/, ''))\n const errorType = parsed.error?.type || parsed.type || ''\n const friendly: Record<string, string> = {\n overloaded_error: 'The AI service is temporarily busy. Please try again in a moment.',\n rate_limit_error: 'Too many requests. Please wait a moment and try again.',\n api_error: 'The AI service encountered an error. Please try again.',\n authentication_error: 'Authentication failed. Please check your configuration.',\n }\n return friendly[errorType] || 'The AI service encountered an error. Please try again.'\n } catch {\n return 'The AI service encountered an error. Please try again.'\n }\n }\n // HTTP status errors\n if (message.startsWith('Agent request failed:')) {\n const status = message.match(/\\d+/)?.[0]\n if (status === '429') return 'Too many requests. Please wait a moment and try again.'\n if (status === '503' || status === '529') return 'The AI service is temporarily busy. Please try again in a moment.'\n return 'The AI service is temporarily unavailable. Please try again.'\n }\n return message\n}\n\ninterface AgentSSEEvent {\n type: 'text_delta' | 'tool_use_start' | 'tool_use_result' | 'add_portlet' | 'add_markdown' | 'dashboard_saved' | 'turn_complete' | 'done' | 'error'\n data: any\n}\n\nexport interface UseAgentChatOptions {\n /** Override default agent endpoint (default: apiUrl + '/agent/chat') */\n agentEndpoint?: string\n /** Client-side API key for demo/try-site use */\n agentApiKey?: string\n /** Override LLM provider (anthropic | openai | google) */\n agentProvider?: string\n /** Override LLM model (e.g. 'gpt-4o', 'gemini-2.0-flash') */\n agentModel?: string\n /** Override provider endpoint URL (for OpenAI-compatible services) */\n agentProviderEndpoint?: string\n /** Called when agent adds a portlet to the notebook */\n onAddPortlet: (data: PortletBlock) => void\n /** Called when agent adds a markdown block to the notebook */\n onAddMarkdown: (data: MarkdownBlock) => void\n /** Called when the agent saves a dashboard configuration */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when streaming text arrives */\n onTextDelta: (text: string) => void\n /** Called when a tool call starts */\n onToolStart: (id: string, name: string, input?: unknown) => void\n /** Called when a tool call completes */\n onToolResult: (id: string, name: string, result?: unknown, isError?: boolean) => void\n /** Called when the agent completes with session ID and optional trace ID */\n onDone: (sessionId: string, traceId?: string) => void\n /** Called when a turn completes (between agentic turns) */\n onTurnComplete?: () => void\n /** Called on error */\n onError: (message: string) => void\n}\n\n/** Simplified message format for sending conversation history */\nexport interface AgentHistoryMessage {\n role: 'user' | 'assistant'\n content: string\n toolCalls?: Array<{\n id: string\n name: string\n input?: unknown\n result?: unknown\n status: 'running' | 'complete' | 'error'\n }>\n}\n\nexport interface UseAgentChatResult {\n /** Send a message to the agent, optionally with prior conversation history */\n sendMessage: (content: string, sessionId?: string | null, history?: AgentHistoryMessage[]) => Promise<void>\n /** Whether the agent is currently streaming */\n isStreaming: boolean\n /** Abort the current stream */\n abort: () => void\n}\n\n/**\n * Hook for streaming chat with the agentic notebook backend.\n * Uses fetch() with ReadableStream to consume SSE events.\n */\nexport function useAgentChat(options: UseAgentChatOptions): UseAgentChatResult {\n const { agentEndpoint, agentApiKey, agentProvider, agentModel, agentProviderEndpoint } = options\n\n const { cubeApi } = useCubeApi()\n const abortControllerRef = useRef<AbortController | null>(null)\n const [isStreaming, setIsStreaming] = useState(false)\n\n // Store callbacks in a ref so handleEvent always reads the latest\n // without causing sendMessage to be recreated on every render\n const callbacksRef = useRef(options)\n callbacksRef.current = options\n\n const sendMessage = useCallback(async (content: string, sessionId?: string | null, history?: AgentHistoryMessage[]) => {\n function handleEvent(event: AgentSSEEvent) {\n const cb = callbacksRef.current\n switch (event.type) {\n case 'text_delta':\n cb.onTextDelta(event.data)\n break\n case 'tool_use_start':\n cb.onToolStart(event.data.id, event.data.name, event.data.input)\n break\n case 'tool_use_result':\n cb.onToolResult(event.data.id, event.data.name, event.data.result, event.data.isError)\n break\n case 'add_portlet':\n cb.onAddPortlet({\n ...event.data,\n type: 'portlet',\n })\n break\n case 'add_markdown':\n cb.onAddMarkdown({\n ...event.data,\n type: 'markdown',\n })\n break\n case 'dashboard_saved':\n cb.onDashboardSaved?.(event.data)\n break\n case 'turn_complete':\n cb.onTurnComplete?.()\n break\n case 'done':\n cb.onDone(event.data.sessionId, event.data.traceId)\n break\n case 'error':\n cb.onError(event.data.message)\n break\n }\n }\n\n // Abort any existing stream\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n }\n\n const controller = new AbortController()\n abortControllerRef.current = controller\n setIsStreaming(true)\n\n try {\n // Build endpoint URL from CubeClient's API URL\n const apiUrl = (cubeApi as any).apiUrl || '/cubejs-api/v1'\n const endpoint = agentEndpoint || `${apiUrl}/agent/chat`\n\n // Build headers matching CubeClient's auth pattern\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(cubeApi as any).headers,\n }\n\n // Add agent API key if provided\n if (agentApiKey) {\n headers['X-Agent-Api-Key'] = agentApiKey\n }\n if (agentProvider) {\n headers['X-Agent-Provider'] = agentProvider\n }\n if (agentModel) {\n headers['X-Agent-Model'] = agentModel\n }\n if (agentProviderEndpoint) {\n headers['X-Agent-Provider-Endpoint'] = agentProviderEndpoint\n }\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n credentials: (cubeApi as any).credentials ?? 'include',\n body: JSON.stringify({\n message: content,\n ...(sessionId ? { sessionId } : {}),\n ...(history && history.length > 0 ? { history } : {}),\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(errorData.error || `Agent request failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('No response body received')\n }\n\n // Read SSE stream\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process complete SSE events (delimited by double newline)\n const events = buffer.split('\\n\\n')\n buffer = events.pop() || '' // Keep incomplete last chunk\n\n for (const eventStr of events) {\n const lines = eventStr.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event: AgentSSEEvent = JSON.parse(line.slice(6))\n handleEvent(event)\n } catch {\n // Skip malformed events\n }\n }\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n const lines = buffer.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event: AgentSSEEvent = JSON.parse(line.slice(6))\n handleEvent(event)\n } catch {\n // Skip malformed events\n }\n }\n }\n }\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n const raw = error instanceof Error ? error.message : 'Stream failed'\n callbacksRef.current.onError(formatUserFacingError(raw))\n }\n } finally {\n setIsStreaming(false)\n abortControllerRef.current = null\n }\n }, [cubeApi, agentEndpoint, agentApiKey, agentProvider, agentModel, agentProviderEndpoint])\n\n const abort = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort()\n abortControllerRef.current = null\n setIsStreaming(false)\n }\n }, [])\n\n return {\n sendMessage,\n isStreaming,\n abort,\n }\n}\n","/**\n * ChatMessage - Renders individual user and assistant messages\n */\n\nimport React, { useState } from 'react'\nimport type { ChatMessage as ChatMessageType, ToolCallRecord } from '../../stores/notebookStore'\nimport LoadingIndicator from '../LoadingIndicator'\n\n/** Simple inline markdown parser for bold, italic, and code in chat text */\nfunction renderInlineMarkdown(text: string): React.ReactNode[] {\n const nodes: React.ReactNode[] = []\n let remaining = text\n let key = 0\n\n while (remaining) {\n // Code inline `text`\n const codeMatch = remaining.match(/^(.*?)`([^`]+)`(.*)$/)\n if (codeMatch) {\n const [, before, code, after] = codeMatch\n if (before) nodes.push(<span key={key++}>{before}</span>)\n nodes.push(\n <code key={key++} className=\"dc:px-1 dc:py-0.5 dc:rounded dc:text-xs bg-dc-surface dc:font-mono\">\n {code}\n </code>\n )\n remaining = after\n continue\n }\n\n // Bold **text**\n const boldMatch = remaining.match(/^(.*?)\\*\\*([^*]+)\\*\\*(.*)$/)\n if (boldMatch) {\n const [, before, bold, after] = boldMatch\n if (before) nodes.push(<span key={key++}>{before}</span>)\n nodes.push(<strong key={key++} className=\"dc:font-semibold\">{bold}</strong>)\n remaining = after\n continue\n }\n\n // Plain text\n nodes.push(<span key={key}>{remaining}</span>)\n break\n }\n\n return nodes\n}\n\ninterface ChatMessageProps {\n message: ChatMessageType\n /** Custom loading indicator for tool call spinners */\n loadingComponent?: React.ReactNode\n}\n\n/** Tool call label mapping for user-friendly display */\nconst TOOL_LABELS: Record<string, string> = {\n discover_cubes: 'Discovering cubes',\n get_cube_metadata: 'Reading metadata',\n execute_query: 'Executing query',\n add_portlet: 'Adding visualization',\n add_markdown: 'Adding explanation',\n}\n\nfunction ToolCallIndicator({ toolCall, loadingComponent }: { toolCall: ToolCallRecord; loadingComponent?: React.ReactNode }) {\n const [expanded, setExpanded] = useState(false)\n const label = TOOL_LABELS[toolCall.name] || toolCall.name\n const isRunning = toolCall.status === 'running'\n\n return (\n <div className=\"dc:my-1 dc:text-xs\">\n <button\n onClick={() => setExpanded(!expanded)}\n className=\"dc:flex dc:items-center dc:gap-1.5 text-dc-text-secondary dc:hover:opacity-80 dc:transition-opacity\"\n >\n {isRunning ? (\n loadingComponent\n ? <span className=\"dc:inline-flex dc:items-center dc:justify-center dc:h-3 dc:w-3\">{loadingComponent}</span>\n : <LoadingIndicator size=\"xs\" />\n ) : (\n <span className=\"dc:text-xs\">\n {toolCall.status === 'error' ? '\\u2717' : '\\u2713'}\n </span>\n )}\n <span>{label}{isRunning ? '...' : ''}</span>\n {!isRunning && (\n <span className=\"dc:text-[10px] dc:opacity-60\">\n {expanded ? '\\u25B2' : '\\u25BC'}\n </span>\n )}\n </button>\n {expanded && toolCall.result != null && (\n <pre className=\"dc:mt-1 dc:p-2 dc:rounded dc:text-[11px] dc:overflow-x-auto dc:max-h-32 dc:overflow-y-auto bg-dc-surface-secondary text-dc-text-secondary\">\n {typeof toolCall.result === 'string'\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2)}\n </pre>\n )}\n </div>\n )\n}\n\nconst MSG_FADE_IN: React.CSSProperties = {\n animation: 'dc-msg-in 100ms ease-out',\n}\n\nconst ChatMessage = React.memo(function ChatMessage({ message, loadingComponent }: ChatMessageProps) {\n const isUser = message.role === 'user'\n const hasContent = !!message.content?.trim()\n const hasError = !!message.error\n const hasToolCalls = message.toolCalls && message.toolCalls.length > 0\n\n // Don't render empty assistant messages\n if (!isUser && !hasContent && !hasError && !hasToolCalls) return null\n\n return (\n <div\n className={`dc:flex dc:mb-3 ${isUser ? 'dc:justify-end' : 'dc:justify-start'}`}\n style={MSG_FADE_IN}\n >\n <div\n className={`dc:max-w-[85%] dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm ${\n isUser\n ? 'bg-dc-accent text-dc-accent-text dc:rounded-br-sm'\n : hasError && !hasContent\n ? 'bg-dc-warning-bg text-dc-text dc:rounded-bl-sm'\n : 'bg-dc-surface-secondary text-dc-text dc:rounded-bl-sm'\n }`}\n >\n {/* Message text */}\n {hasContent && (\n <div className=\"dc:whitespace-pre-wrap dc:break-words\">\n {isUser ? message.content : renderInlineMarkdown(message.content)}\n </div>\n )}\n\n {/* Error display */}\n {hasError && (\n <div className={`dc:flex dc:items-start dc:gap-2 ${hasContent ? 'dc:mt-2 dc:pt-2 dc:border-t dc:border-current dc:border-opacity-10' : ''}`}>\n <span className=\"dc:text-base dc:leading-none dc:mt-0.5 text-dc-warning dc:flex-shrink-0\">{'\\u26A0'}</span>\n <span className=\"text-dc-text-secondary\">{message.error}</span>\n </div>\n )}\n\n {/* Tool call indicators */}\n {hasToolCalls && (\n <div className={hasContent || hasError ? 'dc:mt-1 dc:border-t dc:border-current dc:border-opacity-10 dc:pt-1' : ''}>\n {message.toolCalls!.map((tc, i) => (\n <ToolCallIndicator key={tc.id || i} toolCall={tc} loadingComponent={loadingComponent} />\n ))}\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default ChatMessage\n","/**\n * ChatInput - Text input for sending messages to the agent\n */\n\nimport React, { useCallback, useRef, useEffect } from 'react'\n\ninterface ChatInputProps {\n value: string\n onChange: (value: string) => void\n onSend: () => void\n onStop?: () => void\n onContinue?: () => void\n isStreaming?: boolean\n showContinue?: boolean\n disabled?: boolean\n placeholder?: string\n}\n\nconst ChatInput = React.memo(function ChatInput({\n value,\n onChange,\n onSend,\n onStop,\n onContinue,\n isStreaming = false,\n showContinue = false,\n disabled = false,\n placeholder = 'Ask about your data...',\n}: ChatInputProps) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n // Auto-resize textarea\n useEffect(() => {\n const textarea = textareaRef.current\n if (textarea) {\n textarea.style.height = 'auto'\n textarea.style.height = `${Math.min(textarea.scrollHeight, 150)}px`\n }\n }, [value])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n if (!disabled && value.trim()) {\n onSend()\n }\n }\n },\n [disabled, value, onSend]\n )\n\n return (\n <div className=\"dc:flex dc:gap-2 dc:items-end dc:p-3 border-dc-border dc:border-t\">\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n className=\"dc:flex-1 dc:resize-none dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm bg-dc-surface-secondary text-dc-text border-dc-border dc:border dc:outline-none dc:focus:ring-1 focus:ring-dc-accent dc:disabled:opacity-50\"\n />\n {isStreaming ? (\n <button\n onClick={onStop}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors text-dc-error border-dc-border dc:border dc:hover:opacity-80 dc:shrink-0\"\n >\n Stop\n </button>\n ) : (\n <>\n {showContinue && !value.trim() && (\n <button\n onClick={() => {\n onContinue?.()\n textareaRef.current?.focus()\n }}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors border-dc-border dc:border text-dc-text-secondary dc:hover:opacity-80 dc:shrink-0\"\n >\n Continue\n </button>\n )}\n <button\n onClick={onSend}\n disabled={disabled || !value.trim()}\n className=\"dc:px-4 dc:py-2 dc:rounded-lg dc:text-sm dc:font-medium dc:transition-colors bg-dc-accent text-dc-accent-text dc:hover:opacity-90 dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:shrink-0\"\n >\n Send\n </button>\n </>\n )}\n </div>\n )\n})\n\nexport default ChatInput\n","/**\n * AgentChatPanel - Right panel containing chat messages and input\n */\n\nimport React, { useRef, useEffect, useCallback, useState } from 'react'\nimport { useShallow } from 'zustand/react/shallow'\nimport { useNotebookStore, selectChatState, selectChatActions } from '../../stores/notebookStore'\nimport { useAgentChat } from '../../hooks/useAgentChat'\nimport type { PortletBlock, MarkdownBlock, ChatMessage as ChatMessageType } from '../../stores/notebookStore'\nimport ChatMessage from './ChatMessage'\nimport ChatInput from './ChatInput'\nimport LoadingIndicator from '../LoadingIndicator'\nimport { getIcon } from '../../icons'\n\nconst ThumbUpIcon = getIcon('thumbUp')\nconst ThumbDownIcon = getIcon('thumbDown')\n\ninterface AgentChatPanelProps {\n agentEndpoint?: string\n agentApiKey?: string\n agentProvider?: string\n agentModel?: string\n agentProviderEndpoint?: string\n onClear?: () => void\n /** Called when the agent saves a dashboard. Presence enables the \"Save as Dashboard\" button. */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when user submits feedback (thumbs up/down) */\n onScore?: (data: { traceId: string; value: number; comment?: string }) => void\n /** Custom loading indicator for tool call spinners */\n loadingComponent?: React.ReactNode\n /** Initial prompt to auto-send on mount */\n initialPrompt?: string\n}\n\nconst AgentChatPanel = React.memo(function AgentChatPanel({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onClear,\n onDashboardSaved,\n onScore,\n loadingComponent,\n initialPrompt,\n}: AgentChatPanelProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const initialPromptSentRef = useRef(false)\n const [lastTraceId, setLastTraceId] = useState<string | null>(null)\n const [scoredTraceIds, setScoredTraceIds] = useState<Set<string>>(new Set())\n const [isThinking, setIsThinking] = useState(false)\n\n // Track whether the next content should start a new assistant message\n // (set after turn_complete, cleared when first content of new turn arrives)\n const needsNewMessageRef = useRef(false)\n\n // Store state\n const { messages, isStreaming, inputValue } = useNotebookStore(useShallow(selectChatState))\n const {\n addMessage,\n appendToLastAssistantMessage,\n setLastAssistantError,\n addToolCallToLastAssistant,\n updateLastToolCall,\n setIsStreaming,\n setInputValue,\n setSessionId,\n } = useNotebookStore(useShallow(selectChatActions))\n\n const sessionId = useNotebookStore((s) => s.sessionId)\n const addBlock = useNotebookStore((s) => s.addBlock)\n const reset = useNotebookStore((s) => s.reset)\n const portletBlockCount = useNotebookStore((s) => s.blocks.filter((b) => b.type === 'portlet').length)\n\n // Refs for values doSend reads at call-time (avoids recreating callbacks on every text delta)\n const messagesRef = useRef(messages)\n messagesRef.current = messages\n const isStreamingRef = useRef(isStreaming)\n isStreamingRef.current = isStreaming\n const sessionIdRef = useRef(sessionId)\n sessionIdRef.current = sessionId\n\n // Lazily create a new assistant message when needed (between turns)\n const ensureNewMessage = useCallback(() => {\n if (needsNewMessageRef.current) {\n needsNewMessageRef.current = false\n addMessage({\n id: `msg-${Date.now()}`,\n role: 'assistant',\n content: '',\n toolCalls: [],\n timestamp: Date.now(),\n })\n }\n }, [addMessage])\n\n // Auto-scroll only when NEW messages arrive or thinking starts (not on initial load)\n const prevMsgCountRef = useRef(messages.length)\n useEffect(() => {\n if (messages.length > prevMsgCountRef.current) {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n prevMsgCountRef.current = messages.length\n }, [messages])\n\n useEffect(() => {\n if (isThinking) {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [isThinking])\n\n // Agent chat hook\n const { sendMessage, abort } = useAgentChat({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onTextDelta: useCallback((text: string) => {\n setIsThinking(false)\n ensureNewMessage()\n appendToLastAssistantMessage(text)\n }, [ensureNewMessage, appendToLastAssistantMessage]),\n onToolStart: useCallback((id: string, name: string, input?: unknown) => {\n setIsThinking(false)\n ensureNewMessage()\n addToolCallToLastAssistant({ id, name, input, status: 'running' })\n }, [ensureNewMessage, addToolCallToLastAssistant]),\n onToolResult: useCallback((id: string, _name: string, result?: unknown, isError?: boolean) => {\n updateLastToolCall({ id, status: isError ? 'error' : 'complete', result })\n }, [updateLastToolCall]),\n onAddPortlet: useCallback((data: PortletBlock) => {\n addBlock(data)\n }, [addBlock]),\n onAddMarkdown: useCallback((data: MarkdownBlock) => {\n addBlock(data)\n }, [addBlock]),\n onDashboardSaved,\n onTurnComplete: useCallback(() => {\n // Don't create a new message yet — just flag that the next turn\n // should start a new bubble (created lazily by ensureNewMessage)\n needsNewMessageRef.current = true\n setIsThinking(true)\n }, []),\n onDone: useCallback((sid: string, traceId?: string) => {\n needsNewMessageRef.current = false\n setSessionId(sid)\n setIsStreaming(false)\n setIsThinking(false)\n if (traceId) setLastTraceId(traceId)\n }, [setSessionId, setIsStreaming]),\n onError: useCallback((message: string) => {\n setIsThinking(false)\n ensureNewMessage()\n setLastAssistantError(message)\n setIsStreaming(false)\n }, [ensureNewMessage, setLastAssistantError, setIsStreaming]),\n })\n\n // Send a message (used by both Send and Continue)\n // Reads messages/isStreaming/sessionId from refs to avoid recreating on every text delta\n const doSend = useCallback((content: string) => {\n if (!content || isStreamingRef.current) return\n\n needsNewMessageRef.current = false\n\n // Capture current messages as history BEFORE adding the new ones\n const history = messagesRef.current.map((m: ChatMessageType) => ({\n role: m.role,\n content: m.content,\n ...(m.toolCalls && m.toolCalls.length > 0 ? { toolCalls: m.toolCalls } : {}),\n }))\n\n // Add user message\n addMessage({\n id: `msg-${Date.now()}`,\n role: 'user',\n content,\n timestamp: Date.now(),\n })\n\n // Create empty assistant message for first turn's streaming\n addMessage({\n id: `msg-${Date.now() + 1}`,\n role: 'assistant',\n content: '',\n toolCalls: [],\n timestamp: Date.now(),\n })\n\n setInputValue('')\n setIsStreaming(true)\n setIsThinking(true)\n\n // Send to agent with conversation history for session continuity\n sendMessage(content, sessionIdRef.current, history)\n }, [addMessage, setInputValue, setIsStreaming, sendMessage])\n\n // Auto-send initial prompt on mount (doSend is stable so this won't re-trigger)\n // Reset ref on cleanup so React StrictMode's double-mount doesn't block the real mount\n useEffect(() => {\n if (initialPrompt && !initialPromptSentRef.current && messages.length === 0) {\n initialPromptSentRef.current = true\n // Small delay to ensure chat hook is fully initialized\n const timer = setTimeout(() => doSend(initialPrompt), 100)\n return () => {\n clearTimeout(timer)\n initialPromptSentRef.current = false\n }\n }\n }, [initialPrompt, messages.length, doSend])\n\n const inputValueRef = useRef(inputValue)\n inputValueRef.current = inputValue\n\n const handleSend = useCallback(() => {\n doSend(inputValueRef.current.trim())\n }, [doSend])\n\n const handleStop = useCallback(() => {\n abort()\n setIsStreaming(false)\n }, [abort, setIsStreaming])\n\n const handleContinue = useCallback(() => {\n // Just set placeholder text — user types their own follow-up and sends\n setInputValue('')\n }, [setInputValue])\n\n const handleClear = useCallback(() => {\n abort()\n setIsStreaming(false)\n setIsThinking(false)\n reset()\n setLastTraceId(null)\n setScoredTraceIds(new Set())\n onClear?.()\n }, [abort, setIsStreaming, reset, onClear])\n\n const handleSaveAsDashboard = useCallback(() => {\n doSend(\n 'Save the current notebook as a dashboard with a professional layout, section headers, and appropriate filters.'\n )\n }, [doSend])\n\n const handleScore = useCallback((value: number) => {\n if (!lastTraceId || !onScore) return\n onScore({ traceId: lastTraceId, value })\n setScoredTraceIds(prev => new Set(prev).add(lastTraceId))\n }, [lastTraceId, onScore])\n\n const showSaveAsDashboard = !!onDashboardSaved && !isStreaming && portletBlockCount > 0 && messages.length > 0\n const showFeedback = !!onScore && !isStreaming && lastTraceId && messages.length > 0 && !scoredTraceIds.has(lastTraceId)\n const lastScored = lastTraceId ? scoredTraceIds.has(lastTraceId) : false\n\n return (\n <div className=\"dc:flex dc:flex-col dc:h-full bg-dc-surface\">\n {/* Header */}\n <div className=\"dc:flex dc:items-center dc:justify-between dc:px-4 dc:py-3 border-dc-border dc:border-b\">\n <h3 className=\"dc:text-sm dc:font-semibold text-dc-text\">AI Assistant</h3>\n <div className=\"dc:flex dc:items-center dc:gap-1\">\n {showSaveAsDashboard && (\n <button\n onClick={handleSaveAsDashboard}\n className=\"dc:text-xs dc:px-2 dc:py-1 dc:rounded text-dc-accent dc:hover:opacity-80\"\n title=\"Save notebook as a dashboard\"\n >\n Save as Dashboard\n </button>\n )}\n {(messages.length > 0) && (\n <button\n onClick={handleClear}\n disabled={isStreaming}\n className=\"dc:text-xs dc:px-2 dc:py-1 dc:rounded text-dc-text-secondary dc:hover:opacity-80 dc:disabled:opacity-40\"\n title=\"Clear notebook and chat\"\n >\n Clear\n </button>\n )}\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"dc:flex-1 dc:overflow-y-auto dc:px-4 dc:py-3\">\n {messages.length === 0 ? (\n <EmptyState />\n ) : (\n messages.map((msg) => (\n <ChatMessage\n key={msg.id}\n message={msg}\n loadingComponent={loadingComponent}\n />\n ))\n )}\n {/* Thinking indicator (between turns or waiting for first response) */}\n {isThinking && <ThinkingBubble loadingComponent={loadingComponent} />}\n\n {/* Feedback (thumbs up/down) */}\n {(showFeedback || lastScored) && (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:gap-3 dc:py-4 dc:mt-2\">\n {lastScored ? (\n <span className=\"dc:text-sm text-dc-text-secondary\">Thanks for your feedback!</span>\n ) : (\n <>\n <span className=\"dc:text-sm text-dc-text-secondary\">Was this helpful?</span>\n <div className=\"dc:flex dc:items-center dc:gap-2\">\n <button\n onClick={() => handleScore(1)}\n className=\"dc:flex dc:items-center dc:gap-1.5 dc:px-3 dc:py-1.5 dc:rounded-lg dc:text-sm dc:font-medium border-dc-border dc:border text-dc-success hover:bg-dc-success-bg dc:transition-colors bg-dc-surface dc:cursor-pointer\"\n >\n <ThumbUpIcon className=\"dc:w-4 dc:h-4\" />\n Yes\n </button>\n <button\n onClick={() => handleScore(0)}\n className=\"dc:flex dc:items-center dc:gap-1.5 dc:px-3 dc:py-1.5 dc:rounded-lg dc:text-sm dc:font-medium border-dc-border dc:border text-dc-error hover:bg-dc-danger-bg dc:transition-colors bg-dc-surface dc:cursor-pointer\"\n >\n <ThumbDownIcon className=\"dc:w-4 dc:h-4\" />\n No\n </button>\n </div>\n </>\n )}\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input */}\n <ChatInput\n value={inputValue}\n onChange={setInputValue}\n onSend={handleSend}\n onStop={handleStop}\n onContinue={handleContinue}\n isStreaming={isStreaming}\n showContinue={!isStreaming && messages.length > 0}\n />\n </div>\n )\n})\n\nfunction ThinkingBubble({ loadingComponent }: { loadingComponent?: React.ReactNode }) {\n return (\n <div\n className=\"dc:flex dc:mb-3 dc:justify-start\"\n style={{ animation: 'dc-msg-in 100ms ease-out' }}\n >\n <div className=\"dc:rounded-lg dc:px-3 dc:py-2 dc:text-sm bg-dc-surface-secondary text-dc-text-secondary dc:rounded-bl-sm dc:flex dc:items-center dc:gap-2\">\n {loadingComponent\n ? <span className=\"dc:inline-flex dc:items-center dc:justify-center dc:h-4 dc:w-4\">{loadingComponent}</span>\n : <LoadingIndicator size=\"xs\" />}\n <span>Thinking...</span>\n </div>\n </div>\n )\n}\n\nfunction EmptyState() {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:h-full\">\n <div className=\"dc:text-center dc:max-w-xs\">\n <div className=\"dc:text-lg dc:font-semibold text-dc-text dc:mb-2\">\n Data Analysis Assistant\n </div>\n <p className=\"dc:text-sm text-dc-text-secondary dc:mb-4\">\n Ask me about your data and I'll create visualizations and insights.\n </p>\n <div className=\"dc:space-y-2 dc:text-xs text-dc-text-muted\">\n <p>\"Show me employee productivity trends\"</p>\n <p>\"What are the top departments by headcount?\"</p>\n <p>\"Compare revenue across product categories\"</p>\n </div>\n </div>\n </div>\n )\n}\n\nexport default AgentChatPanel\n","/**\n * AgenticNotebook - AI-powered data analysis notebook\n *\n * Top-level component combining a notebook canvas (left) with a chat panel (right).\n * The AI agent discovers available data, executes queries, creates visualizations,\n * and explains findings within a single conversational flow.\n *\n * Responsive behavior:\n * - Wide (>= 768px): Drag-resizable two-column layout\n * - Narrow (< 768px): Toggle between collapsed icon strip + expanded panel\n *\n * Requires:\n * - CubeProvider wrapping this component\n * - Server configured with `agent` option in HonoAdapterOptions\n * - @anthropic-ai/claude-agent-sdk installed on the server\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n NotebookStoreProvider,\n useNotebookStore,\n type NotebookBlock,\n type NotebookConfig,\n} from '../../stores/notebookStore'\nimport NotebookCanvas from './NotebookCanvas'\nimport AgentChatPanel from './AgentChatPanel'\nimport { useNotebookLayout } from '../../hooks/useNotebookLayout'\nimport { getChartTypeIcon, getIcon } from '../../icons/registry'\nimport type { ColorPalette } from '../../types'\nimport type { ReactNode } from 'react'\n\nexport interface AgenticNotebookProps {\n /** Initial config to restore (saved notebooks) */\n config?: NotebookConfig\n /** Override default agent endpoint (default: apiUrl + '/agent/chat') */\n agentEndpoint?: string\n /** Client-side API key (for demo/try-site use) */\n agentApiKey?: string\n /** Override LLM provider (anthropic | openai | google) */\n agentProvider?: string\n /** Override LLM model (e.g. 'gpt-4o', 'gemini-2.0-flash') */\n agentModel?: string\n /** Override provider endpoint URL (for OpenAI-compatible services) */\n agentProviderEndpoint?: string\n /** Callback when notebook state changes (for persistence) */\n onSave?: (config: NotebookConfig) => void | Promise<void>\n /** Callback when dirty state changes */\n onDirtyStateChange?: (isDirty: boolean) => void\n /** Color palette for charts */\n colorPalette?: ColorPalette\n /** Called when the agent saves a dashboard. Presence enables the \"Save as Dashboard\" button. */\n onDashboardSaved?: (data: { title: string; description?: string; dashboardConfig: any }) => void\n /** Called when user submits feedback (thumbs up/down). Receives traceId from the last agent response. */\n onScore?: (data: { traceId: string; value: number; comment?: string }) => void\n /** Custom loading indicator for tool call spinners (defaults to LoadingIndicator) */\n loadingComponent?: ReactNode\n /** Additional CSS class name */\n className?: string\n /** Initial prompt to auto-send on mount */\n initialPrompt?: string\n}\n\n/**\n * Collapsed strip showing notebook block icons (shown in narrow mode when chat is expanded)\n */\nfunction CollapsedNotebookStrip({\n blocks,\n pulsingBlockId,\n nudge,\n onExpand,\n}: {\n blocks: NotebookBlock[]\n pulsingBlockId: string | null\n nudge: boolean\n onExpand: () => void\n}) {\n const BookOpenIcon = getIcon('bookOpen')\n const DocumentIcon = getIcon('documentText')\n\n return (\n <button\n type=\"button\"\n onClick={onExpand}\n className=\"dc:h-full dc:flex-shrink-0 dc:flex dc:flex-col dc:items-center dc:pt-3 dc:gap-2 bg-dc-surface border-dc-border dc:border-r dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n style={\n nudge\n ? { animation: 'dc-strip-nudge 0.8s ease-in-out 2', width: 48 }\n : { width: 48 }\n }\n title=\"Expand notebook\"\n >\n <BookOpenIcon className=\"dc:w-5 dc:h-5 text-dc-text-muted\" />\n <div\n className=\"dc:flex dc:flex-col dc:items-center dc:gap-1.5 dc:flex-1 dc:overflow-y-auto dc:py-1\"\n style={{ scrollbarWidth: 'none' }}\n >\n {blocks.length === 0 ? (\n <span\n className=\"dc:text-[9px] text-dc-text-disabled dc:writing-vertical-lr dc:mt-2\"\n style={{ writingMode: 'vertical-lr' }}\n >\n No blocks\n </span>\n ) : (\n blocks.map((block) => {\n const isPulsing = block.id === pulsingBlockId\n let Icon: React.ComponentType<{ className?: string }>\n if (block.type === 'portlet') {\n Icon = getChartTypeIcon(block.chartType)\n } else {\n Icon = DocumentIcon\n }\n return (\n <div\n key={block.id}\n className=\"dc:w-6 dc:h-6 dc:flex dc:items-center dc:justify-center dc:rounded\"\n style={\n isPulsing\n ? { animation: 'dc-icon-pulse 0.6s ease-in-out 3' }\n : undefined\n }\n title={block.type === 'portlet' ? block.title : (block.title || 'Markdown')}\n >\n <Icon className=\"dc:w-4 dc:h-4 text-dc-text-muted\" />\n </div>\n )\n })\n )}\n </div>\n </button>\n )\n}\n\n/**\n * Collapsed strip showing AI chat icon (shown in narrow mode when notebook is expanded)\n */\nfunction CollapsedChatStrip({ onExpand }: { onExpand: () => void }) {\n const SparklesIcon = getIcon('sparkles')\n\n return (\n <button\n type=\"button\"\n onClick={onExpand}\n className=\"dc:w-12 dc:h-full dc:flex-shrink-0 dc:flex dc:flex-col dc:items-center dc:pt-3 dc:gap-2 bg-dc-surface border-dc-border dc:border-l dc:cursor-pointer dc:hover:bg-dc-surface-hover dc:transition-colors\"\n title=\"Expand AI chat\"\n >\n <SparklesIcon className=\"dc:w-5 dc:h-5 text-dc-accent\" />\n <span\n className=\"dc:text-[10px] dc:font-medium text-dc-text-muted\"\n style={{ writingMode: 'vertical-lr' }}\n >\n AI Chat\n </span>\n </button>\n )\n}\n\n/**\n * Inner component that uses the notebook store (must be inside provider)\n */\nfunction AgenticNotebookInner({\n agentEndpoint,\n agentApiKey,\n agentProvider,\n agentModel,\n agentProviderEndpoint,\n onSave,\n onDirtyStateChange,\n onDashboardSaved,\n onScore,\n loadingComponent,\n className,\n initialPrompt,\n}: Omit<AgenticNotebookProps, 'config' | 'colorPalette'>) {\n const [dividerPosition, setDividerPosition] = useState(60) // 60% left, 40% right\n const dividerContainerRef = useRef<HTMLDivElement | null>(null)\n const isDraggingRef = useRef(false)\n\n // Responsive layout\n const { containerRef: layoutRef, layoutMode } = useNotebookLayout()\n const [expandedPanel, setExpandedPanel] = useState<'chat' | 'notebook'>('chat')\n const [pulsingBlockId, setPulsingBlockId] = useState<string | null>(null)\n const [nudgeStrip, setNudgeStrip] = useState(false)\n const prevLayoutModeRef = useRef(layoutMode)\n\n const blocks = useNotebookStore((s) => s.blocks)\n const blockCount = blocks.length\n const messageCount = useNotebookStore((s) => s.messages.length)\n const isStreaming = useNotebookStore((s) => s.isStreaming)\n const save = useNotebookStore((s) => s.save)\n\n // Reset to chat when crossing from narrow → wide\n useEffect(() => {\n if (prevLayoutModeRef.current === 'narrow' && layoutMode === 'wide') {\n setExpandedPanel('chat')\n }\n prevLayoutModeRef.current = layoutMode\n }, [layoutMode])\n\n // Detect new blocks added while notebook is collapsed → pulse the icon\n const prevBlockCountRef = useRef(blockCount)\n useEffect(() => {\n if (\n layoutMode === 'narrow' &&\n expandedPanel === 'chat' &&\n blockCount > prevBlockCountRef.current\n ) {\n // Find the newest block (last in the array)\n const newestBlock = blocks[blocks.length - 1]\n if (newestBlock) {\n setPulsingBlockId(newestBlock.id)\n const timer = setTimeout(() => setPulsingBlockId(null), 2000)\n return () => clearTimeout(timer)\n }\n }\n prevBlockCountRef.current = blockCount\n }, [blockCount, blocks, layoutMode, expandedPanel])\n\n // Nudge the notebook strip when streaming ends while collapsed and there are blocks\n const wasStreamingRef = useRef(false)\n useEffect(() => {\n if (isStreaming) {\n wasStreamingRef.current = true\n } else if (\n wasStreamingRef.current &&\n layoutMode === 'narrow' &&\n expandedPanel === 'chat' &&\n blockCount > 0\n ) {\n wasStreamingRef.current = false\n setNudgeStrip(true)\n const timer = setTimeout(() => setNudgeStrip(false), 1700)\n return () => clearTimeout(timer)\n }\n }, [isStreaming, layoutMode, expandedPanel, blockCount])\n\n // Merge refs: layoutRef (RefCallback) + dividerContainerRef (for drag calculations)\n const mergedRef = useCallback(\n (node: HTMLDivElement | null) => {\n layoutRef(node)\n dividerContainerRef.current = node\n },\n [layoutRef],\n )\n\n // Track dirty state\n const initialRef = useRef({ blockCount, msgCount: messageCount })\n useEffect(() => {\n const isDirty =\n blockCount !== initialRef.current.blockCount ||\n messageCount !== initialRef.current.msgCount\n onDirtyStateChange?.(isDirty)\n }, [blockCount, messageCount, onDirtyStateChange])\n\n // Debounced save - fires 1s after blocks/messages count stabilizes\n // Waits until streaming completes to avoid saving partial content\n const saveTimeoutRef = useRef<ReturnType<typeof setTimeout>>()\n const pendingSaveRef = useRef(false)\n const onSaveRef = useRef(onSave)\n onSaveRef.current = onSave\n // Track whether we've ever had content (so we save empty state on Clear but not on initial mount)\n const hasHadContentRef = useRef(blockCount > 0 || messageCount > 0)\n useEffect(() => {\n if (blockCount > 0 || messageCount > 0) {\n hasHadContentRef.current = true\n }\n if (!onSaveRef.current || !hasHadContentRef.current) return\n\n if (isStreaming) {\n // Mark that a save is needed once streaming completes\n pendingSaveRef.current = true\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n return\n }\n\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n saveTimeoutRef.current = setTimeout(() => {\n pendingSaveRef.current = false\n const config = save()\n onSaveRef.current?.(config)\n }, 1000)\n\n return () => {\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n }\n }, [blockCount, messageCount, isStreaming, save])\n\n // Flush pending save when streaming ends\n useEffect(() => {\n if (!isStreaming && pendingSaveRef.current && onSaveRef.current && hasHadContentRef.current) {\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n saveTimeoutRef.current = setTimeout(() => {\n pendingSaveRef.current = false\n const config = save()\n onSaveRef.current?.(config)\n }, 1000)\n }\n }, [isStreaming, save])\n\n // Explicit clear handler — save immediately with empty state\n const handleClear = useCallback(() => {\n if (onSaveRef.current) {\n // Cancel any pending debounced save\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n onSaveRef.current({ blocks: [], messages: [] })\n }\n }, [])\n\n // Divider drag handlers\n const handleDividerMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n isDraggingRef.current = true\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (!isDraggingRef.current || !dividerContainerRef.current) return\n const rect = dividerContainerRef.current.getBoundingClientRect()\n const newPos = ((moveEvent.clientX - rect.left) / rect.width) * 100\n setDividerPosition(Math.min(Math.max(newPos, 30), 80))\n }\n\n const handleMouseUp = () => {\n isDraggingRef.current = false\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n }\n\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n }, [])\n\n const chatPanel = (\n <AgentChatPanel\n agentEndpoint={agentEndpoint}\n agentApiKey={agentApiKey}\n agentProvider={agentProvider}\n agentModel={agentModel}\n agentProviderEndpoint={agentProviderEndpoint}\n onClear={handleClear}\n onDashboardSaved={onDashboardSaved}\n onScore={onScore}\n loadingComponent={loadingComponent}\n initialPrompt={initialPrompt}\n />\n )\n\n // --- Narrow mode: collapsed strip + expanded panel ---\n if (layoutMode === 'narrow') {\n return (\n <div\n ref={mergedRef}\n className={`dc:flex dc:h-full dc:w-full dc:overflow-hidden bg-dc-surface-secondary ${className || ''}`}\n >\n {expandedPanel === 'chat' ? (\n <>\n <CollapsedNotebookStrip\n blocks={blocks}\n pulsingBlockId={pulsingBlockId}\n nudge={nudgeStrip}\n onExpand={() => setExpandedPanel('notebook')}\n />\n <div className=\"dc:h-full dc:overflow-hidden dc:flex-1\">\n {chatPanel}\n </div>\n </>\n ) : (\n <>\n <div className=\"dc:h-full dc:overflow-hidden dc:flex-1\">\n <NotebookCanvas />\n </div>\n <CollapsedChatStrip onExpand={() => setExpandedPanel('chat')} />\n </>\n )}\n </div>\n )\n }\n\n // --- Wide mode: existing drag-resizable two-column layout ---\n return (\n <div\n ref={mergedRef}\n className={`dc:flex dc:h-full dc:w-full dc:overflow-hidden bg-dc-surface-secondary ${className || ''}`}\n >\n {/* Left: Notebook Canvas */}\n <div\n className=\"dc:h-full dc:overflow-hidden\"\n style={{ width: `${dividerPosition}%` }}\n >\n <NotebookCanvas />\n </div>\n\n {/* Resizable Divider */}\n <div\n className=\"dc:w-1 dc:h-full dc:cursor-col-resize dc:flex-shrink-0 dc:transition-colors bg-dc-border dc:hover:bg-dc-accent\"\n onMouseDown={handleDividerMouseDown}\n />\n\n {/* Right: Chat Panel */}\n <div\n className=\"dc:h-full dc:overflow-hidden\"\n style={{ width: `${100 - dividerPosition}%` }}\n >\n {chatPanel}\n </div>\n </div>\n )\n}\n\n/**\n * AgenticNotebook - AI-powered data analysis notebook\n *\n * @example\n * ```tsx\n * <CubeProvider apiOptions={{ apiUrl: '/api/cubejs-api/v1' }} token={token}>\n * <AgenticNotebook\n * agentApiKey=\"sk-...\"\n * onSave={(config) => saveToDatabase(config)}\n * />\n * </CubeProvider>\n * ```\n */\nconst AgenticNotebook = React.memo(function AgenticNotebook({\n config,\n ...props\n}: AgenticNotebookProps) {\n return (\n <NotebookStoreProvider initialConfig={config}>\n <AgenticNotebookInner {...props} />\n </NotebookStoreProvider>\n )\n})\n\nexport default AgenticNotebook\n","// Placeholder component - will be implemented in Phase 4\nexport function AnalyticsPage() {\n return <div>Analytics Page - Coming in Phase 4</div>\n}","/**\n * DashboardThumbnailPlaceholder\n *\n * A placeholder component shown when a dashboard thumbnail doesn't exist\n * but the thumbnail feature is enabled. Displays a simple grid icon\n * with \"No preview\" text.\n */\n\nimport { getIcon } from '../icons'\n\nconst GridIcon = getIcon('segment')\n\nexport interface DashboardThumbnailPlaceholderProps {\n /** Additional CSS classes */\n className?: string\n}\n\nexport function DashboardThumbnailPlaceholder({\n className = ''\n}: DashboardThumbnailPlaceholderProps) {\n return (\n <div\n className={`dc:flex dc:items-center dc:justify-center bg-dc-bg-secondary ${className}`}\n >\n <div className=\"dc:text-center\">\n <GridIcon\n className=\"dc:w-8 dc:h-8 dc:mx-auto dc:mb-2 text-dc-text-muted dc:opacity-50\"\n />\n <span className=\"dc:text-xs text-dc-text-muted\">No preview</span>\n </div>\n </div>\n )\n}\n\nexport default DashboardThumbnailPlaceholder\n"],"names":["createDefaultState","createStoreActions","set","get","block","state","id","b","direction","idx","newBlocks","swapIdx","updates","message","text","messages","lastMsg","error","toolCall","update","toolCalls","tc","streaming","value","config","createNotebookStore","initialState","createStore","devtools","subscribeWithSelector","NotebookStoreContext","createContext","NotebookStoreProvider","children","initialConfig","storeRef","useRef","store","useNotebookStore","selector","useContext","useStore","selectBlocks","selectMessages","selectIsStreaming","selectSessionId","selectInputValue","selectChatState","selectChatActions","selectBlockActions","ICON_STYLE","ChevronUpIcon","getIcon","ChevronDownIcon","EditIcon","DeleteIcon","NotebookPortletBlock","React","onRemove","onMoveUp","onMoveDown","onEdit","isFirst","isLast","debugData","setDebugData","useState","handleDebugDataReady","useCallback","data","jsxs","jsx","DebugModal","AnalyticsPortlet","DocumentTextIcon","ScrollableTable","props","markdownOptions","NotebookMarkdownBlock","Markdown","NotebookCanvas","blocks","removeBlock","moveBlock","updateBlock","useShallow","endRef","editingBlock","setEditingBlock","prevCountRef","useEffect","handleRemove","handleMoveUp","handleMoveDown","handleEdit","handleEditSave","portletData","normalized","ensureAnalysisConfig","analysisConfig","chartModeConfig","index","PortletAnalysisModal","formatUserFacingError","parsed","errorType","status","useAgentChat","options","agentEndpoint","agentApiKey","agentProvider","agentModel","agentProviderEndpoint","cubeApi","useCubeApi","abortControllerRef","isStreaming","setIsStreaming","callbacksRef","sendMessage","content","sessionId","history","handleEvent","event","cb","controller","apiUrl","endpoint","headers","response","errorData","reader","decoder","buffer","done","events","eventStr","lines","line","raw","abort","renderInlineMarkdown","nodes","remaining","key","codeMatch","before","code","after","boldMatch","bold","TOOL_LABELS","ToolCallIndicator","loadingComponent","expanded","setExpanded","label","isRunning","LoadingIndicator","MSG_FADE_IN","ChatMessage","isUser","hasContent","hasError","hasToolCalls","i","ChatInput","onChange","onSend","onStop","onContinue","showContinue","disabled","placeholder","textareaRef","textarea","handleKeyDown","e","Fragment","ThumbUpIcon","ThumbDownIcon","AgentChatPanel","onClear","onDashboardSaved","onScore","initialPrompt","messagesEndRef","initialPromptSentRef","lastTraceId","setLastTraceId","scoredTraceIds","setScoredTraceIds","isThinking","setIsThinking","needsNewMessageRef","inputValue","addMessage","appendToLastAssistantMessage","setLastAssistantError","addToolCallToLastAssistant","updateLastToolCall","setInputValue","setSessionId","s","addBlock","reset","portletBlockCount","messagesRef","isStreamingRef","sessionIdRef","ensureNewMessage","prevMsgCountRef","name","input","_name","result","isError","sid","traceId","doSend","m","timer","inputValueRef","handleSend","handleStop","handleContinue","handleClear","handleSaveAsDashboard","handleScore","prev","showSaveAsDashboard","showFeedback","lastScored","EmptyState","msg","ThinkingBubble","CollapsedNotebookStrip","pulsingBlockId","nudge","onExpand","BookOpenIcon","DocumentIcon","isPulsing","Icon","getChartTypeIcon","CollapsedChatStrip","SparklesIcon","AgenticNotebookInner","onSave","onDirtyStateChange","className","dividerPosition","setDividerPosition","dividerContainerRef","isDraggingRef","layoutRef","layoutMode","useNotebookLayout","expandedPanel","setExpandedPanel","setPulsingBlockId","nudgeStrip","setNudgeStrip","prevLayoutModeRef","blockCount","messageCount","save","prevBlockCountRef","newestBlock","wasStreamingRef","mergedRef","node","initialRef","isDirty","saveTimeoutRef","pendingSaveRef","onSaveRef","hasHadContentRef","handleDividerMouseDown","handleMouseMove","moveEvent","rect","newPos","handleMouseUp","chatPanel","AgenticNotebook","AnalyticsPage","GridIcon","DashboardThumbnailPlaceholder"],"mappings":"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"}
|
package/dist/client/providers.js
CHANGED