@elabs-ai/components-ai 4.1.0 → 5.0.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.
- package/README.md +3 -3
- package/dist/{_audio-player-media-chrome-T3XVXWRZ.js → _audio-player-media-chrome.js} +1 -1
- package/dist/_code-block-theme.js +12 -0
- package/dist/_code-block-theme.js.map +1 -0
- package/dist/{_flow-boundary-SHNWLQG5.js → _flow-boundary.js} +1 -1
- package/dist/_flow-boundary.js.map +1 -0
- package/dist/_flow-lazy.js +8 -0
- package/dist/_flow-lazy.js.map +1 -0
- package/dist/_lazy-boundary-conformance.js +2 -0
- package/dist/_lazy-boundary-conformance.js.map +1 -0
- package/dist/_lazy-cjk.js +13 -0
- package/dist/_lazy-cjk.js.map +1 -0
- package/dist/_lazy-engine-boundary.js +9 -0
- package/dist/_lazy-engine-boundary.js.map +1 -0
- package/dist/_lazy-math.js +13 -0
- package/dist/_lazy-math.js.map +1 -0
- package/dist/_lazy-mermaid.js +12 -0
- package/dist/_lazy-mermaid.js.map +1 -0
- package/dist/_mermaid-error-panel.js +9 -0
- package/dist/_mermaid-error-panel.js.map +1 -0
- package/dist/{_persona-rive-JEG44YHX.js → _persona-rive.js} +19 -24
- package/dist/_persona-rive.js.map +1 -0
- package/dist/_streamdown-i18n.js +21 -0
- package/dist/_streamdown-i18n.js.map +1 -0
- package/dist/_streamdown-safety.js +10 -0
- package/dist/_streamdown-safety.js.map +1 -0
- package/dist/_theme-scope-store.js +13 -0
- package/dist/_theme-scope-store.js.map +1 -0
- package/dist/a2ui/a2ui-surface.js +17 -0
- package/dist/a2ui/a2ui-surface.js.map +1 -0
- package/dist/a2ui/core/catalog.generated.js +10 -0
- package/dist/a2ui/core/catalog.generated.js.map +1 -0
- package/dist/a2ui/core/complete-json.js +10 -0
- package/dist/a2ui/core/complete-json.js.map +1 -0
- package/dist/a2ui/core/index.js +37 -0
- package/dist/a2ui/core/index.js.map +1 -0
- package/dist/a2ui/core/schema.js +11 -0
- package/dist/a2ui/core/schema.js.map +1 -0
- package/dist/a2ui/core/spec.js +10 -0
- package/dist/a2ui/core/spec.js.map +1 -0
- package/dist/a2ui/core/validate.js +16 -0
- package/dist/a2ui/core/validate.js.map +1 -0
- package/dist/a2ui/index.js +54 -0
- package/dist/a2ui/index.js.map +1 -0
- package/dist/a2ui/ui-catalog.js +18 -0
- package/dist/a2ui/ui-catalog.js.map +1 -0
- package/dist/agent-event.js +10 -0
- package/dist/agent-event.js.map +1 -0
- package/dist/agent-timeline.js +11 -0
- package/dist/agent-timeline.js.map +1 -0
- package/dist/agent.js +25 -0
- package/dist/agent.js.map +1 -0
- package/dist/artifact.js +23 -0
- package/dist/artifact.js.map +1 -0
- package/dist/asset-preview.js +22 -0
- package/dist/asset-preview.js.map +1 -0
- package/dist/attachments.js +33 -0
- package/dist/attachments.js.map +1 -0
- package/dist/audio-player.js +30 -0
- package/dist/audio-player.js.map +1 -0
- package/dist/audio-visualizer.js +9 -0
- package/dist/audio-visualizer.js.map +1 -0
- package/dist/canvas.js +10 -0
- package/dist/canvas.js.map +1 -0
- package/dist/chain-of-thought.js +22 -0
- package/dist/chain-of-thought.js.map +1 -0
- package/dist/chat-greeting.js +8 -0
- package/dist/chat-greeting.js.map +1 -0
- package/dist/chat-shell.js +9 -0
- package/dist/chat-shell.js.map +1 -0
- package/dist/checkpoint.js +13 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/chunk-2XOIG5TG.js +72 -0
- package/dist/chunk-2XOIG5TG.js.map +1 -0
- package/dist/chunk-34CQ2VHM.js +172 -0
- package/dist/chunk-34CQ2VHM.js.map +1 -0
- package/dist/chunk-3TDHPXZZ.js +60 -0
- package/dist/chunk-3TDHPXZZ.js.map +1 -0
- package/dist/chunk-3XNPMDZY.js +478 -0
- package/dist/chunk-3XNPMDZY.js.map +1 -0
- package/dist/chunk-3YPT3V7L.js +56 -0
- package/dist/chunk-3YPT3V7L.js.map +1 -0
- package/dist/chunk-475UEU2Q.js +87 -0
- package/dist/chunk-475UEU2Q.js.map +1 -0
- package/dist/chunk-4CBTII2I.js +95 -0
- package/dist/chunk-4CBTII2I.js.map +1 -0
- package/dist/chunk-4XRNIZMG.js +22 -0
- package/dist/chunk-4XRNIZMG.js.map +1 -0
- package/dist/chunk-5NNWUKK5.js +2 -0
- package/dist/chunk-5NNWUKK5.js.map +1 -0
- package/dist/chunk-5UOMU27Z.js +164 -0
- package/dist/chunk-5UOMU27Z.js.map +1 -0
- package/dist/chunk-5VGYZ62I.js +264 -0
- package/dist/chunk-5VGYZ62I.js.map +1 -0
- package/dist/chunk-6IQPH2OS.js +21 -0
- package/dist/chunk-6IQPH2OS.js.map +1 -0
- package/dist/chunk-6PB2MXCI.js +482 -0
- package/dist/chunk-6PB2MXCI.js.map +1 -0
- package/dist/chunk-7FD5CZEU.js +215 -0
- package/dist/chunk-7FD5CZEU.js.map +1 -0
- package/dist/chunk-7RL6KZDF.js +266 -0
- package/dist/chunk-7RL6KZDF.js.map +1 -0
- package/dist/chunk-ADOYAGGK.js +482 -0
- package/dist/chunk-ADOYAGGK.js.map +1 -0
- package/dist/chunk-AXMNJMMH.js +984 -0
- package/dist/chunk-AXMNJMMH.js.map +1 -0
- package/dist/chunk-BA3AEMOU.js +21 -0
- package/dist/chunk-BA3AEMOU.js.map +1 -0
- package/dist/chunk-BBHFOYML.js +336 -0
- package/dist/chunk-BBHFOYML.js.map +1 -0
- package/dist/chunk-BHUVISIY.js +221 -0
- package/dist/chunk-BHUVISIY.js.map +1 -0
- package/dist/chunk-BM2LWERA.js +100 -0
- package/dist/chunk-BM2LWERA.js.map +1 -0
- package/dist/chunk-CMOYXNPJ.js +211 -0
- package/dist/chunk-CMOYXNPJ.js.map +1 -0
- package/dist/chunk-CZP3RHC4.js +74 -0
- package/dist/chunk-CZP3RHC4.js.map +1 -0
- package/dist/chunk-DDG5JHQT.js +112 -0
- package/dist/chunk-DDG5JHQT.js.map +1 -0
- package/dist/chunk-DJODXO7I.js +38 -0
- package/dist/chunk-DJODXO7I.js.map +1 -0
- package/dist/chunk-DWJDJLPU.js +192 -0
- package/dist/chunk-DWJDJLPU.js.map +1 -0
- package/dist/chunk-DZW6LM22.js +45 -0
- package/dist/chunk-DZW6LM22.js.map +1 -0
- package/dist/chunk-ELGCZLZF.js +305 -0
- package/dist/chunk-ELGCZLZF.js.map +1 -0
- package/dist/chunk-EV3U6ZZB.js +209 -0
- package/dist/chunk-EV3U6ZZB.js.map +1 -0
- package/dist/chunk-EY7LVUKQ.js +87 -0
- package/dist/chunk-EY7LVUKQ.js.map +1 -0
- package/dist/chunk-F4C74F7M.js +230 -0
- package/dist/chunk-F4C74F7M.js.map +1 -0
- package/dist/chunk-FERYDFZA.js +108 -0
- package/dist/chunk-FERYDFZA.js.map +1 -0
- package/dist/chunk-FUIYG2DS.js +166 -0
- package/dist/chunk-FUIYG2DS.js.map +1 -0
- package/dist/chunk-GKYZT3LA.js +136 -0
- package/dist/chunk-GKYZT3LA.js.map +1 -0
- package/dist/chunk-H42LRUQ4.js +102 -0
- package/dist/chunk-H42LRUQ4.js.map +1 -0
- package/dist/chunk-HVXM2G5F.js +222 -0
- package/dist/chunk-HVXM2G5F.js.map +1 -0
- package/dist/chunk-I4RDAGVY.js +53 -0
- package/dist/chunk-I4RDAGVY.js.map +1 -0
- package/dist/chunk-IQJG4IDX.js +208 -0
- package/dist/chunk-IQJG4IDX.js.map +1 -0
- package/dist/chunk-IX2PXG4Y.js +144 -0
- package/dist/chunk-IX2PXG4Y.js.map +1 -0
- package/dist/chunk-IXICSOOP.js +287 -0
- package/dist/chunk-IXICSOOP.js.map +1 -0
- package/dist/chunk-JY5HSN4D.js +84 -0
- package/dist/chunk-JY5HSN4D.js.map +1 -0
- package/dist/chunk-LMNSBOBG.js +19 -0
- package/dist/chunk-LMNSBOBG.js.map +1 -0
- package/dist/chunk-MBI7D6IL.js +42 -0
- package/dist/chunk-MBI7D6IL.js.map +1 -0
- package/dist/chunk-MLFMYCPH.js +192 -0
- package/dist/chunk-MLFMYCPH.js.map +1 -0
- package/dist/chunk-MOK66734.js +33 -0
- package/dist/chunk-MOK66734.js.map +1 -0
- package/dist/chunk-MXTAWPYM.js +196 -0
- package/dist/chunk-MXTAWPYM.js.map +1 -0
- package/dist/chunk-NCL2UZKI.js +96 -0
- package/dist/chunk-NCL2UZKI.js.map +1 -0
- package/dist/chunk-NET4YLRY.js +107 -0
- package/dist/chunk-NET4YLRY.js.map +1 -0
- package/dist/chunk-NIG67CFM.js +329 -0
- package/dist/chunk-NIG67CFM.js.map +1 -0
- package/dist/chunk-NMVNNO3L.js +10 -0
- package/dist/chunk-NMVNNO3L.js.map +1 -0
- package/dist/chunk-NP7VID4K.js +2 -0
- package/dist/chunk-NP7VID4K.js.map +1 -0
- package/dist/chunk-NPUCMAG2.js +382 -0
- package/dist/chunk-NPUCMAG2.js.map +1 -0
- package/dist/chunk-NSCLRHES.js +102 -0
- package/dist/chunk-NSCLRHES.js.map +1 -0
- package/dist/chunk-OEUXHVFW.js +86 -0
- package/dist/chunk-OEUXHVFW.js.map +1 -0
- package/dist/chunk-ONBHFIMZ.js +137 -0
- package/dist/chunk-ONBHFIMZ.js.map +1 -0
- package/dist/chunk-OPH2HHL2.js +228 -0
- package/dist/chunk-OPH2HHL2.js.map +1 -0
- package/dist/chunk-OQERHIQP.js +287 -0
- package/dist/chunk-OQERHIQP.js.map +1 -0
- package/dist/chunk-P6YJAZFG.js +103 -0
- package/dist/chunk-P6YJAZFG.js.map +1 -0
- package/dist/chunk-PG7ERDOD.js +65 -0
- package/dist/chunk-PG7ERDOD.js.map +1 -0
- package/dist/chunk-PIB5JBMA.js +90 -0
- package/dist/chunk-PIB5JBMA.js.map +1 -0
- package/dist/chunk-PQ5BPIWQ.js +22 -0
- package/dist/chunk-PQ5BPIWQ.js.map +1 -0
- package/dist/chunk-PQBF6ZIQ.js +55 -0
- package/dist/chunk-PQBF6ZIQ.js.map +1 -0
- package/dist/chunk-PTWCTSZL.js +173 -0
- package/dist/chunk-PTWCTSZL.js.map +1 -0
- package/dist/chunk-QJUNPVOS.js +101 -0
- package/dist/chunk-QJUNPVOS.js.map +1 -0
- package/dist/chunk-QUDZOTRV.js +43 -0
- package/dist/chunk-QUDZOTRV.js.map +1 -0
- package/dist/chunk-RB7G65JC.js +213 -0
- package/dist/chunk-RB7G65JC.js.map +1 -0
- package/dist/chunk-RPHAOR7P.js +45 -0
- package/dist/chunk-RPHAOR7P.js.map +1 -0
- package/dist/chunk-RTCSH2AN.js +331 -0
- package/dist/chunk-RTCSH2AN.js.map +1 -0
- package/dist/chunk-S3ISPW3A.js +28 -0
- package/dist/chunk-S3ISPW3A.js.map +1 -0
- package/dist/chunk-SEVN656N.js +36 -0
- package/dist/chunk-SEVN656N.js.map +1 -0
- package/dist/chunk-SKVG672B.js +64 -0
- package/dist/chunk-SKVG672B.js.map +1 -0
- package/dist/chunk-SPQIU7GA.js +236 -0
- package/dist/chunk-SPQIU7GA.js.map +1 -0
- package/dist/chunk-SSGJ6MEM.js +1076 -0
- package/dist/chunk-SSGJ6MEM.js.map +1 -0
- package/dist/chunk-SSKZ2AED.js +118 -0
- package/dist/chunk-SSKZ2AED.js.map +1 -0
- package/dist/chunk-T56JFGXI.js +561 -0
- package/dist/chunk-T56JFGXI.js.map +1 -0
- package/dist/chunk-TCB6O74A.js +137 -0
- package/dist/chunk-TCB6O74A.js.map +1 -0
- package/dist/chunk-TTEYPO6X.js +57 -0
- package/dist/chunk-TTEYPO6X.js.map +1 -0
- package/dist/chunk-TWPHAJNM.js +462 -0
- package/dist/chunk-TWPHAJNM.js.map +1 -0
- package/dist/chunk-TXJJLP4O.js +336 -0
- package/dist/chunk-TXJJLP4O.js.map +1 -0
- package/dist/chunk-TZ6TB7VM.js +245 -0
- package/dist/chunk-TZ6TB7VM.js.map +1 -0
- package/dist/chunk-UBLKJJ7K.js +278 -0
- package/dist/chunk-UBLKJJ7K.js.map +1 -0
- package/dist/chunk-UCJ6IUFS.js +52 -0
- package/dist/chunk-UCJ6IUFS.js.map +1 -0
- package/dist/chunk-UCKFJ3QF.js +197 -0
- package/dist/chunk-UCKFJ3QF.js.map +1 -0
- package/dist/chunk-UPXSLILN.js +20 -0
- package/dist/chunk-UPXSLILN.js.map +1 -0
- package/dist/chunk-V4DORGWJ.js +92 -0
- package/dist/chunk-V4DORGWJ.js.map +1 -0
- package/dist/chunk-V6E5DYZD.js +80 -0
- package/dist/chunk-V6E5DYZD.js.map +1 -0
- package/dist/chunk-VLLYKF3P.js +96 -0
- package/dist/chunk-VLLYKF3P.js.map +1 -0
- package/dist/chunk-VLNBTOH6.js +43 -0
- package/dist/chunk-VLNBTOH6.js.map +1 -0
- package/dist/chunk-WMDSMSPL.js +303 -0
- package/dist/chunk-WMDSMSPL.js.map +1 -0
- package/dist/chunk-WU5BLGTF.js +149 -0
- package/dist/chunk-WU5BLGTF.js.map +1 -0
- package/dist/chunk-WYTZVSGK.js +245 -0
- package/dist/chunk-WYTZVSGK.js.map +1 -0
- package/dist/chunk-X47QMM6K.js +187 -0
- package/dist/chunk-X47QMM6K.js.map +1 -0
- package/dist/chunk-XNBKO32Y.js +174 -0
- package/dist/chunk-XNBKO32Y.js.map +1 -0
- package/dist/chunk-YHUSW7D2.js +40 -0
- package/dist/chunk-YHUSW7D2.js.map +1 -0
- package/dist/chunk-YSKD7UXX.js +126 -0
- package/dist/chunk-YSKD7UXX.js.map +1 -0
- package/dist/chunk-YYRDGWOU.js +72 -0
- package/dist/chunk-YYRDGWOU.js.map +1 -0
- package/dist/chunk-ZIGZMWM7.js +19 -0
- package/dist/chunk-ZIGZMWM7.js.map +1 -0
- package/dist/chunk-ZKRTUKNP.js +40 -0
- package/dist/chunk-ZKRTUKNP.js.map +1 -0
- package/dist/code-block.js +38 -0
- package/dist/code-block.js.map +1 -0
- package/dist/commit.js +51 -0
- package/dist/commit.js.map +1 -0
- package/dist/composer.js +15 -0
- package/dist/composer.js.map +1 -0
- package/dist/confirmation.js +53 -0
- package/dist/confirmation.js.map +1 -0
- package/dist/connection.js +8 -0
- package/dist/connection.js.map +1 -0
- package/dist/context-panel.js +25 -0
- package/dist/context-panel.js.map +1 -0
- package/dist/controls.js +10 -0
- package/dist/controls.js.map +1 -0
- package/dist/conversation.js +19 -0
- package/dist/conversation.js.map +1 -0
- package/dist/diff-view.js +15 -0
- package/dist/diff-view.js.map +1 -0
- package/dist/edge.js +10 -0
- package/dist/edge.js.map +1 -0
- package/dist/environment-variables.js +29 -0
- package/dist/environment-variables.js.map +1 -0
- package/dist/file-tree.js +23 -0
- package/dist/file-tree.js.map +1 -0
- package/dist/gallery.js +9 -0
- package/dist/gallery.js.map +1 -0
- package/dist/grouped-parts.js +21 -0
- package/dist/grouped-parts.js.map +1 -0
- package/dist/image.js +9 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +403 -108
- package/dist/index.js +671 -13205
- package/dist/index.js.map +1 -1
- package/dist/inline-citation.js +39 -0
- package/dist/inline-citation.js.map +1 -0
- package/dist/jsx-preview.js +17 -0
- package/dist/jsx-preview.js.map +1 -0
- package/dist/markdown-view.js +17 -0
- package/dist/markdown-view.js.map +1 -0
- package/dist/message-compare.js +12 -0
- package/dist/message-compare.js.map +1 -0
- package/dist/message-edit.js +19 -0
- package/dist/message-edit.js.map +1 -0
- package/dist/message-feedback.js +11 -0
- package/dist/message-feedback.js.map +1 -0
- package/dist/message-form-spec.js +38 -0
- package/dist/message-form-spec.js.map +1 -0
- package/dist/message-form.js +26 -0
- package/dist/message-form.js.map +1 -0
- package/dist/message-table-spec.js +26 -0
- package/dist/message-table-spec.js.map +1 -0
- package/dist/message-table.js +12 -0
- package/dist/message-table.js.map +1 -0
- package/dist/message.js +51 -0
- package/dist/message.js.map +1 -0
- package/dist/mic-selector.js +27 -0
- package/dist/mic-selector.js.map +1 -0
- package/dist/model-provider-logo.js +13 -0
- package/dist/model-provider-logo.js.map +1 -0
- package/dist/motion-config.js +9 -0
- package/dist/motion-config.js.map +1 -0
- package/dist/node.js +22 -0
- package/dist/node.js.map +1 -0
- package/dist/open-in-chat.js +31 -0
- package/dist/open-in-chat.js.map +1 -0
- package/dist/package-info.js +25 -0
- package/dist/package-info.js.map +1 -0
- package/dist/panel.js +10 -0
- package/dist/panel.js.map +1 -0
- package/dist/part-groups.js +18 -0
- package/dist/part-groups.js.map +1 -0
- package/dist/permission-mode-select.js +9 -0
- package/dist/permission-mode-select.js.map +1 -0
- package/dist/persona-sources.js +8 -0
- package/dist/persona-sources.js.map +1 -0
- package/dist/persona.js +14 -0
- package/dist/persona.js.map +1 -0
- package/dist/plan.js +32 -0
- package/dist/plan.js.map +1 -0
- package/dist/prompt-input-effort.js +9 -0
- package/dist/prompt-input-effort.js.map +1 -0
- package/dist/prompt-input-mode.js +10 -0
- package/dist/prompt-input-mode.js.map +1 -0
- package/dist/prompt-input-slash.js +12 -0
- package/dist/prompt-input-slash.js.map +1 -0
- package/dist/prompt-input.js +89 -0
- package/dist/prompt-input.js.map +1 -0
- package/dist/queue.js +37 -0
- package/dist/queue.js.map +1 -0
- package/dist/reasoning.js +23 -0
- package/dist/reasoning.js.map +1 -0
- package/dist/sandbox.js +28 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/schema-display.js +33 -0
- package/dist/schema-display.js.map +1 -0
- package/dist/selection-toolbar.js +11 -0
- package/dist/selection-toolbar.js.map +1 -0
- package/dist/session-header.js +9 -0
- package/dist/session-header.js.map +1 -0
- package/dist/session-status-bar.js +9 -0
- package/dist/session-status-bar.js.map +1 -0
- package/dist/shimmer.js +9 -0
- package/dist/shimmer.js.map +1 -0
- package/dist/snippet.js +17 -0
- package/dist/snippet.js.map +1 -0
- package/dist/sources.js +17 -0
- package/dist/sources.js.map +1 -0
- package/dist/speech-input.js +9 -0
- package/dist/speech-input.js.map +1 -0
- package/dist/stack-trace.js +27 -0
- package/dist/stack-trace.js.map +1 -0
- package/dist/suggestion.js +16 -0
- package/dist/suggestion.js.map +1 -0
- package/dist/task.js +18 -0
- package/dist/task.js.map +1 -0
- package/dist/test-results.js +43 -0
- package/dist/test-results.js.map +1 -0
- package/dist/token-usage.js +27 -0
- package/dist/token-usage.js.map +1 -0
- package/dist/tool-result-card.js +9 -0
- package/dist/tool-result-card.js.map +1 -0
- package/dist/tool.js +27 -0
- package/dist/tool.js.map +1 -0
- package/dist/toolbar.js +10 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/transcription.js +11 -0
- package/dist/transcription.js.map +1 -0
- package/dist/turn-status.js +9 -0
- package/dist/turn-status.js.map +1 -0
- package/dist/use-audio-level.js +9 -0
- package/dist/use-audio-level.js.map +1 -0
- package/dist/voice-selector.js +47 -0
- package/dist/voice-selector.js.map +1 -0
- package/dist/web-preview.js +19 -0
- package/dist/web-preview.js.map +1 -0
- package/package.json +12 -10
- package/schemas/a2ui-surface.v1.schema.json +5425 -0
- package/src/__contract__/audio-visualizer.contract.test.tsx +49 -0
- package/src/__contract__/chat-shell.contract.test.tsx +49 -0
- package/src/__contract__/grouped-parts.contract.test.tsx +49 -0
- package/src/__contract__/image.contract.test.tsx +49 -0
- package/src/__contract__/markdown-view.contract.test.tsx +49 -0
- package/src/__contract__/message-feedback.contract.test.tsx +49 -0
- package/src/__contract__/message-form.contract.test.tsx +49 -0
- package/src/__contract__/message-table.contract.test.tsx +49 -0
- package/src/__contract__/model-provider-logo.contract.test.tsx +49 -0
- package/src/__contract__/persona.contract.test.tsx +49 -0
- package/src/__contract__/prompt-input-effort.contract.test.tsx +49 -0
- package/src/__contract__/prompt-input-mode.contract.test.tsx +49 -0
- package/src/_chat-shell-rail.tsx +4 -2
- package/src/_flow-boundary.tsx +2 -2
- package/src/_lazy-cjk.test.ts +43 -0
- package/src/_lazy-cjk.ts +73 -0
- package/src/_lazy-math.test.ts +63 -0
- package/src/_lazy-math.ts +90 -0
- package/src/_persona-rive.tsx +27 -41
- package/src/_streamdown-i18n.ts +73 -21
- package/src/_streamdown-safety.ts +2 -2
- package/src/_theme-scope-store.test.ts +83 -0
- package/src/_theme-scope-store.ts +103 -0
- package/src/a2ui/a2ui-surface.stories.tsx +662 -0
- package/src/a2ui/a2ui-surface.test.tsx +201 -0
- package/src/a2ui/a2ui-surface.tsx +354 -0
- package/src/a2ui/catalog.source.json +772 -0
- package/src/a2ui/core/a2ui-core.test.ts +178 -0
- package/src/a2ui/core/catalog.generated.ts +1006 -0
- package/src/a2ui/core/complete-json.ts +81 -0
- package/src/a2ui/core/index.ts +10 -0
- package/src/a2ui/core/schema.ts +111 -0
- package/src/a2ui/core/spec.ts +148 -0
- package/src/a2ui/core/validate.ts +266 -0
- package/src/a2ui/index.ts +7 -0
- package/src/a2ui/ui-catalog.tsx +225 -0
- package/src/a2ui/wave1-chart-spec.test.ts +87 -0
- package/src/a2ui/wave2-chart-spec.test.ts +108 -0
- package/src/agent-event.tsx +1 -1
- package/src/agent.tsx +18 -13
- package/src/agentic-workspace.stories.tsx +6 -45
- package/src/artifact.tsx +2 -2
- package/src/asset-preview.test.tsx +40 -0
- package/src/asset-preview.tsx +83 -12
- package/src/attachments.tsx +7 -4
- package/src/chat-shell.test.tsx +40 -10
- package/src/chat-shell.tsx +90 -44
- package/src/chat.stories.tsx +47 -42
- package/src/code-block.test.tsx +100 -1
- package/src/code-block.tsx +166 -103
- package/src/commit.tsx +30 -41
- package/src/composer.stories.tsx +4 -5
- package/src/composer.test.tsx +45 -0
- package/src/composer.tsx +104 -21
- package/src/confirmation.tsx +1 -1
- package/src/context-panel.stories.tsx +1 -1
- package/src/context-panel.tsx +2 -2
- package/src/conversation.stories.tsx +24 -0
- package/src/conversation.test.tsx +69 -0
- package/src/conversation.tsx +47 -8
- package/src/diff-view.stories.tsx +79 -0
- package/src/diff-view.test.tsx +52 -2
- package/src/diff-view.tsx +92 -36
- package/src/environment-variables.tsx +20 -37
- package/src/file-tree.test.tsx +21 -0
- package/src/file-tree.tsx +33 -16
- package/src/gallery.stories.tsx +42 -0
- package/src/gallery.tsx +2 -2
- package/src/grouped-parts.stories.tsx +23 -0
- package/src/grouped-parts.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/inline-citation.tsx +5 -5
- package/src/jsx-preview.tsx +151 -43
- package/src/markdown-view.test.tsx +7 -3
- package/src/markdown-view.tsx +8 -1
- package/src/message-compare.stories.tsx +40 -0
- package/src/message-compare.tsx +2 -1
- package/src/message-form.stories.tsx +36 -3
- package/src/message-form.test.tsx +8 -2
- package/src/message-form.tsx +16 -8
- package/src/message-table.stories.tsx +26 -2
- package/src/message-table.test.tsx +7 -0
- package/src/message-table.tsx +9 -5
- package/src/message.test.tsx +73 -3
- package/src/message.tsx +36 -12
- package/src/model-provider-logo.test.tsx +57 -3
- package/src/model-provider-logo.tsx +45 -11
- package/src/open-in-chat.tsx +50 -29
- package/src/package-info.tsx +23 -20
- package/src/prompt-input-slash.stories.tsx +1 -1
- package/src/prompt-input.test.tsx +67 -1
- package/src/prompt-input.tsx +42 -4
- package/src/queue.tsx +4 -4
- package/src/reasoning.stories.tsx +27 -0
- package/src/reasoning.tsx +17 -6
- package/src/sandbox.tsx +3 -3
- package/src/schema-display.test.tsx +56 -0
- package/src/schema-display.tsx +68 -37
- package/src/session-header.stories.tsx +35 -1
- package/src/session-header.tsx +1 -1
- package/src/snippet.test.tsx +6 -2
- package/src/snippet.tsx +14 -34
- package/src/sources.stories.tsx +30 -0
- package/src/sources.tsx +4 -1
- package/src/speech-input.test.tsx +109 -0
- package/src/speech-input.tsx +31 -3
- package/src/stack-trace.tsx +20 -36
- package/src/streamdown-i18n.test.tsx +23 -0
- package/src/templates-ai-assistant.stories.tsx +151 -87
- package/src/test-results.tsx +47 -27
- package/src/token-usage.tsx +6 -6
- package/src/tool.stories.tsx +39 -0
- package/src/tool.test.tsx +65 -0
- package/src/tool.tsx +61 -25
- package/src/toolbar.tsx +0 -10
- package/src/transcription.tsx +1 -1
- package/src/voice-selector.tsx +5 -5
- package/src/web-preview.test.tsx +51 -1
- package/src/web-preview.tsx +39 -8
- package/dist/_flow-boundary-SHNWLQG5.js.map +0 -1
- package/dist/_persona-rive-JEG44YHX.js.map +0 -1
- /package/dist/{_audio-player-media-chrome-T3XVXWRZ.js.map → _audio-player-media-chrome.js.map} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/mic-selector.tsx
|
|
4
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
5
|
+
import { Button } from "@elabs-ai/components-ui";
|
|
6
|
+
import {
|
|
7
|
+
Command,
|
|
8
|
+
CommandEmpty,
|
|
9
|
+
CommandInput,
|
|
10
|
+
CommandItem,
|
|
11
|
+
CommandList
|
|
12
|
+
} from "@elabs-ai/components-ui";
|
|
13
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@elabs-ai/components-ui";
|
|
14
|
+
import { cn } from "@elabs-ai/components-ui/lib/cn";
|
|
15
|
+
import { useLocale } from "@elabs-ai/components-ui";
|
|
16
|
+
import { ChevronsUpDownIcon } from "lucide-react";
|
|
17
|
+
import {
|
|
18
|
+
createContext,
|
|
19
|
+
useCallback,
|
|
20
|
+
useContext,
|
|
21
|
+
useEffect,
|
|
22
|
+
useMemo,
|
|
23
|
+
useRef,
|
|
24
|
+
useState
|
|
25
|
+
} from "react";
|
|
26
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
27
|
+
var deviceIdRegex = /\(([\da-fA-F]{4}:[\da-fA-F]{4})\)$/;
|
|
28
|
+
var MicSelectorContext = createContext({
|
|
29
|
+
data: [],
|
|
30
|
+
onOpenChange: void 0,
|
|
31
|
+
onValueChange: void 0,
|
|
32
|
+
open: false,
|
|
33
|
+
setWidth: void 0,
|
|
34
|
+
value: void 0,
|
|
35
|
+
width: 200
|
|
36
|
+
});
|
|
37
|
+
var useAudioDevices = () => {
|
|
38
|
+
const [devices, setDevices] = useState([]);
|
|
39
|
+
const [loading, setLoading] = useState(true);
|
|
40
|
+
const [error, setError] = useState(null);
|
|
41
|
+
const [hasPermission, setHasPermission] = useState(false);
|
|
42
|
+
const loadDevicesWithoutPermission = useCallback(async () => {
|
|
43
|
+
try {
|
|
44
|
+
setLoading(true);
|
|
45
|
+
setError(null);
|
|
46
|
+
const deviceList = await navigator.mediaDevices.enumerateDevices();
|
|
47
|
+
const audioInputs = deviceList.filter((device) => device.kind === "audioinput");
|
|
48
|
+
setDevices(audioInputs);
|
|
49
|
+
} catch (caughtError) {
|
|
50
|
+
const message = caughtError instanceof Error ? caughtError.message : "Failed to get audio devices";
|
|
51
|
+
setError(message);
|
|
52
|
+
console.error("Error getting audio devices:", message);
|
|
53
|
+
} finally {
|
|
54
|
+
setLoading(false);
|
|
55
|
+
}
|
|
56
|
+
}, []);
|
|
57
|
+
const loadDevicesWithPermission = useCallback(async () => {
|
|
58
|
+
if (loading) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
setLoading(true);
|
|
63
|
+
setError(null);
|
|
64
|
+
const tempStream = await navigator.mediaDevices.getUserMedia({
|
|
65
|
+
audio: true
|
|
66
|
+
});
|
|
67
|
+
for (const track of tempStream.getTracks()) {
|
|
68
|
+
track.stop();
|
|
69
|
+
}
|
|
70
|
+
const deviceList = await navigator.mediaDevices.enumerateDevices();
|
|
71
|
+
const audioInputs = deviceList.filter((device) => device.kind === "audioinput");
|
|
72
|
+
setDevices(audioInputs);
|
|
73
|
+
setHasPermission(true);
|
|
74
|
+
} catch (caughtError) {
|
|
75
|
+
const message = caughtError instanceof Error ? caughtError.message : "Failed to get audio devices";
|
|
76
|
+
setError(message);
|
|
77
|
+
console.error("Error getting audio devices:", message);
|
|
78
|
+
} finally {
|
|
79
|
+
setLoading(false);
|
|
80
|
+
}
|
|
81
|
+
}, [loading]);
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
loadDevicesWithoutPermission();
|
|
84
|
+
}, [loadDevicesWithoutPermission]);
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const handleDeviceChange = () => {
|
|
87
|
+
if (hasPermission) {
|
|
88
|
+
loadDevicesWithPermission();
|
|
89
|
+
} else {
|
|
90
|
+
loadDevicesWithoutPermission();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
navigator.mediaDevices.addEventListener("devicechange", handleDeviceChange);
|
|
94
|
+
return () => {
|
|
95
|
+
navigator.mediaDevices.removeEventListener("devicechange", handleDeviceChange);
|
|
96
|
+
};
|
|
97
|
+
}, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission]);
|
|
98
|
+
return {
|
|
99
|
+
devices,
|
|
100
|
+
error,
|
|
101
|
+
hasPermission,
|
|
102
|
+
loadDevices: loadDevicesWithPermission,
|
|
103
|
+
loading
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
var MicSelector = ({
|
|
107
|
+
defaultValue,
|
|
108
|
+
value: controlledValue,
|
|
109
|
+
onValueChange: controlledOnValueChange,
|
|
110
|
+
defaultOpen = false,
|
|
111
|
+
open: controlledOpen,
|
|
112
|
+
onOpenChange: controlledOnOpenChange,
|
|
113
|
+
...props
|
|
114
|
+
}) => {
|
|
115
|
+
const [value, onValueChange] = useControllableState({
|
|
116
|
+
defaultProp: defaultValue,
|
|
117
|
+
onChange: controlledOnValueChange,
|
|
118
|
+
prop: controlledValue
|
|
119
|
+
});
|
|
120
|
+
const [open, onOpenChange] = useControllableState({
|
|
121
|
+
defaultProp: defaultOpen,
|
|
122
|
+
onChange: controlledOnOpenChange,
|
|
123
|
+
prop: controlledOpen
|
|
124
|
+
});
|
|
125
|
+
const [width, setWidth] = useState(200);
|
|
126
|
+
const { devices, loading, hasPermission, loadDevices } = useAudioDevices();
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (open && !hasPermission && !loading) {
|
|
129
|
+
loadDevices();
|
|
130
|
+
}
|
|
131
|
+
}, [open, hasPermission, loading, loadDevices]);
|
|
132
|
+
const contextValue = useMemo(
|
|
133
|
+
() => ({
|
|
134
|
+
data: devices,
|
|
135
|
+
onOpenChange,
|
|
136
|
+
onValueChange,
|
|
137
|
+
open,
|
|
138
|
+
setWidth,
|
|
139
|
+
value,
|
|
140
|
+
width
|
|
141
|
+
}),
|
|
142
|
+
[devices, onOpenChange, onValueChange, open, setWidth, value, width]
|
|
143
|
+
);
|
|
144
|
+
return /* @__PURE__ */ jsx(MicSelectorContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Popover, { ...props, onOpenChange, open }) });
|
|
145
|
+
};
|
|
146
|
+
var MicSelectorTrigger = ({ children, ...props }) => {
|
|
147
|
+
const { setWidth } = useContext(MicSelectorContext);
|
|
148
|
+
const ref = useRef(null);
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
151
|
+
for (const entry of entries) {
|
|
152
|
+
const newWidth = entry.target.offsetWidth;
|
|
153
|
+
if (newWidth) {
|
|
154
|
+
setWidth?.(newWidth);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (ref.current) {
|
|
159
|
+
resizeObserver.observe(ref.current);
|
|
160
|
+
}
|
|
161
|
+
return () => {
|
|
162
|
+
resizeObserver.disconnect();
|
|
163
|
+
};
|
|
164
|
+
}, [setWidth]);
|
|
165
|
+
return /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", ...props, ref, children: [
|
|
166
|
+
children,
|
|
167
|
+
/* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "shrink-0 text-muted-foreground", size: 16 })
|
|
168
|
+
] }) });
|
|
169
|
+
};
|
|
170
|
+
var MicSelectorContent = ({
|
|
171
|
+
className,
|
|
172
|
+
popoverOptions,
|
|
173
|
+
...props
|
|
174
|
+
}) => {
|
|
175
|
+
const { width, onValueChange, value } = useContext(MicSelectorContext);
|
|
176
|
+
return /* @__PURE__ */ jsx(PopoverContent, { className: cn("p-0", className), style: { width }, ...popoverOptions, children: /* @__PURE__ */ jsx(Command, { onValueChange, value, ...props }) });
|
|
177
|
+
};
|
|
178
|
+
var MicSelectorInput = ({ ...props }) => {
|
|
179
|
+
const { t } = useLocale();
|
|
180
|
+
return /* @__PURE__ */ jsx(CommandInput, { placeholder: t("ai.micSelector.searchPlaceholder"), ...props });
|
|
181
|
+
};
|
|
182
|
+
var MicSelectorList = ({ children, ...props }) => {
|
|
183
|
+
const { data } = useContext(MicSelectorContext);
|
|
184
|
+
return /* @__PURE__ */ jsx(CommandList, { ...props, children: children(data) });
|
|
185
|
+
};
|
|
186
|
+
var MicSelectorEmpty = ({
|
|
187
|
+
children = "No microphone found.",
|
|
188
|
+
...props
|
|
189
|
+
}) => /* @__PURE__ */ jsx(CommandEmpty, { ...props, children });
|
|
190
|
+
var MicSelectorItem = (props) => {
|
|
191
|
+
const { onValueChange, onOpenChange } = useContext(MicSelectorContext);
|
|
192
|
+
const handleSelect = useCallback(
|
|
193
|
+
(currentValue) => {
|
|
194
|
+
onValueChange?.(currentValue);
|
|
195
|
+
onOpenChange?.(false);
|
|
196
|
+
},
|
|
197
|
+
[onValueChange, onOpenChange]
|
|
198
|
+
);
|
|
199
|
+
return /* @__PURE__ */ jsx(CommandItem, { onSelect: handleSelect, ...props });
|
|
200
|
+
};
|
|
201
|
+
var MicSelectorLabel = ({ device, className, ...props }) => {
|
|
202
|
+
const matches = device.label.match(deviceIdRegex);
|
|
203
|
+
if (!matches) {
|
|
204
|
+
return /* @__PURE__ */ jsx("span", { className, ...props, children: device.label });
|
|
205
|
+
}
|
|
206
|
+
const [, deviceId] = matches;
|
|
207
|
+
const name = device.label.replace(deviceIdRegex, "");
|
|
208
|
+
return /* @__PURE__ */ jsxs("span", { className, ...props, children: [
|
|
209
|
+
/* @__PURE__ */ jsx("span", { children: name }),
|
|
210
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
211
|
+
" (",
|
|
212
|
+
deviceId,
|
|
213
|
+
")"
|
|
214
|
+
] })
|
|
215
|
+
] });
|
|
216
|
+
};
|
|
217
|
+
var MicSelectorValue = ({ className, ...props }) => {
|
|
218
|
+
const { data, value } = useContext(MicSelectorContext);
|
|
219
|
+
const currentDevice = data.find((d) => d.deviceId === value);
|
|
220
|
+
if (!currentDevice) {
|
|
221
|
+
return /* @__PURE__ */ jsx("span", { className: cn("flex-1 text-start", className), ...props, children: "Select microphone..." });
|
|
222
|
+
}
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
MicSelectorLabel,
|
|
225
|
+
{
|
|
226
|
+
className: cn("flex-1 text-start", className),
|
|
227
|
+
device: currentDevice,
|
|
228
|
+
...props
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export {
|
|
234
|
+
useAudioDevices,
|
|
235
|
+
MicSelector,
|
|
236
|
+
MicSelectorTrigger,
|
|
237
|
+
MicSelectorContent,
|
|
238
|
+
MicSelectorInput,
|
|
239
|
+
MicSelectorList,
|
|
240
|
+
MicSelectorEmpty,
|
|
241
|
+
MicSelectorItem,
|
|
242
|
+
MicSelectorLabel,
|
|
243
|
+
MicSelectorValue
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=chunk-WYTZVSGK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mic-selector.tsx"],"sourcesContent":["\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { Button } from \"@elabs-ai/components-ui\";\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@elabs-ai/components-ui\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { useLocale } from \"@elabs-ai/components-ui\";\nimport { ChevronsUpDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nconst deviceIdRegex = /\\(([\\da-fA-F]{4}:[\\da-fA-F]{4})\\)$/;\n\ninterface MicSelectorContextType {\n data: MediaDeviceInfo[];\n value: string | undefined;\n onValueChange?: (value: string) => void;\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n width: number;\n setWidth?: (width: number) => void;\n}\n\nconst MicSelectorContext = createContext<MicSelectorContextType>({\n data: [],\n onOpenChange: undefined,\n onValueChange: undefined,\n open: false,\n setWidth: undefined,\n value: undefined,\n width: 200,\n});\n\nexport const useAudioDevices = () => {\n const [devices, setDevices] = useState<MediaDeviceInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [hasPermission, setHasPermission] = useState(false);\n\n const loadDevicesWithoutPermission = useCallback(async () => {\n try {\n setLoading(true);\n setError(null);\n\n const deviceList = await navigator.mediaDevices.enumerateDevices();\n const audioInputs = deviceList.filter((device) => device.kind === \"audioinput\");\n\n setDevices(audioInputs);\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : \"Failed to get audio devices\";\n\n setError(message);\n console.error(\"Error getting audio devices:\", message);\n } finally {\n setLoading(false);\n }\n }, []);\n\n const loadDevicesWithPermission = useCallback(async () => {\n if (loading) {\n return;\n }\n\n try {\n setLoading(true);\n setError(null);\n\n const tempStream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n\n for (const track of tempStream.getTracks()) {\n track.stop();\n }\n\n const deviceList = await navigator.mediaDevices.enumerateDevices();\n const audioInputs = deviceList.filter((device) => device.kind === \"audioinput\");\n\n setDevices(audioInputs);\n setHasPermission(true);\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : \"Failed to get audio devices\";\n\n setError(message);\n console.error(\"Error getting audio devices:\", message);\n } finally {\n setLoading(false);\n }\n }, [loading]);\n\n useEffect(() => {\n loadDevicesWithoutPermission();\n }, [loadDevicesWithoutPermission]);\n\n useEffect(() => {\n const handleDeviceChange = () => {\n if (hasPermission) {\n loadDevicesWithPermission();\n } else {\n loadDevicesWithoutPermission();\n }\n };\n\n navigator.mediaDevices.addEventListener(\"devicechange\", handleDeviceChange);\n\n return () => {\n navigator.mediaDevices.removeEventListener(\"devicechange\", handleDeviceChange);\n };\n }, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission]);\n\n return {\n devices,\n error,\n hasPermission,\n loadDevices: loadDevicesWithPermission,\n loading,\n };\n};\n\nexport type MicSelectorProps = ComponentProps<typeof Popover> & {\n defaultValue?: string;\n value?: string | undefined;\n onValueChange?: (value: string | undefined) => void;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\nexport const MicSelector = ({\n defaultValue,\n value: controlledValue,\n onValueChange: controlledOnValueChange,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n ...props\n}: MicSelectorProps) => {\n const [value, onValueChange] = useControllableState<string | undefined>({\n defaultProp: defaultValue,\n onChange: controlledOnValueChange,\n prop: controlledValue,\n });\n const [open, onOpenChange] = useControllableState({\n defaultProp: defaultOpen,\n onChange: controlledOnOpenChange,\n prop: controlledOpen,\n });\n const [width, setWidth] = useState(200);\n const { devices, loading, hasPermission, loadDevices } = useAudioDevices();\n\n useEffect(() => {\n if (open && !hasPermission && !loading) {\n loadDevices();\n }\n }, [open, hasPermission, loading, loadDevices]);\n\n const contextValue = useMemo(\n () => ({\n data: devices,\n onOpenChange,\n onValueChange,\n open,\n setWidth,\n value,\n width,\n }),\n [devices, onOpenChange, onValueChange, open, setWidth, value, width],\n );\n\n return (\n <MicSelectorContext.Provider value={contextValue}>\n <Popover {...props} onOpenChange={onOpenChange} open={open} />\n </MicSelectorContext.Provider>\n );\n};\n\nexport type MicSelectorTriggerProps = ComponentProps<typeof Button>;\n\nexport const MicSelectorTrigger = ({ children, ...props }: MicSelectorTriggerProps) => {\n const { setWidth } = useContext(MicSelectorContext);\n const ref = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n // Create a ResizeObserver to detect width changes\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newWidth = (entry.target as HTMLElement).offsetWidth;\n if (newWidth) {\n setWidth?.(newWidth);\n }\n }\n });\n\n if (ref.current) {\n resizeObserver.observe(ref.current);\n }\n\n // Clean up the observer when component unmounts\n return () => {\n resizeObserver.disconnect();\n };\n }, [setWidth]);\n\n return (\n <PopoverTrigger asChild>\n <Button variant=\"outline\" {...props} ref={ref}>\n {children}\n <ChevronsUpDownIcon className=\"shrink-0 text-muted-foreground\" size={16} />\n </Button>\n </PopoverTrigger>\n );\n};\n\nexport type MicSelectorContentProps = ComponentProps<typeof Command> & {\n popoverOptions?: ComponentProps<typeof PopoverContent>;\n};\n\nexport const MicSelectorContent = ({\n className,\n popoverOptions,\n ...props\n}: MicSelectorContentProps) => {\n const { width, onValueChange, value } = useContext(MicSelectorContext);\n\n return (\n <PopoverContent className={cn(\"p-0\", className)} style={{ width }} {...popoverOptions}>\n <Command onValueChange={onValueChange} value={value} {...props} />\n </PopoverContent>\n );\n};\n\nexport type MicSelectorInputProps = ComponentProps<typeof CommandInput> & {\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n};\n\nexport const MicSelectorInput = ({ ...props }: MicSelectorInputProps) => {\n const { t } = useLocale();\n return <CommandInput placeholder={t(\"ai.micSelector.searchPlaceholder\")} {...props} />;\n};\n\nexport type MicSelectorListProps = Omit<ComponentProps<typeof CommandList>, \"children\"> & {\n children: (devices: MediaDeviceInfo[]) => ReactNode;\n};\n\nexport const MicSelectorList = ({ children, ...props }: MicSelectorListProps) => {\n const { data } = useContext(MicSelectorContext);\n\n return <CommandList {...props}>{children(data)}</CommandList>;\n};\n\nexport type MicSelectorEmptyProps = ComponentProps<typeof CommandEmpty>;\n\nexport const MicSelectorEmpty = ({\n children = \"No microphone found.\",\n ...props\n}: MicSelectorEmptyProps) => <CommandEmpty {...props}>{children}</CommandEmpty>;\n\nexport type MicSelectorItemProps = ComponentProps<typeof CommandItem>;\n\nexport const MicSelectorItem = (props: MicSelectorItemProps) => {\n const { onValueChange, onOpenChange } = useContext(MicSelectorContext);\n\n const handleSelect = useCallback(\n (currentValue: string) => {\n onValueChange?.(currentValue);\n onOpenChange?.(false);\n },\n [onValueChange, onOpenChange],\n );\n\n return <CommandItem onSelect={handleSelect} {...props} />;\n};\n\nexport type MicSelectorLabelProps = ComponentProps<\"span\"> & {\n device: MediaDeviceInfo;\n};\n\nexport const MicSelectorLabel = ({ device, className, ...props }: MicSelectorLabelProps) => {\n const matches = device.label.match(deviceIdRegex);\n\n if (!matches) {\n return (\n <span className={className} {...props}>\n {device.label}\n </span>\n );\n }\n\n const [, deviceId] = matches;\n const name = device.label.replace(deviceIdRegex, \"\");\n\n return (\n <span className={className} {...props}>\n <span>{name}</span>\n <span className=\"text-muted-foreground\"> ({deviceId})</span>\n </span>\n );\n};\n\nexport type MicSelectorValueProps = ComponentProps<\"span\">;\n\nexport const MicSelectorValue = ({ className, ...props }: MicSelectorValueProps) => {\n const { data, value } = useContext(MicSelectorContext);\n const currentDevice = data.find((d) => d.deviceId === value);\n\n if (!currentDevice) {\n return (\n <span className={cn(\"flex-1 text-start\", className)} {...props}>\n Select microphone...\n </span>\n );\n }\n\n return (\n <MicSelectorLabel\n className={cn(\"flex-1 text-start\", className)}\n device={currentDevice}\n {...props}\n />\n );\n};\n"],"mappings":";;;AAEA,SAAS,4BAA4B;AACrC,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AACnB,SAAS,iBAAiB;AAC1B,SAAS,0BAA0B;AAEnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAmKD,cAkCA,YAlCA;AAjKN,IAAM,gBAAgB;AAYtB,IAAM,qBAAqB,cAAsC;AAAA,EAC/D,MAAM,CAAC;AAAA,EACP,cAAc;AAAA,EACd,eAAe;AAAA,EACf,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AACT,CAAC;AAEM,IAAM,kBAAkB,MAAM;AACnC,QAAM,CAAC,SAAS,UAAU,IAAI,SAA4B,CAAC,CAAC;AAC5D,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AAExD,QAAM,+BAA+B,YAAY,YAAY;AAC3D,QAAI;AACF,iBAAW,IAAI;AACf,eAAS,IAAI;AAEb,YAAM,aAAa,MAAM,UAAU,aAAa,iBAAiB;AACjE,YAAM,cAAc,WAAW,OAAO,CAAC,WAAW,OAAO,SAAS,YAAY;AAE9E,iBAAW,WAAW;AAAA,IACxB,SAAS,aAAa;AACpB,YAAM,UACJ,uBAAuB,QAAQ,YAAY,UAAU;AAEvD,eAAS,OAAO;AAChB,cAAQ,MAAM,gCAAgC,OAAO;AAAA,IACvD,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,4BAA4B,YAAY,YAAY;AACxD,QAAI,SAAS;AACX;AAAA,IACF;AAEA,QAAI;AACF,iBAAW,IAAI;AACf,eAAS,IAAI;AAEb,YAAM,aAAa,MAAM,UAAU,aAAa,aAAa;AAAA,QAC3D,OAAO;AAAA,MACT,CAAC;AAED,iBAAW,SAAS,WAAW,UAAU,GAAG;AAC1C,cAAM,KAAK;AAAA,MACb;AAEA,YAAM,aAAa,MAAM,UAAU,aAAa,iBAAiB;AACjE,YAAM,cAAc,WAAW,OAAO,CAAC,WAAW,OAAO,SAAS,YAAY;AAE9E,iBAAW,WAAW;AACtB,uBAAiB,IAAI;AAAA,IACvB,SAAS,aAAa;AACpB,YAAM,UACJ,uBAAuB,QAAQ,YAAY,UAAU;AAEvD,eAAS,OAAO;AAChB,cAAQ,MAAM,gCAAgC,OAAO;AAAA,IACvD,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,YAAU,MAAM;AACd,iCAA6B;AAAA,EAC/B,GAAG,CAAC,4BAA4B,CAAC;AAEjC,YAAU,MAAM;AACd,UAAM,qBAAqB,MAAM;AAC/B,UAAI,eAAe;AACjB,kCAA0B;AAAA,MAC5B,OAAO;AACL,qCAA6B;AAAA,MAC/B;AAAA,IACF;AAEA,cAAU,aAAa,iBAAiB,gBAAgB,kBAAkB;AAE1E,WAAO,MAAM;AACX,gBAAU,aAAa,oBAAoB,gBAAgB,kBAAkB;AAAA,IAC/E;AAAA,EACF,GAAG,CAAC,eAAe,2BAA2B,4BAA4B,CAAC;AAE3E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,EACF;AACF;AAUO,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,cAAc;AAAA,EACd,MAAM;AAAA,EACN,cAAc;AAAA,EACd,GAAG;AACL,MAAwB;AACtB,QAAM,CAAC,OAAO,aAAa,IAAI,qBAAyC;AAAA,IACtE,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,MAAM,YAAY,IAAI,qBAAqB;AAAA,IAChD,aAAa;AAAA,IACb,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,GAAG;AACtC,QAAM,EAAE,SAAS,SAAS,eAAe,YAAY,IAAI,gBAAgB;AAEzE,YAAU,MAAM;AACd,QAAI,QAAQ,CAAC,iBAAiB,CAAC,SAAS;AACtC,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,eAAe,SAAS,WAAW,CAAC;AAE9C,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,SAAS,cAAc,eAAe,MAAM,UAAU,OAAO,KAAK;AAAA,EACrE;AAEA,SACE,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,cAClC,8BAAC,WAAS,GAAG,OAAO,cAA4B,MAAY,GAC9D;AAEJ;AAIO,IAAM,qBAAqB,CAAC,EAAE,UAAU,GAAG,MAAM,MAA+B;AACrF,QAAM,EAAE,SAAS,IAAI,WAAW,kBAAkB;AAClD,QAAM,MAAM,OAA0B,IAAI;AAE1C,YAAU,MAAM;AAEd,UAAM,iBAAiB,IAAI,eAAe,CAAC,YAAY;AACrD,iBAAW,SAAS,SAAS;AAC3B,cAAM,WAAY,MAAM,OAAuB;AAC/C,YAAI,UAAU;AACZ,qBAAW,QAAQ;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,IAAI,SAAS;AACf,qBAAe,QAAQ,IAAI,OAAO;AAAA,IACpC;AAGA,WAAO,MAAM;AACX,qBAAe,WAAW;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,SACE,oBAAC,kBAAe,SAAO,MACrB,+BAAC,UAAO,SAAQ,WAAW,GAAG,OAAO,KAClC;AAAA;AAAA,IACD,oBAAC,sBAAmB,WAAU,kCAAiC,MAAM,IAAI;AAAA,KAC3E,GACF;AAEJ;AAMO,IAAM,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+B;AAC7B,QAAM,EAAE,OAAO,eAAe,MAAM,IAAI,WAAW,kBAAkB;AAErE,SACE,oBAAC,kBAAe,WAAW,GAAG,OAAO,SAAS,GAAG,OAAO,EAAE,MAAM,GAAI,GAAG,gBACrE,8BAAC,WAAQ,eAA8B,OAAe,GAAG,OAAO,GAClE;AAEJ;AAQO,IAAM,mBAAmB,CAAC,EAAE,GAAG,MAAM,MAA6B;AACvE,QAAM,EAAE,EAAE,IAAI,UAAU;AACxB,SAAO,oBAAC,gBAAa,aAAa,EAAE,kCAAkC,GAAI,GAAG,OAAO;AACtF;AAMO,IAAM,kBAAkB,CAAC,EAAE,UAAU,GAAG,MAAM,MAA4B;AAC/E,QAAM,EAAE,KAAK,IAAI,WAAW,kBAAkB;AAE9C,SAAO,oBAAC,eAAa,GAAG,OAAQ,mBAAS,IAAI,GAAE;AACjD;AAIO,IAAM,mBAAmB,CAAC;AAAA,EAC/B,WAAW;AAAA,EACX,GAAG;AACL,MAA6B,oBAAC,gBAAc,GAAG,OAAQ,UAAS;AAIzD,IAAM,kBAAkB,CAAC,UAAgC;AAC9D,QAAM,EAAE,eAAe,aAAa,IAAI,WAAW,kBAAkB;AAErE,QAAM,eAAe;AAAA,IACnB,CAAC,iBAAyB;AACxB,sBAAgB,YAAY;AAC5B,qBAAe,KAAK;AAAA,IACtB;AAAA,IACA,CAAC,eAAe,YAAY;AAAA,EAC9B;AAEA,SAAO,oBAAC,eAAY,UAAU,cAAe,GAAG,OAAO;AACzD;AAMO,IAAM,mBAAmB,CAAC,EAAE,QAAQ,WAAW,GAAG,MAAM,MAA6B;AAC1F,QAAM,UAAU,OAAO,MAAM,MAAM,aAAa;AAEhD,MAAI,CAAC,SAAS;AACZ,WACE,oBAAC,UAAK,WAAuB,GAAG,OAC7B,iBAAO,OACV;AAAA,EAEJ;AAEA,QAAM,CAAC,EAAE,QAAQ,IAAI;AACrB,QAAM,OAAO,OAAO,MAAM,QAAQ,eAAe,EAAE;AAEnD,SACE,qBAAC,UAAK,WAAuB,GAAG,OAC9B;AAAA,wBAAC,UAAM,gBAAK;AAAA,IACZ,qBAAC,UAAK,WAAU,yBAAwB;AAAA;AAAA,MAAG;AAAA,MAAS;AAAA,OAAC;AAAA,KACvD;AAEJ;AAIO,IAAM,mBAAmB,CAAC,EAAE,WAAW,GAAG,MAAM,MAA6B;AAClF,QAAM,EAAE,MAAM,MAAM,IAAI,WAAW,kBAAkB;AACrD,QAAM,gBAAgB,KAAK,KAAK,CAAC,MAAM,EAAE,aAAa,KAAK;AAE3D,MAAI,CAAC,eAAe;AAClB,WACE,oBAAC,UAAK,WAAW,GAAG,qBAAqB,SAAS,GAAI,GAAG,OAAO,kCAEhE;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,qBAAqB,SAAS;AAAA,MAC5C,QAAQ;AAAA,MACP,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Shimmer
|
|
4
|
+
} from "./chunk-3YPT3V7L.js";
|
|
5
|
+
import {
|
|
6
|
+
getStreamdownPluginsKey,
|
|
7
|
+
useStreamdownMermaidOptions,
|
|
8
|
+
useStreamdownPlugins,
|
|
9
|
+
useStreamdownTranslations
|
|
10
|
+
} from "./chunk-PQBF6ZIQ.js";
|
|
11
|
+
|
|
12
|
+
// src/reasoning.tsx
|
|
13
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
14
|
+
import {
|
|
15
|
+
Collapsible,
|
|
16
|
+
CollapsibleContent,
|
|
17
|
+
CollapsibleTrigger,
|
|
18
|
+
useLocale
|
|
19
|
+
} from "@elabs-ai/components-ui";
|
|
20
|
+
import { cn } from "@elabs-ai/components-ui/lib/cn";
|
|
21
|
+
import { BrainIcon, ChevronDownIcon } from "lucide-react";
|
|
22
|
+
import {
|
|
23
|
+
createContext,
|
|
24
|
+
memo,
|
|
25
|
+
useCallback,
|
|
26
|
+
useContext,
|
|
27
|
+
useEffect,
|
|
28
|
+
useMemo,
|
|
29
|
+
useRef,
|
|
30
|
+
useState
|
|
31
|
+
} from "react";
|
|
32
|
+
import { Streamdown } from "streamdown";
|
|
33
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
34
|
+
var ReasoningContext = createContext(null);
|
|
35
|
+
var useReasoning = () => {
|
|
36
|
+
const context = useContext(ReasoningContext);
|
|
37
|
+
if (!context) {
|
|
38
|
+
throw new Error("Reasoning components must be used within Reasoning");
|
|
39
|
+
}
|
|
40
|
+
return context;
|
|
41
|
+
};
|
|
42
|
+
var AUTO_CLOSE_DELAY = 1e3;
|
|
43
|
+
var MS_IN_S = 1e3;
|
|
44
|
+
var Reasoning = memo(
|
|
45
|
+
({
|
|
46
|
+
className,
|
|
47
|
+
isStreaming = false,
|
|
48
|
+
open,
|
|
49
|
+
defaultOpen,
|
|
50
|
+
onOpenChange,
|
|
51
|
+
duration: durationProp,
|
|
52
|
+
children,
|
|
53
|
+
...props
|
|
54
|
+
}) => {
|
|
55
|
+
const resolvedDefaultOpen = defaultOpen ?? isStreaming;
|
|
56
|
+
const isExplicitlyClosed = defaultOpen === false;
|
|
57
|
+
const [isOpen, setIsOpen] = useControllableState({
|
|
58
|
+
defaultProp: resolvedDefaultOpen,
|
|
59
|
+
onChange: onOpenChange,
|
|
60
|
+
prop: open
|
|
61
|
+
});
|
|
62
|
+
const [duration, setDuration] = useControllableState({
|
|
63
|
+
defaultProp: void 0,
|
|
64
|
+
prop: durationProp
|
|
65
|
+
});
|
|
66
|
+
const hasEverStreamedRef = useRef(isStreaming);
|
|
67
|
+
const [hasAutoClosed, setHasAutoClosed] = useState(false);
|
|
68
|
+
const startTimeRef = useRef(null);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (isStreaming) {
|
|
71
|
+
hasEverStreamedRef.current = true;
|
|
72
|
+
if (startTimeRef.current === null) {
|
|
73
|
+
startTimeRef.current = Date.now();
|
|
74
|
+
}
|
|
75
|
+
} else if (startTimeRef.current !== null) {
|
|
76
|
+
setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));
|
|
77
|
+
startTimeRef.current = null;
|
|
78
|
+
}
|
|
79
|
+
}, [isStreaming, setDuration]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (isStreaming && !isOpen && !isExplicitlyClosed) {
|
|
82
|
+
setIsOpen(true);
|
|
83
|
+
}
|
|
84
|
+
}, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {
|
|
87
|
+
const timer = setTimeout(() => {
|
|
88
|
+
setIsOpen(false);
|
|
89
|
+
setHasAutoClosed(true);
|
|
90
|
+
}, AUTO_CLOSE_DELAY);
|
|
91
|
+
return () => clearTimeout(timer);
|
|
92
|
+
}
|
|
93
|
+
}, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);
|
|
94
|
+
const handleOpenChange = useCallback(
|
|
95
|
+
(newOpen) => {
|
|
96
|
+
setIsOpen(newOpen);
|
|
97
|
+
},
|
|
98
|
+
[setIsOpen]
|
|
99
|
+
);
|
|
100
|
+
const contextValue = useMemo(
|
|
101
|
+
() => ({ duration, isOpen, isStreaming, setIsOpen }),
|
|
102
|
+
[duration, isOpen, isStreaming, setIsOpen]
|
|
103
|
+
);
|
|
104
|
+
return /* @__PURE__ */ jsx(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
105
|
+
Collapsible,
|
|
106
|
+
{
|
|
107
|
+
className: cn("not-prose mb-4", className),
|
|
108
|
+
onOpenChange: handleOpenChange,
|
|
109
|
+
open: isOpen,
|
|
110
|
+
...props,
|
|
111
|
+
children
|
|
112
|
+
}
|
|
113
|
+
) });
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
var defaultGetThinkingMessage = (isStreaming, duration, t) => {
|
|
117
|
+
if (isStreaming || duration === 0) {
|
|
118
|
+
return /* @__PURE__ */ jsx(Shimmer, { duration: 1, children: t("ai.reasoning.thinking") });
|
|
119
|
+
}
|
|
120
|
+
if (duration === void 0) {
|
|
121
|
+
return /* @__PURE__ */ jsx("p", { children: t("ai.reasoning.thoughtDefault") });
|
|
122
|
+
}
|
|
123
|
+
return /* @__PURE__ */ jsx("p", { children: t("ai.reasoning.thoughtForDuration", { duration }) });
|
|
124
|
+
};
|
|
125
|
+
var ReasoningTrigger = memo(
|
|
126
|
+
({ className, children, getThinkingMessage, ...props }) => {
|
|
127
|
+
const { isStreaming, isOpen, duration } = useReasoning();
|
|
128
|
+
const { t } = useLocale();
|
|
129
|
+
return /* @__PURE__ */ jsx(
|
|
130
|
+
CollapsibleTrigger,
|
|
131
|
+
{
|
|
132
|
+
className: cn(
|
|
133
|
+
"flex w-full items-center gap-2 text-muted-foreground text-body transition-colors hover:text-foreground focus-ring",
|
|
134
|
+
className
|
|
135
|
+
),
|
|
136
|
+
...props,
|
|
137
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx(BrainIcon, { className: "size-4" }),
|
|
139
|
+
getThinkingMessage ? getThinkingMessage(isStreaming, duration) : defaultGetThinkingMessage(isStreaming, duration, t),
|
|
140
|
+
/* @__PURE__ */ jsx(
|
|
141
|
+
ChevronDownIcon,
|
|
142
|
+
{
|
|
143
|
+
className: cn("size-4 transition-transform", isOpen ? "rotate-180" : "rotate-0")
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
] })
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
var ReasoningContent = memo(({ className, children, ...props }) => {
|
|
152
|
+
const translations = useStreamdownTranslations();
|
|
153
|
+
const plugins = useStreamdownPlugins(typeof children === "string" ? children : "");
|
|
154
|
+
const mermaidOptions = useStreamdownMermaidOptions();
|
|
155
|
+
return /* @__PURE__ */ jsx(
|
|
156
|
+
CollapsibleContent,
|
|
157
|
+
{
|
|
158
|
+
className: cn(
|
|
159
|
+
"mt-4 text-body",
|
|
160
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]",
|
|
161
|
+
className
|
|
162
|
+
),
|
|
163
|
+
...props,
|
|
164
|
+
children: typeof children === "string" ? /* @__PURE__ */ jsx(
|
|
165
|
+
Streamdown,
|
|
166
|
+
{
|
|
167
|
+
plugins,
|
|
168
|
+
translations,
|
|
169
|
+
mermaid: mermaidOptions,
|
|
170
|
+
children
|
|
171
|
+
},
|
|
172
|
+
getStreamdownPluginsKey(plugins)
|
|
173
|
+
) : children
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
Reasoning.displayName = "Reasoning";
|
|
178
|
+
ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
179
|
+
ReasoningContent.displayName = "ReasoningContent";
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
useReasoning,
|
|
183
|
+
Reasoning,
|
|
184
|
+
ReasoningTrigger,
|
|
185
|
+
ReasoningContent
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=chunk-X47QMM6K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/reasoning.tsx"],"sourcesContent":["\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n useLocale,\n} from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport {\n getStreamdownPluginsKey,\n useStreamdownMermaidOptions,\n useStreamdownPlugins,\n useStreamdownTranslations,\n} from \"./_streamdown-i18n\";\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Shimmer } from \"./shimmer\";\n\ninterface ReasoningContextValue {\n isStreaming: boolean;\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n duration: number | undefined;\n}\n\nconst ReasoningContext = createContext<ReasoningContextValue | null>(null);\n\nexport const useReasoning = () => {\n const context = useContext(ReasoningContext);\n if (!context) {\n throw new Error(\"Reasoning components must be used within Reasoning\");\n }\n return context;\n};\n\nexport type ReasoningProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n duration?: number;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nexport const Reasoning = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n onOpenChange,\n duration: durationProp,\n children,\n ...props\n }: ReasoningProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: undefined,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ReasoningContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose mb-4\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ReasoningContext.Provider>\n );\n },\n);\n\nexport type ReasoningTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nconst defaultGetThinkingMessage = (\n isStreaming: boolean,\n duration: number | undefined,\n t: (key: string, vars?: Record<string, string | number>) => string,\n) => {\n if (isStreaming || duration === 0) {\n return <Shimmer duration={1}>{t(\"ai.reasoning.thinking\")}</Shimmer>;\n }\n if (duration === undefined) {\n return <p>{t(\"ai.reasoning.thoughtDefault\")}</p>;\n }\n return <p>{t(\"ai.reasoning.thoughtForDuration\", { duration })}</p>;\n};\n\nexport const ReasoningTrigger = memo(\n ({ className, children, getThinkingMessage, ...props }: ReasoningTriggerProps) => {\n const { isStreaming, isOpen, duration } = useReasoning();\n const { t } = useLocale();\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-2 text-muted-foreground text-body transition-colors hover:text-foreground focus-ring\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n <BrainIcon className=\"size-4\" />\n {getThinkingMessage\n ? getThinkingMessage(isStreaming, duration)\n : defaultGetThinkingMessage(isStreaming, duration, t)}\n <ChevronDownIcon\n className={cn(\"size-4 transition-transform\", isOpen ? \"rotate-180\" : \"rotate-0\")}\n />\n </>\n )}\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ReasoningContentProps = Omit<ComponentProps<typeof CollapsibleContent>, \"children\"> & {\n /**\n * The reasoning body.\n *\n * A **string** is rendered as streamed markdown (Streamdown) — the default for\n * model reasoning text. Any other node renders **as-is**, so a structured live\n * ledger (a timeline, per-step status) can live inside the disclosure without\n * being handed to a markdown parser. Mirrors the `getThinkingMessage` /\n * `children` override seam on `ReasoningTrigger`.\n *\n * Note an **array** of strings is not a `string` — `{[\"a\", \"b\"]}` renders raw.\n * Pass one string if you want it parsed as markdown.\n */\n children: ReactNode;\n};\n\nexport const ReasoningContent = memo(({ className, children, ...props }: ReasoningContentProps) => {\n // Streamdown's own chrome (code copy, table menus) reads the locale seam (#310).\n const translations = useStreamdownTranslations();\n // Brand-token-derived `code` plugin, not the package's static github-*\n // default (#315 follow-up) — re-derives when the active theme changes.\n // `math`/`cjk` are lazy-loaded off the raw text (#perf-5, see\n // `_streamdown-i18n.ts`) — pass `children` so they load only when this\n // reasoning block actually needs them.\n const plugins = useStreamdownPlugins(typeof children === \"string\" ? children : \"\");\n // The TOP-LEVEL Streamdown `mermaid` prop — catches a failed diagram\n // render, including a missing `mermaid` optional peer (issue #33).\n const mermaidOptions = useStreamdownMermaidOptions();\n\n return (\n <CollapsibleContent\n className={cn(\n \"mt-4 text-body\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]\",\n className,\n )}\n {...props}\n >\n {typeof children === \"string\" ? (\n <Streamdown\n // Forces a remount the first time the lazy math/cjk slot resolves —\n // see `getStreamdownPluginsKey`'s doc in `_streamdown-i18n.ts` for why.\n key={getStreamdownPluginsKey(plugins)}\n plugins={plugins}\n translations={translations}\n mermaid={mermaidOptions}\n >\n {children}\n </Streamdown>\n ) : (\n children\n )}\n </CollapsibleContent>\n );\n});\n\nReasoning.displayName = \"Reasoning\";\nReasoningTrigger.displayName = \"ReasoningTrigger\";\nReasoningContent.displayName = \"ReasoningContent\";\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
A2UI_CATALOG_SCHEMA
|
|
4
|
+
} from "./chunk-AXMNJMMH.js";
|
|
5
|
+
|
|
6
|
+
// src/a2ui/ui-catalog.tsx
|
|
7
|
+
import {
|
|
8
|
+
Accordion,
|
|
9
|
+
AccordionContent,
|
|
10
|
+
AccordionItem,
|
|
11
|
+
AccordionTrigger,
|
|
12
|
+
Alert,
|
|
13
|
+
AlertDescription,
|
|
14
|
+
AlertTitle,
|
|
15
|
+
Avatar,
|
|
16
|
+
AvatarFallback,
|
|
17
|
+
Badge,
|
|
18
|
+
BentoGrid,
|
|
19
|
+
BentoGridItem,
|
|
20
|
+
Button,
|
|
21
|
+
ButtonGroup,
|
|
22
|
+
Card,
|
|
23
|
+
CardAction,
|
|
24
|
+
CardContent,
|
|
25
|
+
CardDescription,
|
|
26
|
+
CardFooter,
|
|
27
|
+
CardHeader,
|
|
28
|
+
CardTitle,
|
|
29
|
+
Checkbox,
|
|
30
|
+
Collapsible,
|
|
31
|
+
CollapsibleContent,
|
|
32
|
+
CollapsibleTrigger,
|
|
33
|
+
Descriptions,
|
|
34
|
+
DescriptionsItem,
|
|
35
|
+
EmptyState,
|
|
36
|
+
Heading,
|
|
37
|
+
Input,
|
|
38
|
+
Kbd,
|
|
39
|
+
Label,
|
|
40
|
+
MetricCard,
|
|
41
|
+
Progress,
|
|
42
|
+
RadioGroup,
|
|
43
|
+
RadioGroupItem,
|
|
44
|
+
SectionHeader,
|
|
45
|
+
Select,
|
|
46
|
+
SelectContent,
|
|
47
|
+
SelectItem,
|
|
48
|
+
SelectTrigger,
|
|
49
|
+
SelectValue,
|
|
50
|
+
Separator,
|
|
51
|
+
Slider,
|
|
52
|
+
StatePanel,
|
|
53
|
+
StatusBadge,
|
|
54
|
+
Switch,
|
|
55
|
+
Table,
|
|
56
|
+
TableBody,
|
|
57
|
+
TableCaption,
|
|
58
|
+
TableCell,
|
|
59
|
+
TableFooter,
|
|
60
|
+
TableHead,
|
|
61
|
+
TableHeader,
|
|
62
|
+
TableRow,
|
|
63
|
+
Tabs,
|
|
64
|
+
TabsContent,
|
|
65
|
+
TabsList,
|
|
66
|
+
TabsTrigger,
|
|
67
|
+
Text,
|
|
68
|
+
Textarea,
|
|
69
|
+
Timeline
|
|
70
|
+
} from "@elabs-ai/components-ui";
|
|
71
|
+
import { jsx } from "react/jsx-runtime";
|
|
72
|
+
var SurfaceAlertTitle = (props) => /* @__PURE__ */ jsx(AlertTitle, { ...props, as: "div" });
|
|
73
|
+
var UI_CATALOG_BINDINGS = {
|
|
74
|
+
Accordion,
|
|
75
|
+
AccordionContent,
|
|
76
|
+
AccordionItem,
|
|
77
|
+
AccordionTrigger,
|
|
78
|
+
Alert,
|
|
79
|
+
AlertDescription,
|
|
80
|
+
AlertTitle: SurfaceAlertTitle,
|
|
81
|
+
Avatar,
|
|
82
|
+
AvatarFallback,
|
|
83
|
+
Badge,
|
|
84
|
+
BentoGrid,
|
|
85
|
+
BentoGridItem,
|
|
86
|
+
Button,
|
|
87
|
+
ButtonGroup,
|
|
88
|
+
Card,
|
|
89
|
+
CardAction,
|
|
90
|
+
CardContent,
|
|
91
|
+
CardDescription,
|
|
92
|
+
CardFooter,
|
|
93
|
+
CardHeader,
|
|
94
|
+
CardTitle,
|
|
95
|
+
Checkbox,
|
|
96
|
+
Collapsible,
|
|
97
|
+
CollapsibleContent,
|
|
98
|
+
CollapsibleTrigger,
|
|
99
|
+
Descriptions,
|
|
100
|
+
DescriptionsItem,
|
|
101
|
+
EmptyState,
|
|
102
|
+
Heading,
|
|
103
|
+
Input,
|
|
104
|
+
Kbd,
|
|
105
|
+
Label,
|
|
106
|
+
MetricCard,
|
|
107
|
+
Progress,
|
|
108
|
+
RadioGroup,
|
|
109
|
+
RadioGroupItem,
|
|
110
|
+
SectionHeader,
|
|
111
|
+
Select,
|
|
112
|
+
SelectContent,
|
|
113
|
+
SelectItem,
|
|
114
|
+
SelectTrigger,
|
|
115
|
+
SelectValue,
|
|
116
|
+
Separator,
|
|
117
|
+
Slider,
|
|
118
|
+
StatePanel,
|
|
119
|
+
StatusBadge,
|
|
120
|
+
Switch,
|
|
121
|
+
Table,
|
|
122
|
+
TableBody,
|
|
123
|
+
TableCaption,
|
|
124
|
+
TableCell,
|
|
125
|
+
TableFooter,
|
|
126
|
+
TableHead,
|
|
127
|
+
TableHeader,
|
|
128
|
+
TableRow,
|
|
129
|
+
Tabs,
|
|
130
|
+
TabsContent,
|
|
131
|
+
TabsList,
|
|
132
|
+
TabsTrigger,
|
|
133
|
+
Text,
|
|
134
|
+
Textarea,
|
|
135
|
+
Timeline
|
|
136
|
+
};
|
|
137
|
+
function createA2uiCatalog(bindings, schema = A2UI_CATALOG_SCHEMA) {
|
|
138
|
+
const catalog = {};
|
|
139
|
+
for (const [type, typeSchema] of Object.entries(schema)) {
|
|
140
|
+
if (typeSchema.builtin) {
|
|
141
|
+
catalog[type] = { schema: typeSchema };
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const component = bindings[type];
|
|
145
|
+
if (!component) {
|
|
146
|
+
throw new Error(`createA2uiCatalog: catalog type "${type}" has no component binding`);
|
|
147
|
+
}
|
|
148
|
+
catalog[type] = { schema: typeSchema, component };
|
|
149
|
+
}
|
|
150
|
+
return catalog;
|
|
151
|
+
}
|
|
152
|
+
function defineA2uiType(partial) {
|
|
153
|
+
return {
|
|
154
|
+
children: partial.children ?? false,
|
|
155
|
+
props: partial.props ?? {},
|
|
156
|
+
events: partial.events ?? {},
|
|
157
|
+
source: partial.source ?? "app",
|
|
158
|
+
...partial.summary ? { summary: partial.summary } : {},
|
|
159
|
+
...partial.builtin ? { builtin: true } : {}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function catalogSchema(catalog) {
|
|
163
|
+
return Object.fromEntries(Object.entries(catalog).map(([t, e]) => [t, e.schema]));
|
|
164
|
+
}
|
|
165
|
+
var uiCatalog = createA2uiCatalog(UI_CATALOG_BINDINGS);
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
UI_CATALOG_BINDINGS,
|
|
169
|
+
createA2uiCatalog,
|
|
170
|
+
defineA2uiType,
|
|
171
|
+
catalogSchema,
|
|
172
|
+
uiCatalog
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=chunk-XNBKO32Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/a2ui/ui-catalog.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * ui-catalog.tsx — the shipped A2UI catalog: every non-builtin type in\n * `catalog.source.json` bound to its `@elabs-ai/components-ui` component. The\n * schema half (`A2UI_CATALOG_SCHEMA`, generated) says what an agent MAY emit; this\n * half says what it renders AS. A test asserts the two key sets are identical, so\n * a type cannot be validatable-but-unrenderable or the reverse.\n *\n * Apps extend it (`createA2uiCatalog`) with their own types — a chart from\n * `@elabs-ai/components-charts`, a domain card — because `ai` may not import its\n * sibling packages (one-way dependency graph) and an app composes freely.\n */\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Alert,\n AlertDescription,\n AlertTitle,\n Avatar,\n AvatarFallback,\n Badge,\n BentoGrid,\n BentoGridItem,\n Button,\n ButtonGroup,\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n Checkbox,\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n Descriptions,\n DescriptionsItem,\n EmptyState,\n Heading,\n Input,\n Kbd,\n Label,\n MetricCard,\n Progress,\n RadioGroup,\n RadioGroupItem,\n SectionHeader,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Separator,\n Slider,\n StatePanel,\n StatusBadge,\n Switch,\n Table,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Text,\n Textarea,\n Timeline,\n} from \"@elabs-ai/components-ui\";\nimport type { AlertTitleProps } from \"@elabs-ai/components-ui\";\nimport type { ComponentType } from \"react\";\n\nimport { A2UI_CATALOG_SCHEMA } from \"./core/catalog.generated\";\nimport type { A2uiCatalogSchema, A2uiCatalogTypeSchema } from \"./core/spec\";\n\n/** One renderable catalog type: its schema plus the component that draws it. */\nexport interface A2uiCatalogEntry {\n schema: A2uiCatalogTypeSchema;\n /** Absent for builtins (`Stack`, `Grid`), which the surface draws itself. */\n component?: ComponentType<Record<string, unknown>>;\n}\n\nexport type A2uiCatalog = Record<string, A2uiCatalogEntry>;\n\n// `ComponentType<Record<string, unknown>>` is the erased shape the renderer calls\n// with validated, catalog-shaped props; each binding is a real ui component.\ntype AnyComponent = ComponentType<any>; // eslint-disable-line @typescript-eslint/no-explicit-any -- erased at the catalog boundary; props are validated against the schema\n\n/**\n * `AlertTitle` inside a surface, as a `<div>` rather than its default `<h5>`.\n *\n * A surface is rendered into a host page whose heading outline the agent cannot see, so a\n * fixed `h5` fails axe's `heading-order` under any host with no `h4` above it — which is\n * most of them. The alert's `role=\"alert\"` announces the title either way, so the heading\n * adds nothing here; `CardTitle` defaults to `div` for the same reason. A host writing real\n * code composes `<AlertTitle as=\"h3\">`, where the level is knowable.\n */\nconst SurfaceAlertTitle = (props: AlertTitleProps) => <AlertTitle {...props} as=\"div\" />;\n\n/** The `@elabs-ai/components-ui` bindings, one per non-builtin catalog type. */\nexport const UI_CATALOG_BINDINGS: Record<string, AnyComponent> = {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Alert,\n AlertDescription,\n AlertTitle: SurfaceAlertTitle,\n Avatar,\n AvatarFallback,\n Badge,\n BentoGrid,\n BentoGridItem,\n Button,\n ButtonGroup,\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n Checkbox,\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n Descriptions,\n DescriptionsItem,\n EmptyState,\n Heading,\n Input,\n Kbd,\n Label,\n MetricCard,\n Progress,\n RadioGroup,\n RadioGroupItem,\n SectionHeader,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Separator,\n Slider,\n StatePanel,\n StatusBadge,\n Switch,\n Table,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Text,\n Textarea,\n Timeline,\n};\n\n/**\n * Build a catalog from component bindings + a schema. Every schema type that is\n * not a builtin must have a binding; a binding without a schema is ignored (it\n * would be unvalidatable). Extend the shipped one:\n *\n * ```ts\n * const catalog = createA2uiCatalog(\n * { ...UI_CATALOG_BINDINGS, RevenueChart },\n * { ...A2UI_CATALOG_SCHEMA, RevenueChart: defineA2uiType({ props: { series: { type: \"array\", required: true } } }) },\n * );\n * ```\n */\nexport function createA2uiCatalog(\n bindings: Record<string, AnyComponent>,\n schema: A2uiCatalogSchema = A2UI_CATALOG_SCHEMA,\n): A2uiCatalog {\n const catalog: A2uiCatalog = {};\n for (const [type, typeSchema] of Object.entries(schema)) {\n if (typeSchema.builtin) {\n catalog[type] = { schema: typeSchema };\n continue;\n }\n const component = bindings[type];\n if (!component) {\n throw new Error(`createA2uiCatalog: catalog type \"${type}\" has no component binding`);\n }\n catalog[type] = { schema: typeSchema, component };\n }\n return catalog;\n}\n\n/** Author a schema entry for an app-provided type with sensible defaults. */\nexport function defineA2uiType(\n partial: Partial<A2uiCatalogTypeSchema> & { source?: string },\n): A2uiCatalogTypeSchema {\n return {\n children: partial.children ?? false,\n props: partial.props ?? {},\n events: partial.events ?? {},\n source: partial.source ?? \"app\",\n ...(partial.summary ? { summary: partial.summary } : {}),\n ...(partial.builtin ? { builtin: true } : {}),\n };\n}\n\n/** The schema half of a catalog (what `validateA2uiSurface` takes). */\nexport function catalogSchema(catalog: A2uiCatalog): A2uiCatalogSchema {\n return Object.fromEntries(Object.entries(catalog).map(([t, e]) => [t, e.schema]));\n}\n\n/** The shipped catalog: builtins + every `@elabs-ai/components-ui` type above. */\nexport const uiCatalog: A2uiCatalog = createA2uiCatalog(UI_CATALOG_BINDINGS);\n"],"mappings":"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","names":[]}
|