@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
package/src/stack-trace.tsx
CHANGED
|
@@ -3,20 +3,11 @@
|
|
|
3
3
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
4
4
|
import { Button } from "@elabs-ai/components-ui";
|
|
5
5
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@elabs-ai/components-ui";
|
|
6
|
-
import { useLocale } from "@elabs-ai/components-ui";
|
|
6
|
+
import { useCopyToClipboard, useLocale } from "@elabs-ai/components-ui";
|
|
7
7
|
import { cn } from "@elabs-ai/components-ui/lib/cn";
|
|
8
8
|
import { AlertTriangleIcon, CheckIcon, ChevronDownIcon, CopyIcon } from "lucide-react";
|
|
9
9
|
import type { ComponentProps } from "react";
|
|
10
|
-
import {
|
|
11
|
-
createContext,
|
|
12
|
-
memo,
|
|
13
|
-
useCallback,
|
|
14
|
-
useContext,
|
|
15
|
-
useEffect,
|
|
16
|
-
useMemo,
|
|
17
|
-
useRef,
|
|
18
|
-
useState,
|
|
19
|
-
} from "react";
|
|
10
|
+
import { createContext, memo, useCallback, useContext, useMemo } from "react";
|
|
20
11
|
|
|
21
12
|
// Regex patterns for parsing stack traces
|
|
22
13
|
const STACK_FRAME_WITH_PARENS_REGEX = /^at\s+(.+?)\s+\((.+):(\d+):(\d+)\)$/;
|
|
@@ -188,7 +179,7 @@ export const StackTrace = memo(
|
|
|
188
179
|
<StackTraceContext.Provider value={contextValue}>
|
|
189
180
|
<div
|
|
190
181
|
className={cn(
|
|
191
|
-
"not-prose w-full overflow-hidden rounded-lg border bg-background font-mono text-
|
|
182
|
+
"not-prose w-full overflow-hidden rounded-lg border bg-background font-mono text-body",
|
|
192
183
|
className,
|
|
193
184
|
)}
|
|
194
185
|
{...props}
|
|
@@ -293,42 +284,35 @@ export const StackTraceCopyButton = memo(
|
|
|
293
284
|
({
|
|
294
285
|
onCopy,
|
|
295
286
|
onError,
|
|
296
|
-
timeout
|
|
287
|
+
timeout,
|
|
297
288
|
className,
|
|
298
289
|
children,
|
|
290
|
+
"aria-label": ariaLabel,
|
|
299
291
|
...props
|
|
300
292
|
}: StackTraceCopyButtonProps) => {
|
|
301
|
-
const
|
|
302
|
-
const timeoutRef = useRef<number>(0);
|
|
293
|
+
const { t } = useLocale();
|
|
303
294
|
const { raw } = useStackTrace();
|
|
295
|
+
// Shared implementation (`@elabs-ai/components-ui`) instead of a private
|
|
296
|
+
// copy of the same copy-to-clipboard state machine (issue-workflow.md
|
|
297
|
+
// dedupe finding) — see `CodeBlockCopyButton` for the reference usage.
|
|
298
|
+
const { copied: isCopied, copy } = useCopyToClipboard(
|
|
299
|
+
timeout === undefined ? undefined : { resetAfterMs: timeout },
|
|
300
|
+
);
|
|
304
301
|
|
|
305
302
|
const copyToClipboard = useCallback(async () => {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
try {
|
|
312
|
-
await navigator.clipboard.writeText(raw);
|
|
313
|
-
setIsCopied(true);
|
|
303
|
+
const ok = await copy(raw);
|
|
304
|
+
if (ok) {
|
|
314
305
|
onCopy?.();
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
onError?.(error as Error);
|
|
306
|
+
} else {
|
|
307
|
+
onError?.(new Error("Clipboard API not available"));
|
|
318
308
|
}
|
|
319
|
-
}, [raw, onCopy, onError
|
|
320
|
-
|
|
321
|
-
useEffect(
|
|
322
|
-
() => () => {
|
|
323
|
-
window.clearTimeout(timeoutRef.current);
|
|
324
|
-
},
|
|
325
|
-
[],
|
|
326
|
-
);
|
|
309
|
+
}, [copy, raw, onCopy, onError]);
|
|
327
310
|
|
|
328
311
|
const Icon = isCopied ? CheckIcon : CopyIcon;
|
|
329
312
|
|
|
330
313
|
return (
|
|
331
314
|
<Button
|
|
315
|
+
aria-label={ariaLabel ?? t("copy")}
|
|
332
316
|
className={cn("size-7", className)}
|
|
333
317
|
onClick={copyToClipboard}
|
|
334
318
|
size="icon"
|
|
@@ -440,7 +424,7 @@ export const StackTraceFrames = memo(
|
|
|
440
424
|
{framesToShow.map((frame) => (
|
|
441
425
|
<div
|
|
442
426
|
className={cn(
|
|
443
|
-
"text-
|
|
427
|
+
"text-meta",
|
|
444
428
|
frame.isInternal ? "text-muted-foreground/50" : "text-foreground/90",
|
|
445
429
|
)}
|
|
446
430
|
key={frame.raw}
|
|
@@ -464,7 +448,7 @@ export const StackTraceFrames = memo(
|
|
|
464
448
|
</div>
|
|
465
449
|
))}
|
|
466
450
|
{framesToShow.length === 0 && (
|
|
467
|
-
<div className="text-muted-foreground text-
|
|
451
|
+
<div className="text-muted-foreground text-meta">{t("ai.stackTrace.empty")}</div>
|
|
468
452
|
)}
|
|
469
453
|
</div>
|
|
470
454
|
);
|
|
@@ -13,6 +13,7 @@ import { LocaleProvider } from "@elabs-ai/components-ui";
|
|
|
13
13
|
import { MessageResponse } from "./message";
|
|
14
14
|
import { MarkdownView } from "./markdown-view";
|
|
15
15
|
import { Reasoning, ReasoningContent } from "./reasoning";
|
|
16
|
+
import { _debugActiveThemeScopeCount } from "./_theme-scope-store";
|
|
16
17
|
|
|
17
18
|
const CODE_MARKDOWN = "```js\nconst a = 1;\n```";
|
|
18
19
|
// `MarkdownView` re-maps `code` onto `ProseInlineCode`, so its Streamdown chrome
|
|
@@ -107,6 +108,28 @@ describe("Streamdown chrome microcopy (#310)", () => {
|
|
|
107
108
|
});
|
|
108
109
|
});
|
|
109
110
|
|
|
111
|
+
describe("useReactiveCodePlugin shares ONE theme-scope observer (perf review §3.3)", () => {
|
|
112
|
+
it("registers a single tracked scope for many simultaneously-mounted MessageResponse instances", () => {
|
|
113
|
+
const before = _debugActiveThemeScopeCount();
|
|
114
|
+
|
|
115
|
+
const { unmount } = render(
|
|
116
|
+
<>
|
|
117
|
+
<MessageResponse>{CODE_MARKDOWN}</MessageResponse>
|
|
118
|
+
<MessageResponse>{CODE_MARKDOWN}</MessageResponse>
|
|
119
|
+
<MessageResponse>{CODE_MARKDOWN}</MessageResponse>
|
|
120
|
+
</>,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// Under the old per-hook `MutationObserver`, a message-dense conversation
|
|
124
|
+
// registered one observer PER instance; the shared store collapses every
|
|
125
|
+
// instance watching the same `<html>` scope into exactly one.
|
|
126
|
+
expect(_debugActiveThemeScopeCount()).toBe(before + 1);
|
|
127
|
+
|
|
128
|
+
unmount();
|
|
129
|
+
expect(_debugActiveThemeScopeCount()).toBe(before);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
110
133
|
/**
|
|
111
134
|
* #315 follow-up — the "major" carve-out: only `<CodeBlock>` had been
|
|
112
135
|
* de-GitHub-ed; every fenced code block rendered through `MessageResponse`/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AI assistant template — the canonical full-screen AI assistant composition
|
|
3
|
-
*
|
|
2
|
+
* AI assistant template — the canonical full-screen AI assistant composition:
|
|
3
|
+
* app-shell nav, an immersive `ChatShell` (transcript scrolls behind a floating
|
|
4
|
+
* `Composer`, one centred reading column) and the `ContextPanel` right rail. This story is the
|
|
4
5
|
* single source of truth: `pnpm gen:templates` derives the consumer template
|
|
5
6
|
* source (`docs/playbooks/templates/ai-assistant.tsx`) from it.
|
|
6
7
|
* Verify across both themes with globals=theme:<slug>.
|
|
@@ -10,8 +11,10 @@ import { useState } from "react";
|
|
|
10
11
|
import { AppIcon } from "@elabs-ai/components-icons";
|
|
11
12
|
import {
|
|
12
13
|
Button,
|
|
14
|
+
NavUser,
|
|
13
15
|
Sidebar,
|
|
14
16
|
SidebarContent,
|
|
17
|
+
SidebarFooter,
|
|
15
18
|
SidebarGroup,
|
|
16
19
|
SidebarGroupContent,
|
|
17
20
|
SidebarHeader,
|
|
@@ -23,7 +26,16 @@ import {
|
|
|
23
26
|
SidebarTrigger,
|
|
24
27
|
} from "@elabs-ai/components-ui";
|
|
25
28
|
import {
|
|
29
|
+
AssetPreview,
|
|
30
|
+
ChatShell,
|
|
26
31
|
Composer,
|
|
32
|
+
ContextPanel,
|
|
33
|
+
ContextPanelBody,
|
|
34
|
+
ContextPanelDetail,
|
|
35
|
+
ContextPanelHeader,
|
|
36
|
+
ContextPanelProvider,
|
|
37
|
+
ContextPanelSection,
|
|
38
|
+
ContextPanelTrigger,
|
|
27
39
|
Conversation,
|
|
28
40
|
ConversationContent,
|
|
29
41
|
ConversationEmptyState,
|
|
@@ -31,6 +43,9 @@ import {
|
|
|
31
43
|
Message,
|
|
32
44
|
MessageContent,
|
|
33
45
|
MessageResponse,
|
|
46
|
+
ProducedAssetTree,
|
|
47
|
+
useContextPanel,
|
|
48
|
+
type ContextAsset,
|
|
34
49
|
} from "./index";
|
|
35
50
|
import { Bot, History, Home, MessageSquare, Settings } from "lucide-react";
|
|
36
51
|
|
|
@@ -47,10 +62,36 @@ const nav = [
|
|
|
47
62
|
{ id: "settings", label: "Settings", icon: Settings },
|
|
48
63
|
];
|
|
49
64
|
|
|
65
|
+
/** Right rail root — what the assistant produced; selecting one drills in. */
|
|
66
|
+
function ContextRailRoot({ assets }: { assets: ContextAsset[] }) {
|
|
67
|
+
const { state, actions } = useContextPanel();
|
|
68
|
+
return (
|
|
69
|
+
<ContextPanelSection label="Produced assets">
|
|
70
|
+
<ProducedAssetTree
|
|
71
|
+
assets={assets}
|
|
72
|
+
selectedId={state.selectedAsset?.id}
|
|
73
|
+
onSelect={actions.openDetail}
|
|
74
|
+
/>
|
|
75
|
+
</ContextPanelSection>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Right rail detail — the focused asset, with Back in the panel header. */
|
|
80
|
+
function ContextRailDetail() {
|
|
81
|
+
const { state } = useContextPanel();
|
|
82
|
+
return (
|
|
83
|
+
<ContextPanelDetail>
|
|
84
|
+
{state.selectedAsset ? <AssetPreview asset={state.selectedAsset} /> : null}
|
|
85
|
+
</ContextPanelDetail>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
50
89
|
function AiAssistantTemplate() {
|
|
51
90
|
const [active, setActive] = useState("chat");
|
|
52
91
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
|
53
92
|
const [status, setStatus] = useState<"ready" | "submitted">("ready");
|
|
93
|
+
// Files the assistant produced — wire to your runtime's tool outputs.
|
|
94
|
+
const [assets] = useState<ContextAsset[]>([]);
|
|
54
95
|
|
|
55
96
|
function send(text: string) {
|
|
56
97
|
setMessages((m) => [...m, { id: crypto.randomUUID(), role: "user", text }]);
|
|
@@ -61,98 +102,121 @@ function AiAssistantTemplate() {
|
|
|
61
102
|
}
|
|
62
103
|
|
|
63
104
|
return (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</SidebarMenuButton>
|
|
88
|
-
</SidebarMenuItem>
|
|
89
|
-
))}
|
|
90
|
-
</SidebarMenu>
|
|
91
|
-
</SidebarGroupContent>
|
|
92
|
-
</SidebarGroup>
|
|
93
|
-
</SidebarContent>
|
|
94
|
-
</Sidebar>
|
|
95
|
-
<SidebarInset className="flex flex-col overflow-hidden">
|
|
96
|
-
<header className="flex h-14 shrink-0 items-center gap-2 border-b px-4">
|
|
97
|
-
<SidebarTrigger />
|
|
98
|
-
<h1 className="text-body font-medium">AI Assistant</h1>
|
|
99
|
-
</header>
|
|
100
|
-
<div className="flex flex-1 flex-col overflow-hidden">
|
|
101
|
-
<Conversation className="flex-1">
|
|
102
|
-
<ConversationContent>
|
|
103
|
-
{messages.length === 0 ? (
|
|
104
|
-
<ConversationEmptyState
|
|
105
|
-
icon={<MessageSquare className="size-8" aria-hidden="true" />}
|
|
106
|
-
title="Start the conversation"
|
|
107
|
-
description="Ask anything to begin."
|
|
108
|
-
actions={
|
|
109
|
-
<>
|
|
110
|
-
<Button
|
|
111
|
-
onClick={() => send("What can you help me with?")}
|
|
112
|
-
size="sm"
|
|
113
|
-
variant="outline"
|
|
105
|
+
// The provider wraps the whole shell so the header trigger and the right
|
|
106
|
+
// rail share one open/closed state.
|
|
107
|
+
<ContextPanelProvider>
|
|
108
|
+
<SidebarProvider className="h-svh min-h-0">
|
|
109
|
+
<Sidebar collapsible="icon">
|
|
110
|
+
<SidebarHeader className="px-3 py-2">
|
|
111
|
+
<div className="flex items-center gap-2">
|
|
112
|
+
<AppIcon height={20} aria-hidden />
|
|
113
|
+
<span className="truncate font-semibold group-data-[collapsible=icon]:hidden">
|
|
114
|
+
Assistant
|
|
115
|
+
</span>
|
|
116
|
+
</div>
|
|
117
|
+
</SidebarHeader>
|
|
118
|
+
<SidebarContent>
|
|
119
|
+
<SidebarGroup>
|
|
120
|
+
<SidebarGroupContent>
|
|
121
|
+
<SidebarMenu>
|
|
122
|
+
{nav.map((n) => (
|
|
123
|
+
<SidebarMenuItem key={n.id}>
|
|
124
|
+
<SidebarMenuButton
|
|
125
|
+
isActive={active === n.id}
|
|
126
|
+
tooltip={n.label}
|
|
127
|
+
onClick={() => setActive(n.id)}
|
|
114
128
|
>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
<n.icon aria-hidden="true" />
|
|
130
|
+
<span>{n.label}</span>
|
|
131
|
+
</SidebarMenuButton>
|
|
132
|
+
</SidebarMenuItem>
|
|
133
|
+
))}
|
|
134
|
+
</SidebarMenu>
|
|
135
|
+
</SidebarGroupContent>
|
|
136
|
+
</SidebarGroup>
|
|
137
|
+
</SidebarContent>
|
|
138
|
+
<SidebarFooter>
|
|
139
|
+
<NavUser user={{ name: "Avery Rao", email: "avery@example.com" }} />
|
|
140
|
+
</SidebarFooter>
|
|
141
|
+
</Sidebar>
|
|
142
|
+
<SidebarInset className="flex min-w-0 flex-col overflow-hidden">
|
|
143
|
+
<header className="flex h-header shrink-0 items-center gap-2 border-b px-4">
|
|
144
|
+
<SidebarTrigger />
|
|
145
|
+
<h1 className="text-body font-medium">AI Assistant</h1>
|
|
146
|
+
<ContextPanelTrigger className="ms-auto" />
|
|
147
|
+
</header>
|
|
148
|
+
{/* `bare`: the transcript scrolls behind the floating composer and
|
|
149
|
+
both share one centred reading column. */}
|
|
150
|
+
<div className="min-h-0 flex-1">
|
|
151
|
+
<ChatShell
|
|
152
|
+
variant="bare"
|
|
153
|
+
composer={
|
|
154
|
+
<Composer
|
|
155
|
+
placeholder="Send a message…"
|
|
156
|
+
status={status === "submitted" ? "Generating…" : "Awaiting your input"}
|
|
157
|
+
sendStatus={status}
|
|
158
|
+
onSubmit={(message) => {
|
|
159
|
+
const text = message.text?.trim();
|
|
160
|
+
if (text) send(text);
|
|
161
|
+
}}
|
|
126
162
|
/>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
163
|
+
}
|
|
164
|
+
>
|
|
165
|
+
<Conversation className="flex-1">
|
|
166
|
+
<ConversationContent>
|
|
167
|
+
{messages.length === 0 ? (
|
|
168
|
+
<ConversationEmptyState
|
|
169
|
+
icon={<MessageSquare className="size-8" aria-hidden="true" />}
|
|
170
|
+
title="Start the conversation"
|
|
171
|
+
description="Ask anything to begin."
|
|
172
|
+
actions={
|
|
173
|
+
<>
|
|
174
|
+
<Button
|
|
175
|
+
onClick={() => send("What can you help me with?")}
|
|
176
|
+
size="sm"
|
|
177
|
+
variant="outline"
|
|
178
|
+
>
|
|
179
|
+
What can you help me with?
|
|
180
|
+
</Button>
|
|
181
|
+
<Button
|
|
182
|
+
onClick={() => send("Summarize my recent activity")}
|
|
183
|
+
size="sm"
|
|
184
|
+
variant="outline"
|
|
185
|
+
>
|
|
186
|
+
Summarize my recent activity
|
|
187
|
+
</Button>
|
|
188
|
+
</>
|
|
189
|
+
}
|
|
190
|
+
/>
|
|
191
|
+
) : (
|
|
192
|
+
messages.map((m) => (
|
|
193
|
+
<Message from={m.role} key={m.id}>
|
|
194
|
+
<MessageContent>
|
|
195
|
+
<MessageResponse>{m.text}</MessageResponse>
|
|
196
|
+
</MessageContent>
|
|
197
|
+
</Message>
|
|
198
|
+
))
|
|
199
|
+
)}
|
|
200
|
+
</ConversationContent>
|
|
201
|
+
<ConversationScrollButton />
|
|
202
|
+
</Conversation>
|
|
203
|
+
</ChatShell>
|
|
204
|
+
</div>
|
|
205
|
+
</SidebarInset>
|
|
206
|
+
<ContextPanel>
|
|
207
|
+
<ContextPanelHeader title="Context" />
|
|
208
|
+
<ContextPanelBody
|
|
209
|
+
root={<ContextRailRoot assets={assets} />}
|
|
210
|
+
detail={<ContextRailDetail />}
|
|
147
211
|
/>
|
|
148
|
-
</
|
|
149
|
-
</
|
|
150
|
-
</
|
|
212
|
+
</ContextPanel>
|
|
213
|
+
</SidebarProvider>
|
|
214
|
+
</ContextPanelProvider>
|
|
151
215
|
);
|
|
152
216
|
}
|
|
153
217
|
|
|
154
218
|
const meta = {
|
|
155
|
-
title: "Patterns/Templates/AI Assistant",
|
|
219
|
+
title: "Patterns/Templates/Starters/AI Assistant",
|
|
156
220
|
parameters: { layout: "fullscreen" },
|
|
157
221
|
tags: ["autodocs"],
|
|
158
222
|
} satisfies Meta;
|
package/src/test-results.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { StatusBadge, StatusIcon, type Status } from "@elabs-ai/components-ui";
|
|
3
|
+
import { StatusBadge, StatusIcon, useLocale, type Status } from "@elabs-ai/components-ui";
|
|
4
4
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@elabs-ai/components-ui";
|
|
5
5
|
import { cn } from "@elabs-ai/components-ui/lib/cn";
|
|
6
6
|
import { ChevronRightIcon } from "lucide-react";
|
|
@@ -64,7 +64,7 @@ export const TestResultsDuration = ({
|
|
|
64
64
|
|
|
65
65
|
return (
|
|
66
66
|
<span
|
|
67
|
-
className={cn("shrink-0 text-muted-foreground text-
|
|
67
|
+
className={cn("shrink-0 text-muted-foreground text-body tabular-nums", className)}
|
|
68
68
|
{...props}
|
|
69
69
|
>
|
|
70
70
|
{children ?? formatDuration(summary.duration)}
|
|
@@ -76,6 +76,7 @@ export type TestResultsSummaryProps = HTMLAttributes<HTMLDivElement>;
|
|
|
76
76
|
|
|
77
77
|
export const TestResultsSummary = ({ className, children, ...props }: TestResultsSummaryProps) => {
|
|
78
78
|
const { summary } = useContext(TestResultsContext);
|
|
79
|
+
const { t } = useLocale();
|
|
79
80
|
|
|
80
81
|
if (!summary) {
|
|
81
82
|
return null;
|
|
@@ -86,16 +87,16 @@ export const TestResultsSummary = ({ className, children, ...props }: TestResult
|
|
|
86
87
|
{children ?? (
|
|
87
88
|
<>
|
|
88
89
|
<StatusBadge size="sm" status="complete">
|
|
89
|
-
{summary.passed}
|
|
90
|
+
{t("ai.testResults.passedCount", { count: summary.passed })}
|
|
90
91
|
</StatusBadge>
|
|
91
92
|
{summary.failed > 0 && (
|
|
92
93
|
<StatusBadge size="sm" status="failed">
|
|
93
|
-
{summary.failed}
|
|
94
|
+
{t("ai.testResults.failedCount", { count: summary.failed })}
|
|
94
95
|
</StatusBadge>
|
|
95
96
|
)}
|
|
96
97
|
{summary.skipped > 0 && (
|
|
97
98
|
<StatusBadge size="sm" status="skipped">
|
|
98
|
-
{summary.skipped}
|
|
99
|
+
{t("ai.testResults.skippedCount", { count: summary.skipped })}
|
|
99
100
|
</StatusBadge>
|
|
100
101
|
)}
|
|
101
102
|
</>
|
|
@@ -134,6 +135,7 @@ export const TestResultsProgress = ({
|
|
|
134
135
|
...props
|
|
135
136
|
}: TestResultsProgressProps) => {
|
|
136
137
|
const { summary } = useContext(TestResultsContext);
|
|
138
|
+
const { t, formatNumber } = useLocale();
|
|
137
139
|
|
|
138
140
|
if (!summary) {
|
|
139
141
|
return null;
|
|
@@ -156,11 +158,14 @@ export const TestResultsProgress = ({
|
|
|
156
158
|
style={{ width: `${failedPercent}%` }}
|
|
157
159
|
/>
|
|
158
160
|
</div>
|
|
159
|
-
<div className="flex justify-between text-muted-foreground text-
|
|
161
|
+
<div className="flex justify-between text-muted-foreground text-meta tabular-nums">
|
|
160
162
|
<span>
|
|
161
|
-
{summary.passed
|
|
163
|
+
{t("ai.testResults.testsPassed", { passed: summary.passed, total: summary.total })}
|
|
164
|
+
</span>
|
|
165
|
+
<span>
|
|
166
|
+
{formatNumber(passedPercent, { maximumFractionDigits: 0 })}
|
|
167
|
+
{"%"}
|
|
162
168
|
</span>
|
|
163
|
-
<span>{passedPercent.toFixed(0)}%</span>
|
|
164
169
|
</div>
|
|
165
170
|
</>
|
|
166
171
|
)}
|
|
@@ -247,7 +252,7 @@ export const TestSuiteName = ({ className, children, ...props }: TestSuiteNamePr
|
|
|
247
252
|
>
|
|
248
253
|
<ChevronRightIcon className="size-4 shrink-0 text-muted-foreground transition-transform duration-fast ease-standard motion-reduce:transition-none group-data-[state=open]:rotate-90" />
|
|
249
254
|
<TestStatusIcon status={status} />
|
|
250
|
-
<span className="min-w-0 flex-1 truncate font-medium text-
|
|
255
|
+
<span className="min-w-0 flex-1 truncate font-medium text-body">{children ?? name}</span>
|
|
251
256
|
</CollapsibleTrigger>
|
|
252
257
|
);
|
|
253
258
|
};
|
|
@@ -265,20 +270,35 @@ export const TestSuiteStats = ({
|
|
|
265
270
|
className,
|
|
266
271
|
children,
|
|
267
272
|
...props
|
|
268
|
-
}: TestSuiteStatsProps) =>
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
)
|
|
273
|
+
}: TestSuiteStatsProps) => {
|
|
274
|
+
const { t } = useLocale();
|
|
275
|
+
return (
|
|
276
|
+
<div
|
|
277
|
+
className={cn("ms-auto flex shrink-0 items-center gap-3 text-meta tabular-nums", className)}
|
|
278
|
+
{...props}
|
|
279
|
+
>
|
|
280
|
+
{children ?? (
|
|
281
|
+
<>
|
|
282
|
+
{passed > 0 && (
|
|
283
|
+
<span className="text-success-text">
|
|
284
|
+
{t("ai.testResults.passedCount", { count: passed })}
|
|
285
|
+
</span>
|
|
286
|
+
)}
|
|
287
|
+
{failed > 0 && (
|
|
288
|
+
<span className="text-destructive-text">
|
|
289
|
+
{t("ai.testResults.failedCount", { count: failed })}
|
|
290
|
+
</span>
|
|
291
|
+
)}
|
|
292
|
+
{skipped > 0 && (
|
|
293
|
+
<span className="text-muted-foreground">
|
|
294
|
+
{t("ai.testResults.skippedCount", { count: skipped })}
|
|
295
|
+
</span>
|
|
296
|
+
)}
|
|
297
|
+
</>
|
|
298
|
+
)}
|
|
299
|
+
</div>
|
|
300
|
+
);
|
|
301
|
+
};
|
|
282
302
|
|
|
283
303
|
export type TestSuiteContentProps = ComponentProps<typeof CollapsibleContent>;
|
|
284
304
|
|
|
@@ -328,7 +348,7 @@ export const TestDuration = ({ className, children, ...props }: TestDurationProp
|
|
|
328
348
|
|
|
329
349
|
return (
|
|
330
350
|
<span
|
|
331
|
-
className={cn("shrink-0 text-muted-foreground text-
|
|
351
|
+
className={cn("shrink-0 text-muted-foreground text-meta tabular-nums", className)}
|
|
332
352
|
{...props}
|
|
333
353
|
>
|
|
334
354
|
{children ?? `${duration}ms`}
|
|
@@ -365,7 +385,7 @@ export const Test = ({ name, status, duration, className, children, ...props }:
|
|
|
365
385
|
return (
|
|
366
386
|
<TestContext.Provider value={contextValue}>
|
|
367
387
|
<div
|
|
368
|
-
className={cn("flex min-w-0 items-center gap-2 ps-10 pe-4 py-2 text-
|
|
388
|
+
className={cn("flex min-w-0 items-center gap-2 ps-10 pe-4 py-2 text-body", className)}
|
|
369
389
|
{...props}
|
|
370
390
|
>
|
|
371
391
|
{children ?? (
|
|
@@ -391,7 +411,7 @@ export const TestError = ({ className, children, ...props }: TestErrorProps) =>
|
|
|
391
411
|
export type TestErrorMessageProps = HTMLAttributes<HTMLParagraphElement>;
|
|
392
412
|
|
|
393
413
|
export const TestErrorMessage = ({ className, children, ...props }: TestErrorMessageProps) => (
|
|
394
|
-
<p className={cn("font-medium text-destructive-text text-
|
|
414
|
+
<p className={cn("font-medium text-destructive-text text-body", className)} {...props}>
|
|
395
415
|
{children}
|
|
396
416
|
</p>
|
|
397
417
|
);
|
|
@@ -400,7 +420,7 @@ export type TestErrorStackProps = HTMLAttributes<HTMLPreElement>;
|
|
|
400
420
|
|
|
401
421
|
export const TestErrorStack = ({ className, children, ...props }: TestErrorStackProps) => (
|
|
402
422
|
<pre
|
|
403
|
-
className={cn("mt-2 overflow-auto font-mono text-destructive-text text-
|
|
423
|
+
className={cn("mt-2 overflow-auto font-mono text-destructive-text text-meta", className)}
|
|
404
424
|
{...props}
|
|
405
425
|
>
|
|
406
426
|
{children}
|
package/src/token-usage.tsx
CHANGED
|
@@ -154,7 +154,7 @@ export const TokenUsageContentHeader = ({
|
|
|
154
154
|
<div className={cn("w-full space-y-2 p-3", className)} {...props}>
|
|
155
155
|
{children ?? (
|
|
156
156
|
<>
|
|
157
|
-
<div className="flex items-center justify-between gap-3 text-
|
|
157
|
+
<div className="flex items-center justify-between gap-3 text-meta">
|
|
158
158
|
<p>{displayPct}</p>
|
|
159
159
|
<p className="font-mono text-muted-foreground">
|
|
160
160
|
{used} / {total}
|
|
@@ -207,7 +207,7 @@ export const TokenUsageContentFooter = ({
|
|
|
207
207
|
return (
|
|
208
208
|
<div
|
|
209
209
|
className={cn(
|
|
210
|
-
"flex w-full items-center justify-between gap-3 bg-secondary p-3 text-
|
|
210
|
+
"flex w-full items-center justify-between gap-3 bg-secondary p-3 text-meta",
|
|
211
211
|
className,
|
|
212
212
|
)}
|
|
213
213
|
{...props}
|
|
@@ -259,7 +259,7 @@ export const TokenUsageInput = ({ className, children, ...props }: TokenUsageInp
|
|
|
259
259
|
});
|
|
260
260
|
|
|
261
261
|
return (
|
|
262
|
-
<div className={cn("flex items-center justify-between text-
|
|
262
|
+
<div className={cn("flex items-center justify-between text-meta", className)} {...props}>
|
|
263
263
|
<span className="text-muted-foreground">{t("ai.tokenUsage.input")}</span>
|
|
264
264
|
<TokensWithCost costText={inputCostText} tokens={inputTokens} />
|
|
265
265
|
</div>
|
|
@@ -293,7 +293,7 @@ export const TokenUsageOutput = ({ className, children, ...props }: TokenUsageOu
|
|
|
293
293
|
});
|
|
294
294
|
|
|
295
295
|
return (
|
|
296
|
-
<div className={cn("flex items-center justify-between text-
|
|
296
|
+
<div className={cn("flex items-center justify-between text-meta", className)} {...props}>
|
|
297
297
|
<span className="text-muted-foreground">{t("ai.tokenUsage.output")}</span>
|
|
298
298
|
<TokensWithCost costText={outputCostText} tokens={outputTokens} />
|
|
299
299
|
</div>
|
|
@@ -333,7 +333,7 @@ export const TokenUsageReasoning = ({
|
|
|
333
333
|
});
|
|
334
334
|
|
|
335
335
|
return (
|
|
336
|
-
<div className={cn("flex items-center justify-between text-
|
|
336
|
+
<div className={cn("flex items-center justify-between text-meta", className)} {...props}>
|
|
337
337
|
<span className="text-muted-foreground">{t("ai.tokenUsage.reasoning")}</span>
|
|
338
338
|
<TokensWithCost costText={reasoningCostText} tokens={reasoningTokens} />
|
|
339
339
|
</div>
|
|
@@ -369,7 +369,7 @@ export const TokenUsageCache = ({ className, children, ...props }: TokenUsageCac
|
|
|
369
369
|
});
|
|
370
370
|
|
|
371
371
|
return (
|
|
372
|
-
<div className={cn("flex items-center justify-between text-
|
|
372
|
+
<div className={cn("flex items-center justify-between text-meta", className)} {...props}>
|
|
373
373
|
<span className="text-muted-foreground">{t("ai.tokenUsage.cache")}</span>
|
|
374
374
|
<TokensWithCost costText={cacheCostText} tokens={cacheTokens} />
|
|
375
375
|
</div>
|