@seed-ship/mcp-ui-solid 6.19.1 → 6.20.0

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.
Files changed (257) hide show
  1. package/CHANGELOG.md +519 -0
  2. package/README.md +791 -1
  3. package/dist/adapters/connector.cjs +15 -4
  4. package/dist/adapters/connector.cjs.map +1 -1
  5. package/dist/adapters/connector.d.ts +38 -0
  6. package/dist/adapters/connector.d.ts.map +1 -1
  7. package/dist/adapters/connector.js +15 -4
  8. package/dist/adapters/connector.js.map +1 -1
  9. package/dist/adapters/index.d.ts +4 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/macro-run.cjs +25 -13
  12. package/dist/adapters/macro-run.cjs.map +1 -1
  13. package/dist/adapters/macro-run.d.ts +37 -2
  14. package/dist/adapters/macro-run.d.ts.map +1 -1
  15. package/dist/adapters/macro-run.js +25 -13
  16. package/dist/adapters/macro-run.js.map +1 -1
  17. package/dist/adapters.cjs +2 -0
  18. package/dist/adapters.cjs.map +1 -1
  19. package/dist/adapters.js +4 -2
  20. package/dist/components/ActionGroupRenderer.cjs +3 -1
  21. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  22. package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
  23. package/dist/components/ActionGroupRenderer.js +3 -1
  24. package/dist/components/ActionGroupRenderer.js.map +1 -1
  25. package/dist/components/AgentCard.cjs +11 -8
  26. package/dist/components/AgentCard.cjs.map +1 -1
  27. package/dist/components/AgentCard.d.ts.map +1 -1
  28. package/dist/components/AgentCard.js +11 -8
  29. package/dist/components/AgentCard.js.map +1 -1
  30. package/dist/components/AgentHandoff.cjs +6 -1
  31. package/dist/components/AgentHandoff.cjs.map +1 -1
  32. package/dist/components/AgentHandoff.d.ts.map +1 -1
  33. package/dist/components/AgentHandoff.js +6 -1
  34. package/dist/components/AgentHandoff.js.map +1 -1
  35. package/dist/components/ArtifactRenderer.cjs +25 -6
  36. package/dist/components/ArtifactRenderer.cjs.map +1 -1
  37. package/dist/components/ArtifactRenderer.d.ts.map +1 -1
  38. package/dist/components/ArtifactRenderer.js +25 -6
  39. package/dist/components/ArtifactRenderer.js.map +1 -1
  40. package/dist/components/AutocompleteDropdown.cjs +30 -24
  41. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  42. package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
  43. package/dist/components/AutocompleteDropdown.js +30 -24
  44. package/dist/components/AutocompleteDropdown.js.map +1 -1
  45. package/dist/components/AutocompleteFormField.cjs +3 -1
  46. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  47. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  48. package/dist/components/AutocompleteFormField.js +4 -2
  49. package/dist/components/AutocompleteFormField.js.map +1 -1
  50. package/dist/components/BriefingDiff.cjs +45 -39
  51. package/dist/components/BriefingDiff.cjs.map +1 -1
  52. package/dist/components/BriefingDiff.d.ts.map +1 -1
  53. package/dist/components/BriefingDiff.js +45 -39
  54. package/dist/components/BriefingDiff.js.map +1 -1
  55. package/dist/components/CarouselRenderer.cjs +8 -2
  56. package/dist/components/CarouselRenderer.cjs.map +1 -1
  57. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  58. package/dist/components/CarouselRenderer.js +8 -2
  59. package/dist/components/CarouselRenderer.js.map +1 -1
  60. package/dist/components/ChartJSRenderer.cjs +60 -36
  61. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  62. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  63. package/dist/components/ChartJSRenderer.js +61 -37
  64. package/dist/components/ChartJSRenderer.js.map +1 -1
  65. package/dist/components/ChatPrompt.cjs +15 -9
  66. package/dist/components/ChatPrompt.cjs.map +1 -1
  67. package/dist/components/ChatPrompt.d.ts.map +1 -1
  68. package/dist/components/ChatPrompt.js +15 -9
  69. package/dist/components/ChatPrompt.js.map +1 -1
  70. package/dist/components/CodeBlockRenderer.cjs +34 -16
  71. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  72. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  73. package/dist/components/CodeBlockRenderer.js +34 -16
  74. package/dist/components/CodeBlockRenderer.js.map +1 -1
  75. package/dist/components/DataPreviewSection.cjs +91 -44
  76. package/dist/components/DataPreviewSection.cjs.map +1 -1
  77. package/dist/components/DataPreviewSection.d.ts.map +1 -1
  78. package/dist/components/DataPreviewSection.js +92 -45
  79. package/dist/components/DataPreviewSection.js.map +1 -1
  80. package/dist/components/DegradedFallback.cjs +20 -16
  81. package/dist/components/DegradedFallback.cjs.map +1 -1
  82. package/dist/components/DegradedFallback.d.ts.map +1 -1
  83. package/dist/components/DegradedFallback.js +20 -16
  84. package/dist/components/DegradedFallback.js.map +1 -1
  85. package/dist/components/FooterRenderer.cjs +21 -17
  86. package/dist/components/FooterRenderer.cjs.map +1 -1
  87. package/dist/components/FooterRenderer.d.ts.map +1 -1
  88. package/dist/components/FooterRenderer.js +21 -17
  89. package/dist/components/FooterRenderer.js.map +1 -1
  90. package/dist/components/FormFieldRenderer.cjs +116 -93
  91. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  92. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  93. package/dist/components/FormFieldRenderer.js +116 -93
  94. package/dist/components/FormFieldRenderer.js.map +1 -1
  95. package/dist/components/FormRenderer.cjs +55 -31
  96. package/dist/components/FormRenderer.cjs.map +1 -1
  97. package/dist/components/FormRenderer.d.ts.map +1 -1
  98. package/dist/components/FormRenderer.js +55 -31
  99. package/dist/components/FormRenderer.js.map +1 -1
  100. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  101. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  102. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  103. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  104. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  105. package/dist/components/GraphRenderer.cjs +56 -33
  106. package/dist/components/GraphRenderer.cjs.map +1 -1
  107. package/dist/components/GraphRenderer.d.ts.map +1 -1
  108. package/dist/components/GraphRenderer.js +56 -33
  109. package/dist/components/GraphRenderer.js.map +1 -1
  110. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  111. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  112. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  113. package/dist/components/ImageGalleryRenderer.js +13 -4
  114. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  115. package/dist/components/LightboxOverlay.cjs +16 -8
  116. package/dist/components/LightboxOverlay.cjs.map +1 -1
  117. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  118. package/dist/components/LightboxOverlay.js +17 -9
  119. package/dist/components/LightboxOverlay.js.map +1 -1
  120. package/dist/components/MapRenderer.cjs +59 -29
  121. package/dist/components/MapRenderer.cjs.map +1 -1
  122. package/dist/components/MapRenderer.d.ts +10 -2
  123. package/dist/components/MapRenderer.d.ts.map +1 -1
  124. package/dist/components/MapRenderer.js +60 -30
  125. package/dist/components/MapRenderer.js.map +1 -1
  126. package/dist/components/ModalRenderer.cjs +4 -1
  127. package/dist/components/ModalRenderer.cjs.map +1 -1
  128. package/dist/components/ModalRenderer.d.ts.map +1 -1
  129. package/dist/components/ModalRenderer.js +5 -2
  130. package/dist/components/ModalRenderer.js.map +1 -1
  131. package/dist/components/ScratchpadPanel.cjs +578 -535
  132. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  133. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  134. package/dist/components/ScratchpadPanel.js +578 -535
  135. package/dist/components/ScratchpadPanel.js.map +1 -1
  136. package/dist/components/StreamingUIRenderer.cjs +92 -28
  137. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  138. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  139. package/dist/components/StreamingUIRenderer.js +92 -28
  140. package/dist/components/StreamingUIRenderer.js.map +1 -1
  141. package/dist/components/UIResourceRenderer.cjs +456 -363
  142. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  143. package/dist/components/UIResourceRenderer.d.ts +21 -0
  144. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  145. package/dist/components/UIResourceRenderer.js +458 -365
  146. package/dist/components/UIResourceRenderer.js.map +1 -1
  147. package/dist/components/VerifiedText.cjs +39 -20
  148. package/dist/components/VerifiedText.cjs.map +1 -1
  149. package/dist/components/VerifiedText.d.ts +2 -1
  150. package/dist/components/VerifiedText.d.ts.map +1 -1
  151. package/dist/components/VerifiedText.js +39 -20
  152. package/dist/components/VerifiedText.js.map +1 -1
  153. package/dist/components/VideoRenderer.cjs +10 -5
  154. package/dist/components/VideoRenderer.cjs.map +1 -1
  155. package/dist/components/VideoRenderer.d.ts.map +1 -1
  156. package/dist/components/VideoRenderer.js +10 -5
  157. package/dist/components/VideoRenderer.js.map +1 -1
  158. package/dist/components/chart-data-table.cjs +38 -17
  159. package/dist/components/chart-data-table.cjs.map +1 -1
  160. package/dist/components/chart-data-table.d.ts +30 -1
  161. package/dist/components/chart-data-table.d.ts.map +1 -1
  162. package/dist/components/chart-data-table.js +38 -17
  163. package/dist/components/chart-data-table.js.map +1 -1
  164. package/dist/context/MCPActionContext.cjs +3 -1
  165. package/dist/context/MCPActionContext.cjs.map +1 -1
  166. package/dist/context/MCPActionContext.d.ts.map +1 -1
  167. package/dist/context/MCPActionContext.js +3 -1
  168. package/dist/context/MCPActionContext.js.map +1 -1
  169. package/dist/context/MCPUIStringsContext.cjs +285 -2
  170. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  171. package/dist/context/MCPUIStringsContext.d.ts +600 -3
  172. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  173. package/dist/context/MCPUIStringsContext.js +285 -2
  174. package/dist/context/MCPUIStringsContext.js.map +1 -1
  175. package/dist/hooks/index.d.ts +2 -2
  176. package/dist/hooks/index.d.ts.map +1 -1
  177. package/dist/hooks/useStreamingUI.cjs +28 -10
  178. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  179. package/dist/hooks/useStreamingUI.d.ts +37 -0
  180. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  181. package/dist/hooks/useStreamingUI.js +28 -10
  182. package/dist/hooks/useStreamingUI.js.map +1 -1
  183. package/dist/hooks.cjs +1 -0
  184. package/dist/hooks.cjs.map +1 -1
  185. package/dist/hooks.js +2 -1
  186. package/dist/index.cjs +23 -8
  187. package/dist/index.cjs.map +1 -1
  188. package/dist/index.d.cts +9 -3
  189. package/dist/index.d.ts +9 -3
  190. package/dist/index.d.ts.map +1 -1
  191. package/dist/index.js +18 -3
  192. package/dist/index.js.map +1 -1
  193. package/dist/services/validation.cjs +41 -16
  194. package/dist/services/validation.cjs.map +1 -1
  195. package/dist/services/validation.d.ts +47 -2
  196. package/dist/services/validation.d.ts.map +1 -1
  197. package/dist/services/validation.js +41 -16
  198. package/dist/services/validation.js.map +1 -1
  199. package/dist/utils/degraded-projections.cjs +37 -12
  200. package/dist/utils/degraded-projections.cjs.map +1 -1
  201. package/dist/utils/degraded-projections.d.ts +39 -3
  202. package/dist/utils/degraded-projections.d.ts.map +1 -1
  203. package/dist/utils/degraded-projections.js +37 -12
  204. package/dist/utils/degraded-projections.js.map +1 -1
  205. package/dist/utils/format-string.cjs +10 -0
  206. package/dist/utils/format-string.cjs.map +1 -0
  207. package/dist/utils/format-string.d.ts +26 -0
  208. package/dist/utils/format-string.d.ts.map +1 -0
  209. package/dist/utils/format-string.js +10 -0
  210. package/dist/utils/format-string.js.map +1 -0
  211. package/dist/validation.cjs +3 -0
  212. package/dist/validation.cjs.map +1 -1
  213. package/dist/validation.d.cts +2 -1
  214. package/dist/validation.d.ts +2 -1
  215. package/dist/validation.d.ts.map +1 -1
  216. package/dist/validation.js +4 -1
  217. package/package.json +1 -1
  218. package/src/adapters/connector.ts +58 -4
  219. package/src/adapters/index.ts +12 -2
  220. package/src/adapters/macro-run.ts +71 -11
  221. package/src/components/ActionGroupRenderer.tsx +3 -1
  222. package/src/components/AgentCard.tsx +27 -9
  223. package/src/components/AgentHandoff.tsx +4 -1
  224. package/src/components/ArtifactRenderer.tsx +17 -5
  225. package/src/components/AutocompleteDropdown.tsx +8 -6
  226. package/src/components/AutocompleteFormField.tsx +5 -1
  227. package/src/components/BriefingDiff.tsx +11 -3
  228. package/src/components/CarouselRenderer.tsx +4 -2
  229. package/src/components/ChartJSRenderer.tsx +18 -9
  230. package/src/components/ChatPrompt.tsx +13 -8
  231. package/src/components/CodeBlockRenderer.tsx +12 -10
  232. package/src/components/DataPreviewSection.tsx +92 -26
  233. package/src/components/DegradedFallback.tsx +4 -2
  234. package/src/components/FooterRenderer.tsx +3 -1
  235. package/src/components/FormFieldRenderer.tsx +34 -19
  236. package/src/components/FormRenderer.tsx +38 -10
  237. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  238. package/src/components/GraphRenderer.tsx +31 -16
  239. package/src/components/ImageGalleryRenderer.tsx +8 -4
  240. package/src/components/LightboxOverlay.tsx +6 -4
  241. package/src/components/MapRenderer.tsx +57 -20
  242. package/src/components/ModalRenderer.tsx +3 -1
  243. package/src/components/ScratchpadPanel.tsx +95 -44
  244. package/src/components/StreamingUIRenderer.tsx +41 -11
  245. package/src/components/UIResourceRenderer.tsx +145 -63
  246. package/src/components/VerifiedText.tsx +19 -9
  247. package/src/components/VideoRenderer.tsx +6 -4
  248. package/src/components/chart-data-table.ts +68 -14
  249. package/src/context/MCPActionContext.tsx +4 -1
  250. package/src/context/MCPUIStringsContext.tsx +1004 -1
  251. package/src/hooks/index.ts +2 -1
  252. package/src/hooks/useStreamingUI.ts +64 -10
  253. package/src/index.ts +23 -0
  254. package/src/services/validation.ts +93 -16
  255. package/src/utils/degraded-projections.ts +75 -12
  256. package/src/utils/format-string.ts +33 -0
  257. package/src/validation.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamingUI.cjs","sources":["../../src/hooks/useStreamingUI.ts"],"sourcesContent":["/**\n * useStreamingUI Hook - Phase 2\n *\n * Client-side hook for consuming the streaming generative UI endpoint.\n * Handles SSE connection, component buffering, reordering, and error handling.\n *\n * Features:\n * - SSE connection with automatic reconnection\n * - Component buffering and reordering by sequenceId\n * - Progress tracking and loading states\n * - Error handling with recovery attempts\n * - Cleanup on unmount\n *\n * Usage:\n * ```tsx\n * const { components, isLoading, error, progress } = useStreamingUI({\n * query: 'Show me revenue trends',\n * spaceIds: ['uuid1', 'uuid2'],\n * onComplete: (metadata) => console.log('Done!', metadata),\n * })\n * ```\n */\n\nimport { createSignal, onCleanup } from 'solid-js'\nimport type { UIComponent } from '../types'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('useStreamingUI')\n\n// SSR detection without importing solid-js/web (which might cause bundler issues)\nconst isServer = typeof window === 'undefined'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface UseStreamingUIOptions {\n query: string\n spaceIds?: string[]\n sessionId?: string\n options?: {\n useCache?: boolean\n useLLM?: boolean\n maxComponents?: number\n preferredComponents?: Array<'chart' | 'table' | 'metric' | 'text'>\n }\n onComplete?: (metadata: CompleteMetadata) => void\n onError?: (error: StreamError) => void\n onComponentReceived?: (component: UIComponent) => void\n}\n\nexport interface StreamingUIState {\n components: UIComponent[]\n isLoading: boolean\n isStreaming: boolean\n error: StreamError | null\n progress: StreamProgress\n metadata: CompleteMetadata | null\n}\n\nexport interface StreamProgress {\n receivedCount: number\n totalCount: number | null\n message: string\n timestamp: string\n}\n\nexport interface CompleteMetadata {\n layoutId: string\n componentsCount: number\n executionTimeMs: number\n /** Alias for executionTimeMs (for compatibility with FooterRenderer) */\n executionTime?: number\n firstTokenMs: number\n provider: 'groq' | 'mock'\n model: string\n tokensUsed?: number\n costUSD?: number\n cached: boolean\n}\n\nexport interface StreamError {\n error: string\n message: string\n componentId?: string\n recoverable: boolean\n}\n\ninterface ComponentBuffer {\n [sequenceId: number]: {\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n }\n}\n\n// ============================================================================\n// SSE Event Types (must match server)\n// ============================================================================\n\ntype SSEEventType = 'status' | 'component-start' | 'component' | 'complete' | 'error'\n\ninterface StatusEvent {\n message: string\n timestamp: string\n totalComponents?: number\n}\n\ninterface ComponentStartEvent {\n componentId: string\n type: 'chart' | 'table' | 'metric' | 'text'\n sequenceId: number\n position: { colStart: number; colSpan: number }\n}\n\ninterface ComponentEvent {\n componentId: string\n sequenceId: number\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\nexport function useStreamingUI(options: UseStreamingUIOptions) {\n // State\n const [components, setComponents] = createSignal<UIComponent[]>([])\n const [isLoading, setIsLoading] = createSignal(false)\n const [isStreaming, setIsStreaming] = createSignal(false)\n const [error, setError] = createSignal<StreamError | null>(null)\n const [progress, setProgress] = createSignal<StreamProgress>({\n receivedCount: 0,\n totalCount: null,\n message: 'Initializing...',\n timestamp: new Date().toISOString(),\n })\n const [metadata, setMetadata] = createSignal<CompleteMetadata | null>(null)\n\n // Component buffer for reordering\n let componentBuffer: ComponentBuffer = {}\n let nextSequenceId = 0\n let eventSource: EventSource | null = null\n let reconnectAttempts = 0\n const maxReconnectAttempts = 3\n\n /**\n * Flush components from buffer in sequence order\n */\n const flushBuffer = () => {\n const flushed: UIComponent[] = []\n\n while (componentBuffer[nextSequenceId]) {\n const { component } = componentBuffer[nextSequenceId]\n flushed.push(component)\n delete componentBuffer[nextSequenceId]\n nextSequenceId++\n }\n\n if (flushed.length > 0) {\n setComponents((prev) => [...prev, ...flushed])\n\n setProgress((prev) => ({\n ...prev,\n receivedCount: prev.receivedCount + flushed.length,\n }))\n\n logger.debug('Flushed components from buffer', {\n count: flushed.length,\n nextSequenceId,\n })\n }\n }\n\n /**\n * Handle SSE status event\n */\n const handleStatusEvent = (data: StatusEvent) => {\n logger.debug('Status event received', data as unknown as Record<string, unknown>)\n\n setProgress({\n receivedCount: progress().receivedCount,\n totalCount: data.totalComponents ?? progress().totalCount,\n message: data.message,\n timestamp: data.timestamp,\n })\n }\n\n /**\n * Handle SSE component-start event\n */\n const handleComponentStartEvent = (data: ComponentStartEvent) => {\n logger.debug('Component-start event received', data as unknown as Record<string, unknown>)\n\n setProgress((prev) => ({\n ...prev,\n message: `Loading ${data.type} component...`,\n timestamp: new Date().toISOString(),\n }))\n }\n\n /**\n * Handle SSE component event\n */\n const handleComponentEvent = (data: ComponentEvent) => {\n logger.debug('Component event received', {\n componentId: data.componentId,\n sequenceId: data.sequenceId,\n })\n\n // Add to buffer\n componentBuffer[data.sequenceId] = {\n component: data.component,\n position: data.position,\n }\n\n // Flush buffer in sequence\n flushBuffer()\n\n // Notify callback\n if (options.onComponentReceived) {\n options.onComponentReceived(data.component)\n }\n }\n\n /**\n * Handle SSE complete event\n */\n const handleCompleteEvent = (data: CompleteMetadata) => {\n logger.info('Stream completed', data as unknown as Record<string, unknown>)\n\n setIsStreaming(false)\n setIsLoading(false)\n // Normalize executionTimeMs to executionTime for compatibility with FooterRenderer\n setMetadata({\n ...data,\n executionTime: data.executionTimeMs || data.executionTime,\n })\n\n // Flush any remaining buffered components\n flushBuffer()\n\n setProgress((prev) => ({\n ...prev,\n message: 'Dashboard loaded',\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onComplete) {\n options.onComplete(data)\n }\n }\n\n /**\n * Handle SSE error event\n */\n const handleErrorEvent = (data: StreamError) => {\n logger.error('Stream error received', data as unknown as Record<string, unknown>)\n\n setError(data)\n setIsStreaming(false)\n setIsLoading(false)\n\n setProgress((prev) => ({\n ...prev,\n message: `Error: ${data.message}`,\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onError) {\n options.onError(data)\n }\n\n // Try to reconnect if recoverable\n if (data.recoverable && reconnectAttempts < maxReconnectAttempts) {\n reconnectAttempts++\n logger.warn('Attempting to reconnect', { attempt: reconnectAttempts })\n setTimeout(() => startStreaming(), 1000 * reconnectAttempts)\n }\n }\n\n /**\n * Parse SSE event\n */\n const parseSSEEvent = (event: MessageEvent, eventType: SSEEventType) => {\n try {\n const data = JSON.parse(event.data)\n\n switch (eventType) {\n case 'status':\n handleStatusEvent(data as StatusEvent)\n break\n case 'component-start':\n handleComponentStartEvent(data as ComponentStartEvent)\n break\n case 'component':\n handleComponentEvent(data as ComponentEvent)\n break\n case 'complete':\n handleCompleteEvent(data as CompleteMetadata)\n break\n case 'error':\n handleErrorEvent(data as StreamError)\n break\n default:\n logger.warn('Unknown SSE event type', { eventType })\n }\n } catch (error) {\n logger.error('Failed to parse SSE event', {\n error: error instanceof Error ? error.message : String(error),\n eventType,\n })\n }\n }\n\n /**\n * Start SSE streaming\n */\n const startStreaming = () => {\n // SSR Guard: Prevent execution on server-side (Node.js environment)\n // fetch() and ReadableStream APIs are only available in browsers\n if (isServer) {\n logger.warn('startStreaming called on server-side - skipping')\n setError({\n error: 'ssr',\n message: 'Streaming UI cannot start on server-side',\n recoverable: false,\n })\n setIsLoading(false)\n return\n }\n\n // Reset state\n setComponents([])\n setError(null)\n setIsLoading(true)\n setIsStreaming(true)\n componentBuffer = {}\n nextSequenceId = 0\n\n setProgress({\n receivedCount: 0,\n totalCount: null,\n message: 'Connecting to server...',\n timestamp: new Date().toISOString(),\n })\n\n logger.info('Starting SSE stream', {\n query: options.query,\n spaceIds: options.spaceIds,\n })\n\n // Build request body\n const requestBody = {\n query: options.query,\n spaceIds: options.spaceIds,\n sessionId: options.sessionId,\n options: options.options,\n }\n\n // Create EventSource (SSE connection)\n // Note: EventSource doesn't support POST, so we need to use fetch + ReadableStream\n fetch('/api/mcp/generative-ui-stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n })\n .then(async (response) => {\n if (!response.ok) {\n const errorData = await response.json()\n throw new Error(errorData.message || 'Stream request failed')\n }\n\n if (!response.body) {\n throw new Error('Response body is null')\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n\n let buffer = ''\n\n // Read stream\n const readChunk = async (): Promise<void> => {\n const { done, value } = await reader.read()\n\n if (done) {\n logger.info('Stream ended')\n return\n }\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE messages\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n let currentEvent: SSEEventType | null = null\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7) as SSEEventType\n } else if (line.startsWith('data: ') && currentEvent) {\n const data = line.slice(6)\n parseSSEEvent({ data } as MessageEvent, currentEvent)\n currentEvent = null\n }\n }\n\n // Continue reading\n return readChunk()\n }\n\n await readChunk()\n })\n .catch((err) => {\n logger.error('Stream fetch failed', {\n error: err instanceof Error ? err.message : String(err),\n })\n\n handleErrorEvent({\n error: 'Stream connection failed',\n message: err instanceof Error ? err.message : 'Unknown error',\n recoverable: true,\n })\n })\n }\n\n /**\n * Stop streaming\n */\n const stopStreaming = () => {\n if (eventSource) {\n eventSource.close()\n eventSource = null\n }\n\n setIsStreaming(false)\n setIsLoading(false)\n\n logger.info('Streaming stopped')\n }\n\n /**\n * Cleanup on unmount\n */\n onCleanup(() => {\n stopStreaming()\n })\n\n // Auto-start streaming\n startStreaming()\n\n // Return state accessors and controls\n return {\n components,\n isLoading,\n isStreaming,\n error,\n progress,\n metadata,\n startStreaming,\n stopStreaming,\n }\n}\n"],"names":["createLogger","createSignal","error","onCleanup"],"mappings":"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"}
1
+ {"version":3,"file":"useStreamingUI.cjs","sources":["../../src/hooks/useStreamingUI.ts"],"sourcesContent":["/**\n * useStreamingUI Hook - Phase 2\n *\n * Client-side hook for consuming the streaming generative UI endpoint.\n * Handles SSE connection, component buffering, reordering, and error handling.\n *\n * Features:\n * - SSE connection with automatic reconnection\n * - Component buffering and reordering by sequenceId\n * - Progress tracking and loading states\n * - Error handling with recovery attempts\n * - Cleanup on unmount\n *\n * Usage:\n * ```tsx\n * const { components, isLoading, error, progress } = useStreamingUI({\n * query: 'Show me revenue trends',\n * spaceIds: ['uuid1', 'uuid2'],\n * onComplete: (metadata) => console.log('Done!', metadata),\n * })\n * ```\n */\n\nimport { createSignal, onCleanup } from 'solid-js'\nimport type { UIComponent } from '../types'\nimport { createLogger } from '../utils/logger'\nimport { formatMCPUIString } from '../utils/format-string'\n\nconst logger = createLogger('useStreamingUI')\n\n// SSR detection without importing solid-js/web (which might cause bundler issues)\nconst isServer = typeof window === 'undefined'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Every string `useStreamingUI` puts into `progress().message` and\n * `error()` — both are rendered by `<StreamingUIRenderer>`.\n *\n * @since v6.20.0 — `StreamingUIRenderer` feeds these from `MCPUIStrings`\n * (`stream*` keys); a host calling the hook directly passes `messages`.\n */\nexport interface StreamingUIMessages {\n /** Initial progress message. */\n initializing: string\n /** Progress message while the request is sent. */\n connecting: string\n /** Progress message on `component-start`. Template — `{type}`. */\n loadingComponent: string\n /** Progress message on `complete`. */\n dashboardLoaded: string\n /** Progress message after an error. Template — `{message}`. */\n errorProgress: string\n /** `StreamError.error` when the fetch / read fails. */\n connectionFailed: string\n /** `StreamError.message` when the server answers non-OK without a message. */\n requestFailed: string\n /** `StreamError.message` when the response has no body. */\n emptyResponse: string\n /** `StreamError.message` when streaming starts during SSR. */\n serverSide: string\n /** `StreamError.message` when the failure carries no message. */\n unknownError: string\n}\n\n/** English defaults of {@link StreamingUIMessages}. */\nexport const DEFAULT_STREAMING_UI_MESSAGES: StreamingUIMessages = {\n initializing: 'Initializing...',\n connecting: 'Connecting to server...',\n loadingComponent: 'Loading {type} component...',\n dashboardLoaded: 'Dashboard loaded',\n errorProgress: 'Error: {message}',\n connectionFailed: 'Stream connection failed',\n requestFailed: 'Stream request failed',\n emptyResponse: 'Response body is null',\n serverSide: 'Streaming UI cannot start on server-side',\n unknownError: 'Unknown error',\n}\n\nexport interface UseStreamingUIOptions {\n query: string\n spaceIds?: string[]\n sessionId?: string\n options?: {\n useCache?: boolean\n useLLM?: boolean\n maxComponents?: number\n preferredComponents?: Array<'chart' | 'table' | 'metric' | 'text'>\n }\n onComplete?: (metadata: CompleteMetadata) => void\n onError?: (error: StreamError) => void\n onComponentReceived?: (component: UIComponent) => void\n /**\n * Localized progress / error messages (v6.20.0). Each key is read when\n * the message is produced, so an object with getters stays reactive.\n * Omitted keys fall back to {@link DEFAULT_STREAMING_UI_MESSAGES}.\n */\n messages?: Partial<StreamingUIMessages>\n}\n\nexport interface StreamingUIState {\n components: UIComponent[]\n isLoading: boolean\n isStreaming: boolean\n error: StreamError | null\n progress: StreamProgress\n metadata: CompleteMetadata | null\n}\n\nexport interface StreamProgress {\n receivedCount: number\n totalCount: number | null\n message: string\n timestamp: string\n}\n\nexport interface CompleteMetadata {\n layoutId: string\n componentsCount: number\n executionTimeMs: number\n /** Alias for executionTimeMs (for compatibility with FooterRenderer) */\n executionTime?: number\n firstTokenMs: number\n provider: 'groq' | 'mock'\n model: string\n tokensUsed?: number\n costUSD?: number\n cached: boolean\n}\n\nexport interface StreamError {\n error: string\n message: string\n componentId?: string\n recoverable: boolean\n}\n\ninterface ComponentBuffer {\n [sequenceId: number]: {\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n }\n}\n\n// ============================================================================\n// SSE Event Types (must match server)\n// ============================================================================\n\ntype SSEEventType = 'status' | 'component-start' | 'component' | 'complete' | 'error'\n\ninterface StatusEvent {\n message: string\n timestamp: string\n totalComponents?: number\n}\n\ninterface ComponentStartEvent {\n componentId: string\n type: 'chart' | 'table' | 'metric' | 'text'\n sequenceId: number\n position: { colStart: number; colSpan: number }\n}\n\ninterface ComponentEvent {\n componentId: string\n sequenceId: number\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\nexport function useStreamingUI(options: UseStreamingUIOptions) {\n const msg = (key: keyof StreamingUIMessages): string =>\n options.messages?.[key] ?? DEFAULT_STREAMING_UI_MESSAGES[key]\n\n // State\n const [components, setComponents] = createSignal<UIComponent[]>([])\n const [isLoading, setIsLoading] = createSignal(false)\n const [isStreaming, setIsStreaming] = createSignal(false)\n const [error, setError] = createSignal<StreamError | null>(null)\n const [progress, setProgress] = createSignal<StreamProgress>({\n receivedCount: 0,\n totalCount: null,\n message: msg('initializing'),\n timestamp: new Date().toISOString(),\n })\n const [metadata, setMetadata] = createSignal<CompleteMetadata | null>(null)\n\n // Component buffer for reordering\n let componentBuffer: ComponentBuffer = {}\n let nextSequenceId = 0\n let eventSource: EventSource | null = null\n let reconnectAttempts = 0\n const maxReconnectAttempts = 3\n\n /**\n * Flush components from buffer in sequence order\n */\n const flushBuffer = () => {\n const flushed: UIComponent[] = []\n\n while (componentBuffer[nextSequenceId]) {\n const { component } = componentBuffer[nextSequenceId]\n flushed.push(component)\n delete componentBuffer[nextSequenceId]\n nextSequenceId++\n }\n\n if (flushed.length > 0) {\n setComponents((prev) => [...prev, ...flushed])\n\n setProgress((prev) => ({\n ...prev,\n receivedCount: prev.receivedCount + flushed.length,\n }))\n\n logger.debug('Flushed components from buffer', {\n count: flushed.length,\n nextSequenceId,\n })\n }\n }\n\n /**\n * Handle SSE status event\n */\n const handleStatusEvent = (data: StatusEvent) => {\n logger.debug('Status event received', data as unknown as Record<string, unknown>)\n\n setProgress({\n receivedCount: progress().receivedCount,\n totalCount: data.totalComponents ?? progress().totalCount,\n message: data.message,\n timestamp: data.timestamp,\n })\n }\n\n /**\n * Handle SSE component-start event\n */\n const handleComponentStartEvent = (data: ComponentStartEvent) => {\n logger.debug('Component-start event received', data as unknown as Record<string, unknown>)\n\n setProgress((prev) => ({\n ...prev,\n message: formatMCPUIString(msg('loadingComponent'), { type: data.type }),\n timestamp: new Date().toISOString(),\n }))\n }\n\n /**\n * Handle SSE component event\n */\n const handleComponentEvent = (data: ComponentEvent) => {\n logger.debug('Component event received', {\n componentId: data.componentId,\n sequenceId: data.sequenceId,\n })\n\n // Add to buffer\n componentBuffer[data.sequenceId] = {\n component: data.component,\n position: data.position,\n }\n\n // Flush buffer in sequence\n flushBuffer()\n\n // Notify callback\n if (options.onComponentReceived) {\n options.onComponentReceived(data.component)\n }\n }\n\n /**\n * Handle SSE complete event\n */\n const handleCompleteEvent = (data: CompleteMetadata) => {\n logger.info('Stream completed', data as unknown as Record<string, unknown>)\n\n setIsStreaming(false)\n setIsLoading(false)\n // Normalize executionTimeMs to executionTime for compatibility with FooterRenderer\n setMetadata({\n ...data,\n executionTime: data.executionTimeMs || data.executionTime,\n })\n\n // Flush any remaining buffered components\n flushBuffer()\n\n setProgress((prev) => ({\n ...prev,\n message: msg('dashboardLoaded'),\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onComplete) {\n options.onComplete(data)\n }\n }\n\n /**\n * Handle SSE error event\n */\n const handleErrorEvent = (data: StreamError) => {\n logger.error('Stream error received', data as unknown as Record<string, unknown>)\n\n setError(data)\n setIsStreaming(false)\n setIsLoading(false)\n\n setProgress((prev) => ({\n ...prev,\n message: formatMCPUIString(msg('errorProgress'), { message: data.message }),\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onError) {\n options.onError(data)\n }\n\n // Try to reconnect if recoverable\n if (data.recoverable && reconnectAttempts < maxReconnectAttempts) {\n reconnectAttempts++\n logger.warn('Attempting to reconnect', { attempt: reconnectAttempts })\n setTimeout(() => startStreaming(), 1000 * reconnectAttempts)\n }\n }\n\n /**\n * Parse SSE event\n */\n const parseSSEEvent = (event: MessageEvent, eventType: SSEEventType) => {\n try {\n const data = JSON.parse(event.data)\n\n switch (eventType) {\n case 'status':\n handleStatusEvent(data as StatusEvent)\n break\n case 'component-start':\n handleComponentStartEvent(data as ComponentStartEvent)\n break\n case 'component':\n handleComponentEvent(data as ComponentEvent)\n break\n case 'complete':\n handleCompleteEvent(data as CompleteMetadata)\n break\n case 'error':\n handleErrorEvent(data as StreamError)\n break\n default:\n logger.warn('Unknown SSE event type', { eventType })\n }\n } catch (error) {\n logger.error('Failed to parse SSE event', {\n error: error instanceof Error ? error.message : String(error),\n eventType,\n })\n }\n }\n\n /**\n * Start SSE streaming\n */\n const startStreaming = () => {\n // SSR Guard: Prevent execution on server-side (Node.js environment)\n // fetch() and ReadableStream APIs are only available in browsers\n if (isServer) {\n logger.warn('startStreaming called on server-side - skipping')\n setError({\n error: 'ssr',\n message: msg('serverSide'),\n recoverable: false,\n })\n setIsLoading(false)\n return\n }\n\n // Reset state\n setComponents([])\n setError(null)\n setIsLoading(true)\n setIsStreaming(true)\n componentBuffer = {}\n nextSequenceId = 0\n\n setProgress({\n receivedCount: 0,\n totalCount: null,\n message: msg('connecting'),\n timestamp: new Date().toISOString(),\n })\n\n logger.info('Starting SSE stream', {\n query: options.query,\n spaceIds: options.spaceIds,\n })\n\n // Build request body\n const requestBody = {\n query: options.query,\n spaceIds: options.spaceIds,\n sessionId: options.sessionId,\n options: options.options,\n }\n\n // Create EventSource (SSE connection)\n // Note: EventSource doesn't support POST, so we need to use fetch + ReadableStream\n fetch('/api/mcp/generative-ui-stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n })\n .then(async (response) => {\n if (!response.ok) {\n const errorData = await response.json()\n throw new Error(errorData.message || msg('requestFailed'))\n }\n\n if (!response.body) {\n throw new Error(msg('emptyResponse'))\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n\n let buffer = ''\n\n // Read stream\n const readChunk = async (): Promise<void> => {\n const { done, value } = await reader.read()\n\n if (done) {\n logger.info('Stream ended')\n return\n }\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE messages\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n let currentEvent: SSEEventType | null = null\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7) as SSEEventType\n } else if (line.startsWith('data: ') && currentEvent) {\n const data = line.slice(6)\n parseSSEEvent({ data } as MessageEvent, currentEvent)\n currentEvent = null\n }\n }\n\n // Continue reading\n return readChunk()\n }\n\n await readChunk()\n })\n .catch((err) => {\n logger.error('Stream fetch failed', {\n error: err instanceof Error ? err.message : String(err),\n })\n\n handleErrorEvent({\n error: msg('connectionFailed'),\n message: err instanceof Error ? err.message : msg('unknownError'),\n recoverable: true,\n })\n })\n }\n\n /**\n * Stop streaming\n */\n const stopStreaming = () => {\n if (eventSource) {\n eventSource.close()\n eventSource = null\n }\n\n setIsStreaming(false)\n setIsLoading(false)\n\n logger.info('Streaming stopped')\n }\n\n /**\n * Cleanup on unmount\n */\n onCleanup(() => {\n stopStreaming()\n })\n\n // Auto-start streaming\n startStreaming()\n\n // Return state accessors and controls\n return {\n components,\n isLoading,\n isStreaming,\n error,\n progress,\n metadata,\n startStreaming,\n stopStreaming,\n }\n}\n"],"names":["createLogger","createSignal","formatMCPUIString","error","onCleanup"],"mappings":"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"}
@@ -21,6 +21,37 @@
21
21
  * ```
22
22
  */
23
23
  import type { UIComponent } from '../types';
24
+ /**
25
+ * Every string `useStreamingUI` puts into `progress().message` and
26
+ * `error()` — both are rendered by `<StreamingUIRenderer>`.
27
+ *
28
+ * @since v6.20.0 — `StreamingUIRenderer` feeds these from `MCPUIStrings`
29
+ * (`stream*` keys); a host calling the hook directly passes `messages`.
30
+ */
31
+ export interface StreamingUIMessages {
32
+ /** Initial progress message. */
33
+ initializing: string;
34
+ /** Progress message while the request is sent. */
35
+ connecting: string;
36
+ /** Progress message on `component-start`. Template — `{type}`. */
37
+ loadingComponent: string;
38
+ /** Progress message on `complete`. */
39
+ dashboardLoaded: string;
40
+ /** Progress message after an error. Template — `{message}`. */
41
+ errorProgress: string;
42
+ /** `StreamError.error` when the fetch / read fails. */
43
+ connectionFailed: string;
44
+ /** `StreamError.message` when the server answers non-OK without a message. */
45
+ requestFailed: string;
46
+ /** `StreamError.message` when the response has no body. */
47
+ emptyResponse: string;
48
+ /** `StreamError.message` when streaming starts during SSR. */
49
+ serverSide: string;
50
+ /** `StreamError.message` when the failure carries no message. */
51
+ unknownError: string;
52
+ }
53
+ /** English defaults of {@link StreamingUIMessages}. */
54
+ export declare const DEFAULT_STREAMING_UI_MESSAGES: StreamingUIMessages;
24
55
  export interface UseStreamingUIOptions {
25
56
  query: string;
26
57
  spaceIds?: string[];
@@ -34,6 +65,12 @@ export interface UseStreamingUIOptions {
34
65
  onComplete?: (metadata: CompleteMetadata) => void;
35
66
  onError?: (error: StreamError) => void;
36
67
  onComponentReceived?: (component: UIComponent) => void;
68
+ /**
69
+ * Localized progress / error messages (v6.20.0). Each key is read when
70
+ * the message is produced, so an object with getters stays reactive.
71
+ * Omitted keys fall back to {@link DEFAULT_STREAMING_UI_MESSAGES}.
72
+ */
73
+ messages?: Partial<StreamingUIMessages>;
37
74
  }
38
75
  export interface StreamingUIState {
39
76
  components: UIComponent[];
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamingUI.d.ts","sourceRoot":"","sources":["../../src/hooks/useStreamingUI.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAY3C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,mBAAmB,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAA;KACnE,CAAA;IACD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACtC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,KAAK,IAAI,CAAA;CACvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,OAAO,CAAA;CACrB;AAuCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB;;;;;;;;;EAuV5D"}
1
+ {"version":3,"file":"useStreamingUI.d.ts","sourceRoot":"","sources":["../../src/hooks/useStreamingUI.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAa3C;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,gBAAgB,EAAE,MAAM,CAAA;IACxB,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAA;IACvB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,gBAAgB,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAA;IACrB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,uDAAuD;AACvD,eAAO,MAAM,6BAA6B,EAAE,mBAW3C,CAAA;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,mBAAmB,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAA;KACnE,CAAA;IACD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACtC,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,KAAK,IAAI,CAAA;IACtD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAA;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,OAAO,CAAA;CACrB;AAuCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB;;;;;;;;;EA0V5D"}
@@ -1,8 +1,25 @@
1
1
  import { createSignal, onCleanup } from "solid-js";
2
2
  import { createLogger } from "../utils/logger.js";
3
+ import { formatMCPUIString } from "../utils/format-string.js";
3
4
  const logger = createLogger("useStreamingUI");
4
5
  const isServer = typeof window === "undefined";
6
+ const DEFAULT_STREAMING_UI_MESSAGES = {
7
+ initializing: "Initializing...",
8
+ connecting: "Connecting to server...",
9
+ loadingComponent: "Loading {type} component...",
10
+ dashboardLoaded: "Dashboard loaded",
11
+ errorProgress: "Error: {message}",
12
+ connectionFailed: "Stream connection failed",
13
+ requestFailed: "Stream request failed",
14
+ emptyResponse: "Response body is null",
15
+ serverSide: "Streaming UI cannot start on server-side",
16
+ unknownError: "Unknown error"
17
+ };
5
18
  function useStreamingUI(options) {
19
+ const msg = (key) => {
20
+ var _a;
21
+ return ((_a = options.messages) == null ? void 0 : _a[key]) ?? DEFAULT_STREAMING_UI_MESSAGES[key];
22
+ };
6
23
  const [components, setComponents] = createSignal([]);
7
24
  const [isLoading, setIsLoading] = createSignal(false);
8
25
  const [isStreaming, setIsStreaming] = createSignal(false);
@@ -10,7 +27,7 @@ function useStreamingUI(options) {
10
27
  const [progress, setProgress] = createSignal({
11
28
  receivedCount: 0,
12
29
  totalCount: null,
13
- message: "Initializing...",
30
+ message: msg("initializing"),
14
31
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
15
32
  });
16
33
  const [metadata, setMetadata] = createSignal(null);
@@ -51,7 +68,7 @@ function useStreamingUI(options) {
51
68
  logger.debug("Component-start event received", data);
52
69
  setProgress((prev) => ({
53
70
  ...prev,
54
- message: `Loading ${data.type} component...`,
71
+ message: formatMCPUIString(msg("loadingComponent"), { type: data.type }),
55
72
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
56
73
  }));
57
74
  };
@@ -80,7 +97,7 @@ function useStreamingUI(options) {
80
97
  flushBuffer();
81
98
  setProgress((prev) => ({
82
99
  ...prev,
83
- message: "Dashboard loaded",
100
+ message: msg("dashboardLoaded"),
84
101
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
85
102
  }));
86
103
  if (options.onComplete) {
@@ -94,7 +111,7 @@ function useStreamingUI(options) {
94
111
  setIsLoading(false);
95
112
  setProgress((prev) => ({
96
113
  ...prev,
97
- message: `Error: ${data.message}`,
114
+ message: formatMCPUIString(msg("errorProgress"), { message: data.message }),
98
115
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
99
116
  }));
100
117
  if (options.onError) {
@@ -140,7 +157,7 @@ function useStreamingUI(options) {
140
157
  logger.warn("startStreaming called on server-side - skipping");
141
158
  setError({
142
159
  error: "ssr",
143
- message: "Streaming UI cannot start on server-side",
160
+ message: msg("serverSide"),
144
161
  recoverable: false
145
162
  });
146
163
  setIsLoading(false);
@@ -155,7 +172,7 @@ function useStreamingUI(options) {
155
172
  setProgress({
156
173
  receivedCount: 0,
157
174
  totalCount: null,
158
- message: "Connecting to server...",
175
+ message: msg("connecting"),
159
176
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
160
177
  });
161
178
  logger.info("Starting SSE stream", {
@@ -177,10 +194,10 @@ function useStreamingUI(options) {
177
194
  }).then(async (response) => {
178
195
  if (!response.ok) {
179
196
  const errorData = await response.json();
180
- throw new Error(errorData.message || "Stream request failed");
197
+ throw new Error(errorData.message || msg("requestFailed"));
181
198
  }
182
199
  if (!response.body) {
183
- throw new Error("Response body is null");
200
+ throw new Error(msg("emptyResponse"));
184
201
  }
185
202
  const reader = response.body.getReader();
186
203
  const decoder = new TextDecoder();
@@ -212,8 +229,8 @@ function useStreamingUI(options) {
212
229
  error: err instanceof Error ? err.message : String(err)
213
230
  });
214
231
  handleErrorEvent({
215
- error: "Stream connection failed",
216
- message: err instanceof Error ? err.message : "Unknown error",
232
+ error: msg("connectionFailed"),
233
+ message: err instanceof Error ? err.message : msg("unknownError"),
217
234
  recoverable: true
218
235
  });
219
236
  });
@@ -239,6 +256,7 @@ function useStreamingUI(options) {
239
256
  };
240
257
  }
241
258
  export {
259
+ DEFAULT_STREAMING_UI_MESSAGES,
242
260
  useStreamingUI
243
261
  };
244
262
  //# sourceMappingURL=useStreamingUI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamingUI.js","sources":["../../src/hooks/useStreamingUI.ts"],"sourcesContent":["/**\n * useStreamingUI Hook - Phase 2\n *\n * Client-side hook for consuming the streaming generative UI endpoint.\n * Handles SSE connection, component buffering, reordering, and error handling.\n *\n * Features:\n * - SSE connection with automatic reconnection\n * - Component buffering and reordering by sequenceId\n * - Progress tracking and loading states\n * - Error handling with recovery attempts\n * - Cleanup on unmount\n *\n * Usage:\n * ```tsx\n * const { components, isLoading, error, progress } = useStreamingUI({\n * query: 'Show me revenue trends',\n * spaceIds: ['uuid1', 'uuid2'],\n * onComplete: (metadata) => console.log('Done!', metadata),\n * })\n * ```\n */\n\nimport { createSignal, onCleanup } from 'solid-js'\nimport type { UIComponent } from '../types'\nimport { createLogger } from '../utils/logger'\n\nconst logger = createLogger('useStreamingUI')\n\n// SSR detection without importing solid-js/web (which might cause bundler issues)\nconst isServer = typeof window === 'undefined'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface UseStreamingUIOptions {\n query: string\n spaceIds?: string[]\n sessionId?: string\n options?: {\n useCache?: boolean\n useLLM?: boolean\n maxComponents?: number\n preferredComponents?: Array<'chart' | 'table' | 'metric' | 'text'>\n }\n onComplete?: (metadata: CompleteMetadata) => void\n onError?: (error: StreamError) => void\n onComponentReceived?: (component: UIComponent) => void\n}\n\nexport interface StreamingUIState {\n components: UIComponent[]\n isLoading: boolean\n isStreaming: boolean\n error: StreamError | null\n progress: StreamProgress\n metadata: CompleteMetadata | null\n}\n\nexport interface StreamProgress {\n receivedCount: number\n totalCount: number | null\n message: string\n timestamp: string\n}\n\nexport interface CompleteMetadata {\n layoutId: string\n componentsCount: number\n executionTimeMs: number\n /** Alias for executionTimeMs (for compatibility with FooterRenderer) */\n executionTime?: number\n firstTokenMs: number\n provider: 'groq' | 'mock'\n model: string\n tokensUsed?: number\n costUSD?: number\n cached: boolean\n}\n\nexport interface StreamError {\n error: string\n message: string\n componentId?: string\n recoverable: boolean\n}\n\ninterface ComponentBuffer {\n [sequenceId: number]: {\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n }\n}\n\n// ============================================================================\n// SSE Event Types (must match server)\n// ============================================================================\n\ntype SSEEventType = 'status' | 'component-start' | 'component' | 'complete' | 'error'\n\ninterface StatusEvent {\n message: string\n timestamp: string\n totalComponents?: number\n}\n\ninterface ComponentStartEvent {\n componentId: string\n type: 'chart' | 'table' | 'metric' | 'text'\n sequenceId: number\n position: { colStart: number; colSpan: number }\n}\n\ninterface ComponentEvent {\n componentId: string\n sequenceId: number\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\nexport function useStreamingUI(options: UseStreamingUIOptions) {\n // State\n const [components, setComponents] = createSignal<UIComponent[]>([])\n const [isLoading, setIsLoading] = createSignal(false)\n const [isStreaming, setIsStreaming] = createSignal(false)\n const [error, setError] = createSignal<StreamError | null>(null)\n const [progress, setProgress] = createSignal<StreamProgress>({\n receivedCount: 0,\n totalCount: null,\n message: 'Initializing...',\n timestamp: new Date().toISOString(),\n })\n const [metadata, setMetadata] = createSignal<CompleteMetadata | null>(null)\n\n // Component buffer for reordering\n let componentBuffer: ComponentBuffer = {}\n let nextSequenceId = 0\n let eventSource: EventSource | null = null\n let reconnectAttempts = 0\n const maxReconnectAttempts = 3\n\n /**\n * Flush components from buffer in sequence order\n */\n const flushBuffer = () => {\n const flushed: UIComponent[] = []\n\n while (componentBuffer[nextSequenceId]) {\n const { component } = componentBuffer[nextSequenceId]\n flushed.push(component)\n delete componentBuffer[nextSequenceId]\n nextSequenceId++\n }\n\n if (flushed.length > 0) {\n setComponents((prev) => [...prev, ...flushed])\n\n setProgress((prev) => ({\n ...prev,\n receivedCount: prev.receivedCount + flushed.length,\n }))\n\n logger.debug('Flushed components from buffer', {\n count: flushed.length,\n nextSequenceId,\n })\n }\n }\n\n /**\n * Handle SSE status event\n */\n const handleStatusEvent = (data: StatusEvent) => {\n logger.debug('Status event received', data as unknown as Record<string, unknown>)\n\n setProgress({\n receivedCount: progress().receivedCount,\n totalCount: data.totalComponents ?? progress().totalCount,\n message: data.message,\n timestamp: data.timestamp,\n })\n }\n\n /**\n * Handle SSE component-start event\n */\n const handleComponentStartEvent = (data: ComponentStartEvent) => {\n logger.debug('Component-start event received', data as unknown as Record<string, unknown>)\n\n setProgress((prev) => ({\n ...prev,\n message: `Loading ${data.type} component...`,\n timestamp: new Date().toISOString(),\n }))\n }\n\n /**\n * Handle SSE component event\n */\n const handleComponentEvent = (data: ComponentEvent) => {\n logger.debug('Component event received', {\n componentId: data.componentId,\n sequenceId: data.sequenceId,\n })\n\n // Add to buffer\n componentBuffer[data.sequenceId] = {\n component: data.component,\n position: data.position,\n }\n\n // Flush buffer in sequence\n flushBuffer()\n\n // Notify callback\n if (options.onComponentReceived) {\n options.onComponentReceived(data.component)\n }\n }\n\n /**\n * Handle SSE complete event\n */\n const handleCompleteEvent = (data: CompleteMetadata) => {\n logger.info('Stream completed', data as unknown as Record<string, unknown>)\n\n setIsStreaming(false)\n setIsLoading(false)\n // Normalize executionTimeMs to executionTime for compatibility with FooterRenderer\n setMetadata({\n ...data,\n executionTime: data.executionTimeMs || data.executionTime,\n })\n\n // Flush any remaining buffered components\n flushBuffer()\n\n setProgress((prev) => ({\n ...prev,\n message: 'Dashboard loaded',\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onComplete) {\n options.onComplete(data)\n }\n }\n\n /**\n * Handle SSE error event\n */\n const handleErrorEvent = (data: StreamError) => {\n logger.error('Stream error received', data as unknown as Record<string, unknown>)\n\n setError(data)\n setIsStreaming(false)\n setIsLoading(false)\n\n setProgress((prev) => ({\n ...prev,\n message: `Error: ${data.message}`,\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onError) {\n options.onError(data)\n }\n\n // Try to reconnect if recoverable\n if (data.recoverable && reconnectAttempts < maxReconnectAttempts) {\n reconnectAttempts++\n logger.warn('Attempting to reconnect', { attempt: reconnectAttempts })\n setTimeout(() => startStreaming(), 1000 * reconnectAttempts)\n }\n }\n\n /**\n * Parse SSE event\n */\n const parseSSEEvent = (event: MessageEvent, eventType: SSEEventType) => {\n try {\n const data = JSON.parse(event.data)\n\n switch (eventType) {\n case 'status':\n handleStatusEvent(data as StatusEvent)\n break\n case 'component-start':\n handleComponentStartEvent(data as ComponentStartEvent)\n break\n case 'component':\n handleComponentEvent(data as ComponentEvent)\n break\n case 'complete':\n handleCompleteEvent(data as CompleteMetadata)\n break\n case 'error':\n handleErrorEvent(data as StreamError)\n break\n default:\n logger.warn('Unknown SSE event type', { eventType })\n }\n } catch (error) {\n logger.error('Failed to parse SSE event', {\n error: error instanceof Error ? error.message : String(error),\n eventType,\n })\n }\n }\n\n /**\n * Start SSE streaming\n */\n const startStreaming = () => {\n // SSR Guard: Prevent execution on server-side (Node.js environment)\n // fetch() and ReadableStream APIs are only available in browsers\n if (isServer) {\n logger.warn('startStreaming called on server-side - skipping')\n setError({\n error: 'ssr',\n message: 'Streaming UI cannot start on server-side',\n recoverable: false,\n })\n setIsLoading(false)\n return\n }\n\n // Reset state\n setComponents([])\n setError(null)\n setIsLoading(true)\n setIsStreaming(true)\n componentBuffer = {}\n nextSequenceId = 0\n\n setProgress({\n receivedCount: 0,\n totalCount: null,\n message: 'Connecting to server...',\n timestamp: new Date().toISOString(),\n })\n\n logger.info('Starting SSE stream', {\n query: options.query,\n spaceIds: options.spaceIds,\n })\n\n // Build request body\n const requestBody = {\n query: options.query,\n spaceIds: options.spaceIds,\n sessionId: options.sessionId,\n options: options.options,\n }\n\n // Create EventSource (SSE connection)\n // Note: EventSource doesn't support POST, so we need to use fetch + ReadableStream\n fetch('/api/mcp/generative-ui-stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n })\n .then(async (response) => {\n if (!response.ok) {\n const errorData = await response.json()\n throw new Error(errorData.message || 'Stream request failed')\n }\n\n if (!response.body) {\n throw new Error('Response body is null')\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n\n let buffer = ''\n\n // Read stream\n const readChunk = async (): Promise<void> => {\n const { done, value } = await reader.read()\n\n if (done) {\n logger.info('Stream ended')\n return\n }\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE messages\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n let currentEvent: SSEEventType | null = null\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7) as SSEEventType\n } else if (line.startsWith('data: ') && currentEvent) {\n const data = line.slice(6)\n parseSSEEvent({ data } as MessageEvent, currentEvent)\n currentEvent = null\n }\n }\n\n // Continue reading\n return readChunk()\n }\n\n await readChunk()\n })\n .catch((err) => {\n logger.error('Stream fetch failed', {\n error: err instanceof Error ? err.message : String(err),\n })\n\n handleErrorEvent({\n error: 'Stream connection failed',\n message: err instanceof Error ? err.message : 'Unknown error',\n recoverable: true,\n })\n })\n }\n\n /**\n * Stop streaming\n */\n const stopStreaming = () => {\n if (eventSource) {\n eventSource.close()\n eventSource = null\n }\n\n setIsStreaming(false)\n setIsLoading(false)\n\n logger.info('Streaming stopped')\n }\n\n /**\n * Cleanup on unmount\n */\n onCleanup(() => {\n stopStreaming()\n })\n\n // Auto-start streaming\n startStreaming()\n\n // Return state accessors and controls\n return {\n components,\n isLoading,\n isStreaming,\n error,\n progress,\n metadata,\n startStreaming,\n stopStreaming,\n }\n}\n"],"names":["error"],"mappings":"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"}
1
+ {"version":3,"file":"useStreamingUI.js","sources":["../../src/hooks/useStreamingUI.ts"],"sourcesContent":["/**\n * useStreamingUI Hook - Phase 2\n *\n * Client-side hook for consuming the streaming generative UI endpoint.\n * Handles SSE connection, component buffering, reordering, and error handling.\n *\n * Features:\n * - SSE connection with automatic reconnection\n * - Component buffering and reordering by sequenceId\n * - Progress tracking and loading states\n * - Error handling with recovery attempts\n * - Cleanup on unmount\n *\n * Usage:\n * ```tsx\n * const { components, isLoading, error, progress } = useStreamingUI({\n * query: 'Show me revenue trends',\n * spaceIds: ['uuid1', 'uuid2'],\n * onComplete: (metadata) => console.log('Done!', metadata),\n * })\n * ```\n */\n\nimport { createSignal, onCleanup } from 'solid-js'\nimport type { UIComponent } from '../types'\nimport { createLogger } from '../utils/logger'\nimport { formatMCPUIString } from '../utils/format-string'\n\nconst logger = createLogger('useStreamingUI')\n\n// SSR detection without importing solid-js/web (which might cause bundler issues)\nconst isServer = typeof window === 'undefined'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Every string `useStreamingUI` puts into `progress().message` and\n * `error()` — both are rendered by `<StreamingUIRenderer>`.\n *\n * @since v6.20.0 — `StreamingUIRenderer` feeds these from `MCPUIStrings`\n * (`stream*` keys); a host calling the hook directly passes `messages`.\n */\nexport interface StreamingUIMessages {\n /** Initial progress message. */\n initializing: string\n /** Progress message while the request is sent. */\n connecting: string\n /** Progress message on `component-start`. Template — `{type}`. */\n loadingComponent: string\n /** Progress message on `complete`. */\n dashboardLoaded: string\n /** Progress message after an error. Template — `{message}`. */\n errorProgress: string\n /** `StreamError.error` when the fetch / read fails. */\n connectionFailed: string\n /** `StreamError.message` when the server answers non-OK without a message. */\n requestFailed: string\n /** `StreamError.message` when the response has no body. */\n emptyResponse: string\n /** `StreamError.message` when streaming starts during SSR. */\n serverSide: string\n /** `StreamError.message` when the failure carries no message. */\n unknownError: string\n}\n\n/** English defaults of {@link StreamingUIMessages}. */\nexport const DEFAULT_STREAMING_UI_MESSAGES: StreamingUIMessages = {\n initializing: 'Initializing...',\n connecting: 'Connecting to server...',\n loadingComponent: 'Loading {type} component...',\n dashboardLoaded: 'Dashboard loaded',\n errorProgress: 'Error: {message}',\n connectionFailed: 'Stream connection failed',\n requestFailed: 'Stream request failed',\n emptyResponse: 'Response body is null',\n serverSide: 'Streaming UI cannot start on server-side',\n unknownError: 'Unknown error',\n}\n\nexport interface UseStreamingUIOptions {\n query: string\n spaceIds?: string[]\n sessionId?: string\n options?: {\n useCache?: boolean\n useLLM?: boolean\n maxComponents?: number\n preferredComponents?: Array<'chart' | 'table' | 'metric' | 'text'>\n }\n onComplete?: (metadata: CompleteMetadata) => void\n onError?: (error: StreamError) => void\n onComponentReceived?: (component: UIComponent) => void\n /**\n * Localized progress / error messages (v6.20.0). Each key is read when\n * the message is produced, so an object with getters stays reactive.\n * Omitted keys fall back to {@link DEFAULT_STREAMING_UI_MESSAGES}.\n */\n messages?: Partial<StreamingUIMessages>\n}\n\nexport interface StreamingUIState {\n components: UIComponent[]\n isLoading: boolean\n isStreaming: boolean\n error: StreamError | null\n progress: StreamProgress\n metadata: CompleteMetadata | null\n}\n\nexport interface StreamProgress {\n receivedCount: number\n totalCount: number | null\n message: string\n timestamp: string\n}\n\nexport interface CompleteMetadata {\n layoutId: string\n componentsCount: number\n executionTimeMs: number\n /** Alias for executionTimeMs (for compatibility with FooterRenderer) */\n executionTime?: number\n firstTokenMs: number\n provider: 'groq' | 'mock'\n model: string\n tokensUsed?: number\n costUSD?: number\n cached: boolean\n}\n\nexport interface StreamError {\n error: string\n message: string\n componentId?: string\n recoverable: boolean\n}\n\ninterface ComponentBuffer {\n [sequenceId: number]: {\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n }\n}\n\n// ============================================================================\n// SSE Event Types (must match server)\n// ============================================================================\n\ntype SSEEventType = 'status' | 'component-start' | 'component' | 'complete' | 'error'\n\ninterface StatusEvent {\n message: string\n timestamp: string\n totalComponents?: number\n}\n\ninterface ComponentStartEvent {\n componentId: string\n type: 'chart' | 'table' | 'metric' | 'text'\n sequenceId: number\n position: { colStart: number; colSpan: number }\n}\n\ninterface ComponentEvent {\n componentId: string\n sequenceId: number\n component: UIComponent\n position: { colStart: number; colSpan: number; rowStart?: number; rowSpan?: number }\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\nexport function useStreamingUI(options: UseStreamingUIOptions) {\n const msg = (key: keyof StreamingUIMessages): string =>\n options.messages?.[key] ?? DEFAULT_STREAMING_UI_MESSAGES[key]\n\n // State\n const [components, setComponents] = createSignal<UIComponent[]>([])\n const [isLoading, setIsLoading] = createSignal(false)\n const [isStreaming, setIsStreaming] = createSignal(false)\n const [error, setError] = createSignal<StreamError | null>(null)\n const [progress, setProgress] = createSignal<StreamProgress>({\n receivedCount: 0,\n totalCount: null,\n message: msg('initializing'),\n timestamp: new Date().toISOString(),\n })\n const [metadata, setMetadata] = createSignal<CompleteMetadata | null>(null)\n\n // Component buffer for reordering\n let componentBuffer: ComponentBuffer = {}\n let nextSequenceId = 0\n let eventSource: EventSource | null = null\n let reconnectAttempts = 0\n const maxReconnectAttempts = 3\n\n /**\n * Flush components from buffer in sequence order\n */\n const flushBuffer = () => {\n const flushed: UIComponent[] = []\n\n while (componentBuffer[nextSequenceId]) {\n const { component } = componentBuffer[nextSequenceId]\n flushed.push(component)\n delete componentBuffer[nextSequenceId]\n nextSequenceId++\n }\n\n if (flushed.length > 0) {\n setComponents((prev) => [...prev, ...flushed])\n\n setProgress((prev) => ({\n ...prev,\n receivedCount: prev.receivedCount + flushed.length,\n }))\n\n logger.debug('Flushed components from buffer', {\n count: flushed.length,\n nextSequenceId,\n })\n }\n }\n\n /**\n * Handle SSE status event\n */\n const handleStatusEvent = (data: StatusEvent) => {\n logger.debug('Status event received', data as unknown as Record<string, unknown>)\n\n setProgress({\n receivedCount: progress().receivedCount,\n totalCount: data.totalComponents ?? progress().totalCount,\n message: data.message,\n timestamp: data.timestamp,\n })\n }\n\n /**\n * Handle SSE component-start event\n */\n const handleComponentStartEvent = (data: ComponentStartEvent) => {\n logger.debug('Component-start event received', data as unknown as Record<string, unknown>)\n\n setProgress((prev) => ({\n ...prev,\n message: formatMCPUIString(msg('loadingComponent'), { type: data.type }),\n timestamp: new Date().toISOString(),\n }))\n }\n\n /**\n * Handle SSE component event\n */\n const handleComponentEvent = (data: ComponentEvent) => {\n logger.debug('Component event received', {\n componentId: data.componentId,\n sequenceId: data.sequenceId,\n })\n\n // Add to buffer\n componentBuffer[data.sequenceId] = {\n component: data.component,\n position: data.position,\n }\n\n // Flush buffer in sequence\n flushBuffer()\n\n // Notify callback\n if (options.onComponentReceived) {\n options.onComponentReceived(data.component)\n }\n }\n\n /**\n * Handle SSE complete event\n */\n const handleCompleteEvent = (data: CompleteMetadata) => {\n logger.info('Stream completed', data as unknown as Record<string, unknown>)\n\n setIsStreaming(false)\n setIsLoading(false)\n // Normalize executionTimeMs to executionTime for compatibility with FooterRenderer\n setMetadata({\n ...data,\n executionTime: data.executionTimeMs || data.executionTime,\n })\n\n // Flush any remaining buffered components\n flushBuffer()\n\n setProgress((prev) => ({\n ...prev,\n message: msg('dashboardLoaded'),\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onComplete) {\n options.onComplete(data)\n }\n }\n\n /**\n * Handle SSE error event\n */\n const handleErrorEvent = (data: StreamError) => {\n logger.error('Stream error received', data as unknown as Record<string, unknown>)\n\n setError(data)\n setIsStreaming(false)\n setIsLoading(false)\n\n setProgress((prev) => ({\n ...prev,\n message: formatMCPUIString(msg('errorProgress'), { message: data.message }),\n timestamp: new Date().toISOString(),\n }))\n\n // Notify callback\n if (options.onError) {\n options.onError(data)\n }\n\n // Try to reconnect if recoverable\n if (data.recoverable && reconnectAttempts < maxReconnectAttempts) {\n reconnectAttempts++\n logger.warn('Attempting to reconnect', { attempt: reconnectAttempts })\n setTimeout(() => startStreaming(), 1000 * reconnectAttempts)\n }\n }\n\n /**\n * Parse SSE event\n */\n const parseSSEEvent = (event: MessageEvent, eventType: SSEEventType) => {\n try {\n const data = JSON.parse(event.data)\n\n switch (eventType) {\n case 'status':\n handleStatusEvent(data as StatusEvent)\n break\n case 'component-start':\n handleComponentStartEvent(data as ComponentStartEvent)\n break\n case 'component':\n handleComponentEvent(data as ComponentEvent)\n break\n case 'complete':\n handleCompleteEvent(data as CompleteMetadata)\n break\n case 'error':\n handleErrorEvent(data as StreamError)\n break\n default:\n logger.warn('Unknown SSE event type', { eventType })\n }\n } catch (error) {\n logger.error('Failed to parse SSE event', {\n error: error instanceof Error ? error.message : String(error),\n eventType,\n })\n }\n }\n\n /**\n * Start SSE streaming\n */\n const startStreaming = () => {\n // SSR Guard: Prevent execution on server-side (Node.js environment)\n // fetch() and ReadableStream APIs are only available in browsers\n if (isServer) {\n logger.warn('startStreaming called on server-side - skipping')\n setError({\n error: 'ssr',\n message: msg('serverSide'),\n recoverable: false,\n })\n setIsLoading(false)\n return\n }\n\n // Reset state\n setComponents([])\n setError(null)\n setIsLoading(true)\n setIsStreaming(true)\n componentBuffer = {}\n nextSequenceId = 0\n\n setProgress({\n receivedCount: 0,\n totalCount: null,\n message: msg('connecting'),\n timestamp: new Date().toISOString(),\n })\n\n logger.info('Starting SSE stream', {\n query: options.query,\n spaceIds: options.spaceIds,\n })\n\n // Build request body\n const requestBody = {\n query: options.query,\n spaceIds: options.spaceIds,\n sessionId: options.sessionId,\n options: options.options,\n }\n\n // Create EventSource (SSE connection)\n // Note: EventSource doesn't support POST, so we need to use fetch + ReadableStream\n fetch('/api/mcp/generative-ui-stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n })\n .then(async (response) => {\n if (!response.ok) {\n const errorData = await response.json()\n throw new Error(errorData.message || msg('requestFailed'))\n }\n\n if (!response.body) {\n throw new Error(msg('emptyResponse'))\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n\n let buffer = ''\n\n // Read stream\n const readChunk = async (): Promise<void> => {\n const { done, value } = await reader.read()\n\n if (done) {\n logger.info('Stream ended')\n return\n }\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE messages\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n let currentEvent: SSEEventType | null = null\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7) as SSEEventType\n } else if (line.startsWith('data: ') && currentEvent) {\n const data = line.slice(6)\n parseSSEEvent({ data } as MessageEvent, currentEvent)\n currentEvent = null\n }\n }\n\n // Continue reading\n return readChunk()\n }\n\n await readChunk()\n })\n .catch((err) => {\n logger.error('Stream fetch failed', {\n error: err instanceof Error ? err.message : String(err),\n })\n\n handleErrorEvent({\n error: msg('connectionFailed'),\n message: err instanceof Error ? err.message : msg('unknownError'),\n recoverable: true,\n })\n })\n }\n\n /**\n * Stop streaming\n */\n const stopStreaming = () => {\n if (eventSource) {\n eventSource.close()\n eventSource = null\n }\n\n setIsStreaming(false)\n setIsLoading(false)\n\n logger.info('Streaming stopped')\n }\n\n /**\n * Cleanup on unmount\n */\n onCleanup(() => {\n stopStreaming()\n })\n\n // Auto-start streaming\n startStreaming()\n\n // Return state accessors and controls\n return {\n components,\n isLoading,\n isStreaming,\n error,\n progress,\n metadata,\n startStreaming,\n stopStreaming,\n }\n}\n"],"names":["error"],"mappings":"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"}
package/dist/hooks.cjs CHANGED
@@ -9,6 +9,7 @@ const useDragDrop = require("./hooks/useDragDrop.cjs");
9
9
  const useResize = require("./hooks/useResize.cjs");
10
10
  const useAutocomplete = require("./hooks/useAutocomplete.cjs");
11
11
  const useDataValidator = require("./hooks/useDataValidator.cjs");
12
+ exports.DEFAULT_STREAMING_UI_MESSAGES = useStreamingUI.DEFAULT_STREAMING_UI_MESSAGES;
12
13
  exports.useStreamingUI = useStreamingUI.useStreamingUI;
13
14
  exports.useAction = useAction.useAction;
14
15
  exports.useToolAction = useAction.useToolAction;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"hooks.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/hooks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useStreamingUI } from "./hooks/useStreamingUI.js";
1
+ import { DEFAULT_STREAMING_UI_MESSAGES, useStreamingUI } from "./hooks/useStreamingUI.js";
2
2
  import { useAction, useToolAction } from "./hooks/useAction.js";
3
3
  import { evaluateCondition, useConditionalField } from "./hooks/useConditionalField.js";
4
4
  import { useConfirmModal, useModal } from "./hooks/useModal.js";
@@ -8,6 +8,7 @@ import { useResize } from "./hooks/useResize.js";
8
8
  import { useAutocomplete } from "./hooks/useAutocomplete.js";
9
9
  import { useDataValidator } from "./hooks/useDataValidator.js";
10
10
  export {
11
+ DEFAULT_STREAMING_UI_MESSAGES,
11
12
  evaluateCondition,
12
13
  useAction,
13
14
  useAutocomplete,
package/dist/index.cjs CHANGED
@@ -44,15 +44,18 @@ const useResize = require("./hooks/useResize.cjs");
44
44
  const useAutocomplete = require("./hooks/useAutocomplete.cjs");
45
45
  const useDataValidator = require("./hooks/useDataValidator.cjs");
46
46
  const AutocompleteContext = require("./context/AutocompleteContext.cjs");
47
+ const validation = require("./services/validation.cjs");
48
+ const degradedProjections = require("./utils/degraded-projections.cjs");
49
+ const chartDataTable = require("./components/chart-data-table.cjs");
47
50
  const chatBus = require("./services/chat-bus.cjs");
48
51
  const chatPromptController = require("./services/chat-prompt-controller.cjs");
49
52
  const index = require("./testing/index.cjs");
50
53
  const componentRegistry = require("./services/component-registry.cjs");
51
- const validation = require("./services/validation.cjs");
52
54
  const MCPActionContext = require("./context/MCPActionContext.cjs");
53
55
  const groq = require("./plugins/groq.cjs");
54
56
  const rest = require("./plugins/rest.cjs");
55
57
  const supabase = require("./plugins/supabase.cjs");
58
+ const formatString = require("./utils/format-string.cjs");
56
59
  const dataValidator = require("./services/data-validator.cjs");
57
60
  exports.UIResourceRenderer = UIResourceRenderer.UIResourceRenderer;
58
61
  exports.renderCellValue = UIResourceRenderer.renderCellValue;
@@ -108,11 +111,13 @@ exports.setDuplicateMountReporter = duplicateMountRegistry.setDuplicateMountRepo
108
111
  exports.DEFAULT_MCPUI_STRINGS = MCPUIStringsContext.DEFAULT_MCPUI_STRINGS;
109
112
  exports.MCPUIStringsContext = MCPUIStringsContext.MCPUIStringsContext;
110
113
  exports.MCPUIStringsProvider = MCPUIStringsContext.MCPUIStringsProvider;
114
+ exports.resolveMCPUILocale = MCPUIStringsContext.resolveMCPUILocale;
111
115
  exports.useMCPUIStrings = MCPUIStringsContext.useMCPUIStrings;
112
116
  exports.MCPUITelemetryContext = MCPUITelemetryContext.MCPUITelemetryContext;
113
117
  exports.MCPUITelemetryProvider = MCPUITelemetryContext.MCPUITelemetryProvider;
114
118
  exports.useTelemetry = MCPUITelemetryContext.useTelemetry;
115
119
  exports.createTelemetryDispatcher = telemetry.createTelemetryDispatcher;
120
+ exports.DEFAULT_STREAMING_UI_MESSAGES = useStreamingUI.DEFAULT_STREAMING_UI_MESSAGES;
116
121
  exports.useStreamingUI = useStreamingUI.useStreamingUI;
117
122
  exports.useAction = useAction.useAction;
118
123
  exports.useToolAction = useAction.useToolAction;
@@ -128,6 +133,22 @@ exports.useDataValidator = useDataValidator.useDataValidator;
128
133
  exports.AutocompleteProvider = AutocompleteContext.AutocompleteProvider;
129
134
  exports.useAutocompleteContext = AutocompleteContext.useAutocompleteContext;
130
135
  exports.useAutocompleteContextSafe = AutocompleteContext.useAutocompleteContextSafe;
136
+ exports.DEFAULT_IFRAME_DOMAINS = validation.DEFAULT_IFRAME_DOMAINS;
137
+ exports.DEFAULT_RESOURCE_LIMITS = validation.DEFAULT_RESOURCE_LIMITS;
138
+ exports.DEFAULT_VALIDATION_MESSAGES = validation.DEFAULT_VALIDATION_MESSAGES;
139
+ exports.TRUSTED_IFRAME_DOMAINS = validation.TRUSTED_IFRAME_DOMAINS;
140
+ exports.getIframeSandbox = validation.getIframeSandbox;
141
+ exports.validateComponent = validation.validateComponent;
142
+ exports.validateFieldValue = validation.validateFieldValue;
143
+ exports.validateFormData = validation.validateFormData;
144
+ exports.validateIframeDomain = validation.validateIframeDomain;
145
+ exports.validateLayout = validation.validateLayout;
146
+ exports.DEGRADED_PROJECTION_LABELS = degradedProjections.DEGRADED_PROJECTION_LABELS;
147
+ exports.chartToDegradedTable = degradedProjections.chartToDegradedTable;
148
+ exports.graphToDegradedTable = degradedProjections.graphToDegradedTable;
149
+ exports.mapToDegradedTable = degradedProjections.mapToDegradedTable;
150
+ exports.CHART_DATA_TABLE_LABELS = chartDataTable.CHART_DATA_TABLE_LABELS;
151
+ exports.chartToDataTable = chartDataTable.chartToDataTable;
131
152
  exports.clarificationToPromptConfig = chatBus.clarificationToPromptConfig;
132
153
  exports.createChatBus = chatBus.createChatBus;
133
154
  exports.createCommandHandler = chatBus.createCommandHandler;
@@ -138,13 +159,6 @@ exports.PromptReplacedError = chatPromptController.PromptReplacedError;
138
159
  exports.createChatPromptController = chatPromptController.createChatPromptController;
139
160
  exports.createMockChatBus = index.createMockChatBus;
140
161
  exports.ComponentRegistry = componentRegistry.ComponentRegistry;
141
- exports.DEFAULT_IFRAME_DOMAINS = validation.DEFAULT_IFRAME_DOMAINS;
142
- exports.DEFAULT_RESOURCE_LIMITS = validation.DEFAULT_RESOURCE_LIMITS;
143
- exports.TRUSTED_IFRAME_DOMAINS = validation.TRUSTED_IFRAME_DOMAINS;
144
- exports.getIframeSandbox = validation.getIframeSandbox;
145
- exports.validateComponent = validation.validateComponent;
146
- exports.validateIframeDomain = validation.validateIframeDomain;
147
- exports.validateLayout = validation.validateLayout;
148
162
  exports.MCPActionContext = MCPActionContext.MCPActionContext;
149
163
  exports.MCPActionProvider = MCPActionContext.MCPActionProvider;
150
164
  exports.useMCPAction = MCPActionContext.useMCPAction;
@@ -152,5 +166,6 @@ exports.useMCPActionSafe = MCPActionContext.useMCPActionSafe;
152
166
  exports.createGroqPlugin = groq.createGroqPlugin;
153
167
  exports.createRestPlugin = rest.createRestPlugin;
154
168
  exports.createSupabasePlugin = supabase.createSupabasePlugin;
169
+ exports.formatMCPUIString = formatString.formatMCPUIString;
155
170
  exports.validateAgainstSource = dataValidator.validateAgainstSource;
156
171
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.cts CHANGED
@@ -67,7 +67,7 @@ export { markRenderStart, markRenderEnd, PERF_PREFIX } from './utils/perf';
67
67
  export { getUiResourceStableKey } from './utils/stable-key';
68
68
  export { setDuplicateMountReporter } from './utils/duplicate-mount-registry';
69
69
  export type { DuplicateMountInfo, DuplicateMountReporter, } from './utils/duplicate-mount-registry';
70
- export { MCPUIStringsProvider, MCPUIStringsContext, useMCPUIStrings, DEFAULT_MCPUI_STRINGS, } from './context/MCPUIStringsContext';
70
+ export { MCPUIStringsProvider, MCPUIStringsContext, useMCPUIStrings, DEFAULT_MCPUI_STRINGS, formatMCPUIString, resolveMCPUILocale, } from './context/MCPUIStringsContext';
71
71
  export type { MCPUIStrings, MCPUIStringsProviderProps, } from './context/MCPUIStringsContext';
72
72
  export { MCPUITelemetryProvider, MCPUITelemetryContext, useTelemetry, } from './context/MCPUITelemetryContext';
73
73
  export type { MCPUITelemetryProviderProps } from './context/MCPUITelemetryContext';
@@ -91,8 +91,8 @@ export type { BriefingDiffProps } from './components/BriefingDiff';
91
91
  export type { GhostTextProps, GhostTextInputProps } from './components/GhostText';
92
92
  export type { AutocompleteDropdownProps } from './components/AutocompleteDropdown';
93
93
  export type { AutocompleteFormFieldProps, AutocompleteFormFieldParams } from './components/AutocompleteFormField';
94
- export { useStreamingUI, useAction, useToolAction, useConditionalField, evaluateCondition, useModal, useConfirmModal, useFormPersistence, useDragDrop, useResize, useAutocomplete, useDataValidator, } from './hooks';
95
- export type { UseStreamingUIOptions, StreamingUIState, StreamProgress, StreamError, CompleteMetadata, UseActionReturn, UseActionOptions, UseToolActionReturn, UseConditionalFieldOptions, UseModalReturn, UseConfirmModalReturn, UseFormPersistenceOptions, UseFormPersistenceReturn, UseDragDropOptions, UseDragDropReturn, DragProps, UseResizeOptions, UseResizeReturn, ResizeEdge, UseAutocompleteOptions, UseAutocompleteReturn, UseDataValidatorOptions, UseDataValidatorReturn, } from './hooks';
94
+ export { useStreamingUI, DEFAULT_STREAMING_UI_MESSAGES, useAction, useToolAction, useConditionalField, evaluateCondition, useModal, useConfirmModal, useFormPersistence, useDragDrop, useResize, useAutocomplete, useDataValidator, } from './hooks';
95
+ export type { UseStreamingUIOptions, StreamingUIMessages, StreamingUIState, StreamProgress, StreamError, CompleteMetadata, UseActionReturn, UseActionOptions, UseToolActionReturn, UseConditionalFieldOptions, UseModalReturn, UseConfirmModalReturn, UseFormPersistenceOptions, UseFormPersistenceReturn, UseDragDropOptions, UseDragDropReturn, DragProps, UseResizeOptions, UseResizeReturn, ResizeEdge, UseAutocompleteOptions, UseAutocompleteReturn, UseDataValidatorOptions, UseDataValidatorReturn, } from './hooks';
96
96
  export { MCPActionProvider, MCPActionContext, useMCPAction, useMCPActionSafe } from './context';
97
97
  export { AutocompleteProvider, useAutocompleteContext, useAutocompleteContextSafe, } from './context/AutocompleteContext';
98
98
  export type { MCPActionContextValue, MCPActionProviderProps, ActionRequest, ActionResult, } from './context';
@@ -100,6 +100,12 @@ export type { AutocompleteContextValue, AutocompleteProviderProps, } from './con
100
100
  export { createGroqPlugin, createSupabasePlugin, createRestPlugin, } from './plugins';
101
101
  export type { UIComponent, UILayout, GridPosition, ComponentType, RendererError, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ActionComponentParams, GridComponentParams, FormFieldOption, FormFieldType, FormFieldParams, FormComponentParams, ShowWhenOperator, ShowWhenCondition, ActionRequestBase, ActionResultBase, ActionLifecycleCallbacks, ModalSize, ModalComponentParams, ActionGroupLayout, ActionGroupGap, ActionGroupParams, GalleryImage, ImageGalleryParams, VideoComponentParams, CodeComponentParams, LatLngPoint, MapMarker, MapComponentParams, MapPopupConfig, MapGeoJSONStyle, MapLayer, MapPMTilesConfig, IframePolicy, ValidationOptions, ResizeConstraints, DragDropConfig, DragEventData, DraggableGridItemProps as DraggableGridItemPropsType, AutocompleteResultType, AutocompleteOption, AutocompleteResult, AutocompleteContext, AutocompletePlugin, GroqPluginConfig, SupabasePluginConfig, DuckDBPluginConfig, RestPluginConfig, FieldAutocompleteConfig, AutocompleteProviderConfig, } from './types';
102
102
  export { validateComponent, validateLayout, validateIframeDomain, getIframeSandbox, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, TRUSTED_IFRAME_DOMAINS, ComponentRegistry, createEventEmitter, createCommandHandler, createChatBus, mergeScratchpadSections, validateAgainstSource, } from './services';
103
+ export { validateFieldValue, validateFormData, DEFAULT_VALIDATION_MESSAGES, } from './services/validation';
104
+ export type { FormValidationMessages } from './services/validation';
105
+ export { graphToDegradedTable, mapToDegradedTable, chartToDegradedTable, DEGRADED_PROJECTION_LABELS, } from './utils/degraded-projections';
106
+ export type { DegradedProjectionLabels } from './utils/degraded-projections';
107
+ export { chartToDataTable, CHART_DATA_TABLE_LABELS } from './components/chart-data-table';
108
+ export type { ChartDataTableLabels } from './components/chart-data-table';
103
109
  export { clarificationToPromptConfig } from './services/chat-bus';
104
110
  export { elicitationToPromptConfig } from './services/chat-bus';
105
111
  export { createChatPromptController, PromptReplacedError, } from './services/chat-prompt-controller';
package/dist/index.d.ts CHANGED
@@ -67,7 +67,7 @@ export { markRenderStart, markRenderEnd, PERF_PREFIX } from './utils/perf';
67
67
  export { getUiResourceStableKey } from './utils/stable-key';
68
68
  export { setDuplicateMountReporter } from './utils/duplicate-mount-registry';
69
69
  export type { DuplicateMountInfo, DuplicateMountReporter, } from './utils/duplicate-mount-registry';
70
- export { MCPUIStringsProvider, MCPUIStringsContext, useMCPUIStrings, DEFAULT_MCPUI_STRINGS, } from './context/MCPUIStringsContext';
70
+ export { MCPUIStringsProvider, MCPUIStringsContext, useMCPUIStrings, DEFAULT_MCPUI_STRINGS, formatMCPUIString, resolveMCPUILocale, } from './context/MCPUIStringsContext';
71
71
  export type { MCPUIStrings, MCPUIStringsProviderProps, } from './context/MCPUIStringsContext';
72
72
  export { MCPUITelemetryProvider, MCPUITelemetryContext, useTelemetry, } from './context/MCPUITelemetryContext';
73
73
  export type { MCPUITelemetryProviderProps } from './context/MCPUITelemetryContext';
@@ -91,8 +91,8 @@ export type { BriefingDiffProps } from './components/BriefingDiff';
91
91
  export type { GhostTextProps, GhostTextInputProps } from './components/GhostText';
92
92
  export type { AutocompleteDropdownProps } from './components/AutocompleteDropdown';
93
93
  export type { AutocompleteFormFieldProps, AutocompleteFormFieldParams } from './components/AutocompleteFormField';
94
- export { useStreamingUI, useAction, useToolAction, useConditionalField, evaluateCondition, useModal, useConfirmModal, useFormPersistence, useDragDrop, useResize, useAutocomplete, useDataValidator, } from './hooks';
95
- export type { UseStreamingUIOptions, StreamingUIState, StreamProgress, StreamError, CompleteMetadata, UseActionReturn, UseActionOptions, UseToolActionReturn, UseConditionalFieldOptions, UseModalReturn, UseConfirmModalReturn, UseFormPersistenceOptions, UseFormPersistenceReturn, UseDragDropOptions, UseDragDropReturn, DragProps, UseResizeOptions, UseResizeReturn, ResizeEdge, UseAutocompleteOptions, UseAutocompleteReturn, UseDataValidatorOptions, UseDataValidatorReturn, } from './hooks';
94
+ export { useStreamingUI, DEFAULT_STREAMING_UI_MESSAGES, useAction, useToolAction, useConditionalField, evaluateCondition, useModal, useConfirmModal, useFormPersistence, useDragDrop, useResize, useAutocomplete, useDataValidator, } from './hooks';
95
+ export type { UseStreamingUIOptions, StreamingUIMessages, StreamingUIState, StreamProgress, StreamError, CompleteMetadata, UseActionReturn, UseActionOptions, UseToolActionReturn, UseConditionalFieldOptions, UseModalReturn, UseConfirmModalReturn, UseFormPersistenceOptions, UseFormPersistenceReturn, UseDragDropOptions, UseDragDropReturn, DragProps, UseResizeOptions, UseResizeReturn, ResizeEdge, UseAutocompleteOptions, UseAutocompleteReturn, UseDataValidatorOptions, UseDataValidatorReturn, } from './hooks';
96
96
  export { MCPActionProvider, MCPActionContext, useMCPAction, useMCPActionSafe } from './context';
97
97
  export { AutocompleteProvider, useAutocompleteContext, useAutocompleteContextSafe, } from './context/AutocompleteContext';
98
98
  export type { MCPActionContextValue, MCPActionProviderProps, ActionRequest, ActionResult, } from './context';
@@ -100,6 +100,12 @@ export type { AutocompleteContextValue, AutocompleteProviderProps, } from './con
100
100
  export { createGroqPlugin, createSupabasePlugin, createRestPlugin, } from './plugins';
101
101
  export type { UIComponent, UILayout, GridPosition, ComponentType, RendererError, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ActionComponentParams, GridComponentParams, FormFieldOption, FormFieldType, FormFieldParams, FormComponentParams, ShowWhenOperator, ShowWhenCondition, ActionRequestBase, ActionResultBase, ActionLifecycleCallbacks, ModalSize, ModalComponentParams, ActionGroupLayout, ActionGroupGap, ActionGroupParams, GalleryImage, ImageGalleryParams, VideoComponentParams, CodeComponentParams, LatLngPoint, MapMarker, MapComponentParams, MapPopupConfig, MapGeoJSONStyle, MapLayer, MapPMTilesConfig, IframePolicy, ValidationOptions, ResizeConstraints, DragDropConfig, DragEventData, DraggableGridItemProps as DraggableGridItemPropsType, AutocompleteResultType, AutocompleteOption, AutocompleteResult, AutocompleteContext, AutocompletePlugin, GroqPluginConfig, SupabasePluginConfig, DuckDBPluginConfig, RestPluginConfig, FieldAutocompleteConfig, AutocompleteProviderConfig, } from './types';
102
102
  export { validateComponent, validateLayout, validateIframeDomain, getIframeSandbox, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, TRUSTED_IFRAME_DOMAINS, ComponentRegistry, createEventEmitter, createCommandHandler, createChatBus, mergeScratchpadSections, validateAgainstSource, } from './services';
103
+ export { validateFieldValue, validateFormData, DEFAULT_VALIDATION_MESSAGES, } from './services/validation';
104
+ export type { FormValidationMessages } from './services/validation';
105
+ export { graphToDegradedTable, mapToDegradedTable, chartToDegradedTable, DEGRADED_PROJECTION_LABELS, } from './utils/degraded-projections';
106
+ export type { DegradedProjectionLabels } from './utils/degraded-projections';
107
+ export { chartToDataTable, CHART_DATA_TABLE_LABELS } from './components/chart-data-table';
108
+ export type { ChartDataTableLabels } from './components/chart-data-table';
103
109
  export { clarificationToPromptConfig } from './services/chat-bus';
104
110
  export { elicitationToPromptConfig } from './services/chat-bus';
105
111
  export { createChatPromptController, PromptReplacedError, } from './services/chat-prompt-controller';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAGjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAA;AACpF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AAG7F,OAAO,EACL,oBAAoB,EACpB,oCAAoC,GACrC,MAAM,mCAAmC,CAAA;AAC1C,YAAY,EACV,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,mCAAmC,CAAA;AAC1C,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAG/B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAGtE,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,oCAAoC,CAAA;AAC3C,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,oCAAoC,CAAA;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAGpE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAE1E,YAAY,EACV,uBAAuB,EACvB,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,cAAc,CAAA;AAGrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAClE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAGtG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAC5E,YAAY,EACV,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,kCAAkC,CAAA;AAGzC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,YAAY,EACZ,yBAAyB,GAC1B,MAAM,+BAA+B,CAAA;AAGtC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,GACb,MAAM,iCAAiC,CAAA;AACxC,YAAY,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAA;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,YAAY,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EAAE,iBAAiB,IAAI,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AAChG,YAAY,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAA;AAC9F,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AACtG,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAC9E,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAC9E,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnF,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACjF,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAClF,YAAY,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAA;AAGjH,OAAO,EACL,cAAc,EACd,6BAA6B,EAC7B,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,kBAAkB,EAElB,WAAW,EACX,SAAS,EAET,eAAe,EAEf,gBAAgB,GACjB,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EAExB,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,UAAU,EAEV,sBAAsB,EACtB,qBAAqB,EAErB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE/F,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAA;AAEtC,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAA;AAItC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,WAAW,CAAA;AAMlB,YAAY,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EAEnB,eAAe,EACf,aAAa,EACb,eAAe,EACf,mBAAmB,EAEnB,gBAAgB,EAChB,iBAAiB,EAEjB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EAExB,SAAS,EACT,oBAAoB,EAEpB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EAEjB,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EAEpB,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,gBAAgB,EAEhB,YAAY,EACZ,iBAAiB,EAEjB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,sBAAsB,IAAI,0BAA0B,EAEpD,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,YAAY,CAAA;AAKnB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAA;AAC5E,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AACzF,YAAY,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAGzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAGjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAG/D,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,mCAAmC,CAAA;AAC1C,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAGnD,YAAY,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,EAEzB,cAAc,EACd,SAAS,EACT,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAEjB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,kBAAkB,CAAA"}