@adea-ai/ui 0.140.0 → 0.142.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/dist/components/composites/appearance-editor/appearance-editor.js +2 -2
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
- package/dist/components/composites/catalog-browser/catalog-browser-group.js +1 -1
- package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts +56 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts.map +1 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.js +117 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.js.map +1 -0
- package/dist/components/composites/chain-of-thought/index.d.ts +2 -0
- package/dist/components/composites/chain-of-thought/index.d.ts.map +1 -0
- package/dist/components/composites/chain-of-thought/index.js +2 -0
- package/dist/components/composites/chat/chat.d.ts +67 -0
- package/dist/components/composites/chat/chat.d.ts.map +1 -0
- package/dist/components/composites/chat/chat.js +179 -0
- package/dist/components/composites/chat/chat.js.map +1 -0
- package/dist/components/composites/chat/index.d.ts +2 -0
- package/dist/components/composites/chat/index.d.ts.map +1 -0
- package/dist/components/composites/chat/index.js +2 -0
- package/dist/components/composites/checkpoint/checkpoint-model.d.ts +34 -0
- package/dist/components/composites/checkpoint/checkpoint-model.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint-model.js +48 -0
- package/dist/components/composites/checkpoint/checkpoint-model.js.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint.d.ts +48 -0
- package/dist/components/composites/checkpoint/checkpoint.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint.js +160 -0
- package/dist/components/composites/checkpoint/checkpoint.js.map +1 -0
- package/dist/components/composites/checkpoint/index.d.ts +3 -0
- package/dist/components/composites/checkpoint/index.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/index.js +3 -0
- package/dist/components/composites/confirmation/confirmation-model.d.ts +45 -0
- package/dist/components/composites/confirmation/confirmation-model.d.ts.map +1 -0
- package/dist/components/composites/confirmation/confirmation-model.js +51 -0
- package/dist/components/composites/confirmation/confirmation-model.js.map +1 -0
- package/dist/components/composites/confirmation/confirmation.d.ts +72 -0
- package/dist/components/composites/confirmation/confirmation.d.ts.map +1 -0
- package/dist/components/composites/confirmation/confirmation.js +300 -0
- package/dist/components/composites/confirmation/confirmation.js.map +1 -0
- package/dist/components/composites/confirmation/index.d.ts +3 -0
- package/dist/components/composites/confirmation/index.d.ts.map +1 -0
- package/dist/components/composites/confirmation/index.js +3 -0
- package/dist/components/composites/context/context-model.d.ts +69 -0
- package/dist/components/composites/context/context-model.d.ts.map +1 -0
- package/dist/components/composites/context/context-model.js +122 -0
- package/dist/components/composites/context/context-model.js.map +1 -0
- package/dist/components/composites/context/context.d.ts +38 -0
- package/dist/components/composites/context/context.d.ts.map +1 -0
- package/dist/components/composites/context/context.js +234 -0
- package/dist/components/composites/context/context.js.map +1 -0
- package/dist/components/composites/context/index.d.ts +3 -0
- package/dist/components/composites/context/index.d.ts.map +1 -0
- package/dist/components/composites/context/index.js +3 -0
- package/dist/components/composites/file-tree/build-file-tree.d.ts +138 -0
- package/dist/components/composites/file-tree/build-file-tree.d.ts.map +1 -0
- package/dist/components/composites/file-tree/build-file-tree.js +325 -0
- package/dist/components/composites/file-tree/build-file-tree.js.map +1 -0
- package/dist/components/composites/file-tree/file-tree.d.ts +74 -0
- package/dist/components/composites/file-tree/file-tree.d.ts.map +1 -0
- package/dist/components/composites/file-tree/file-tree.js +389 -0
- package/dist/components/composites/file-tree/file-tree.js.map +1 -0
- package/dist/components/composites/file-tree/index.d.ts +3 -0
- package/dist/components/composites/file-tree/index.d.ts.map +1 -0
- package/dist/components/composites/file-tree/index.js +3 -0
- package/dist/components/composites/inline-citation/citation.d.ts +37 -0
- package/dist/components/composites/inline-citation/citation.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/citation.js +52 -0
- package/dist/components/composites/inline-citation/citation.js.map +1 -0
- package/dist/components/composites/inline-citation/index.d.ts +3 -0
- package/dist/components/composites/inline-citation/index.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/index.js +3 -0
- package/dist/components/composites/inline-citation/inline-citation.d.ts +64 -0
- package/dist/components/composites/inline-citation/inline-citation.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/inline-citation.js +272 -0
- package/dist/components/composites/inline-citation/inline-citation.js.map +1 -0
- package/dist/components/composites/message-scroller/index.d.ts +3 -0
- package/dist/components/composites/message-scroller/index.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/index.js +3 -0
- package/dist/components/composites/message-scroller/message-scroller.d.ts +55 -0
- package/dist/components/composites/message-scroller/message-scroller.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/message-scroller.js +201 -0
- package/dist/components/composites/message-scroller/message-scroller.js.map +1 -0
- package/dist/components/composites/message-scroller/scroll-anchor.d.ts +66 -0
- package/dist/components/composites/message-scroller/scroll-anchor.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/scroll-anchor.js +122 -0
- package/dist/components/composites/message-scroller/scroll-anchor.js.map +1 -0
- package/dist/components/composites/model-selector/index.d.ts +3 -0
- package/dist/components/composites/model-selector/index.d.ts.map +1 -0
- package/dist/components/composites/model-selector/index.js +3 -0
- package/dist/components/composites/model-selector/model-selector.d.ts +55 -0
- package/dist/components/composites/model-selector/model-selector.d.ts.map +1 -0
- package/dist/components/composites/model-selector/model-selector.js +490 -0
- package/dist/components/composites/model-selector/model-selector.js.map +1 -0
- package/dist/components/composites/model-selector/models.d.ts +51 -0
- package/dist/components/composites/model-selector/models.d.ts.map +1 -0
- package/dist/components/composites/model-selector/models.js +71 -0
- package/dist/components/composites/model-selector/models.js.map +1 -0
- package/dist/components/composites/plan/index.d.ts +2 -0
- package/dist/components/composites/plan/index.d.ts.map +1 -0
- package/dist/components/composites/plan/index.js +2 -0
- package/dist/components/composites/plan/plan.d.ts +61 -0
- package/dist/components/composites/plan/plan.d.ts.map +1 -0
- package/dist/components/composites/plan/plan.js +130 -0
- package/dist/components/composites/plan/plan.js.map +1 -0
- package/dist/components/composites/queue/index.d.ts +2 -0
- package/dist/components/composites/queue/index.d.ts.map +1 -0
- package/dist/components/composites/queue/index.js +2 -0
- package/dist/components/composites/queue/queue.d.ts +77 -0
- package/dist/components/composites/queue/queue.d.ts.map +1 -0
- package/dist/components/composites/queue/queue.js +271 -0
- package/dist/components/composites/queue/queue.js.map +1 -0
- package/dist/components/composites/reasoning/index.d.ts +2 -0
- package/dist/components/composites/reasoning/index.d.ts.map +1 -0
- package/dist/components/composites/reasoning/index.js +2 -0
- package/dist/components/composites/reasoning/reasoning.d.ts +62 -0
- package/dist/components/composites/reasoning/reasoning.d.ts.map +1 -0
- package/dist/components/composites/reasoning/reasoning.js +156 -0
- package/dist/components/composites/reasoning/reasoning.js.map +1 -0
- package/dist/components/composites/sources/index.d.ts +3 -0
- package/dist/components/composites/sources/index.d.ts.map +1 -0
- package/dist/components/composites/sources/index.js +3 -0
- package/dist/components/composites/sources/source.d.ts +46 -0
- package/dist/components/composites/sources/source.d.ts.map +1 -0
- package/dist/components/composites/sources/source.js +74 -0
- package/dist/components/composites/sources/source.js.map +1 -0
- package/dist/components/composites/sources/sources.d.ts +45 -0
- package/dist/components/composites/sources/sources.d.ts.map +1 -0
- package/dist/components/composites/sources/sources.js +175 -0
- package/dist/components/composites/sources/sources.js.map +1 -0
- package/dist/components/composites/stack-trace/index.d.ts +3 -0
- package/dist/components/composites/stack-trace/index.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/index.js +3 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.d.ts +118 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.js +376 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.js.map +1 -0
- package/dist/components/composites/stack-trace/stack-trace.d.ts +63 -0
- package/dist/components/composites/stack-trace/stack-trace.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/stack-trace.js +491 -0
- package/dist/components/composites/stack-trace/stack-trace.js.map +1 -0
- package/dist/components/composites/subagent/index.d.ts +2 -0
- package/dist/components/composites/subagent/index.d.ts.map +1 -0
- package/dist/components/composites/subagent/index.js +2 -0
- package/dist/components/composites/subagent/subagent.d.ts +55 -0
- package/dist/components/composites/subagent/subagent.d.ts.map +1 -0
- package/dist/components/composites/subagent/subagent.js +138 -0
- package/dist/components/composites/subagent/subagent.js.map +1 -0
- package/dist/components/composites/suggestion/index.d.ts +2 -0
- package/dist/components/composites/suggestion/index.d.ts.map +1 -0
- package/dist/components/composites/suggestion/index.js +2 -0
- package/dist/components/composites/suggestion/suggestion.d.ts +37 -0
- package/dist/components/composites/suggestion/suggestion.d.ts.map +1 -0
- package/dist/components/composites/suggestion/suggestion.js +100 -0
- package/dist/components/composites/suggestion/suggestion.js.map +1 -0
- package/dist/components/composites/task/index.d.ts +2 -0
- package/dist/components/composites/task/index.d.ts.map +1 -0
- package/dist/components/composites/task/index.js +2 -0
- package/dist/components/composites/task/task.d.ts +96 -0
- package/dist/components/composites/task/task.d.ts.map +1 -0
- package/dist/components/composites/task/task.js +311 -0
- package/dist/components/composites/task/task.js.map +1 -0
- package/dist/components/composites/terminal/ansi.d.ts +101 -0
- package/dist/components/composites/terminal/ansi.d.ts.map +1 -0
- package/dist/components/composites/terminal/ansi.js +544 -0
- package/dist/components/composites/terminal/ansi.js.map +1 -0
- package/dist/components/composites/terminal/index.d.ts +4 -0
- package/dist/components/composites/terminal/index.d.ts.map +1 -0
- package/dist/components/composites/terminal/index.js +4 -0
- package/dist/components/composites/terminal/terminal-model.d.ts +63 -0
- package/dist/components/composites/terminal/terminal-model.d.ts.map +1 -0
- package/dist/components/composites/terminal/terminal-model.js +69 -0
- package/dist/components/composites/terminal/terminal-model.js.map +1 -0
- package/dist/components/composites/terminal/terminal.d.ts +88 -0
- package/dist/components/composites/terminal/terminal.d.ts.map +1 -0
- package/dist/components/composites/terminal/terminal.js +500 -0
- package/dist/components/composites/terminal/terminal.js.map +1 -0
- package/dist/components/composites/test-results/index.d.ts +3 -0
- package/dist/components/composites/test-results/index.d.ts.map +1 -0
- package/dist/components/composites/test-results/index.js +3 -0
- package/dist/components/composites/test-results/test-results-model.d.ts +154 -0
- package/dist/components/composites/test-results/test-results-model.d.ts.map +1 -0
- package/dist/components/composites/test-results/test-results-model.js +252 -0
- package/dist/components/composites/test-results/test-results-model.js.map +1 -0
- package/dist/components/composites/test-results/test-results.d.ts +60 -0
- package/dist/components/composites/test-results/test-results.d.ts.map +1 -0
- package/dist/components/composites/test-results/test-results.js +631 -0
- package/dist/components/composites/test-results/test-results.js.map +1 -0
- package/dist/components/composites/tool/format-tool-value.d.ts +37 -0
- package/dist/components/composites/tool/format-tool-value.d.ts.map +1 -0
- package/dist/components/composites/tool/format-tool-value.js +135 -0
- package/dist/components/composites/tool/format-tool-value.js.map +1 -0
- package/dist/components/composites/tool/index.d.ts +3 -0
- package/dist/components/composites/tool/index.d.ts.map +1 -0
- package/dist/components/composites/tool/index.js +3 -0
- package/dist/components/composites/tool/tool.d.ts +69 -0
- package/dist/components/composites/tool/tool.d.ts.map +1 -0
- package/dist/components/composites/tool/tool.js +214 -0
- package/dist/components/composites/tool/tool.js.map +1 -0
- package/dist/components/composites/update-dialog/update-dialog.js +1 -1
- package/dist/components/conversation/conversation-surface.d.ts +7 -0
- package/dist/components/conversation/conversation-surface.d.ts.map +1 -1
- package/dist/components/conversation/conversation-surface.js +2 -0
- package/dist/components/conversation/conversation-surface.js.map +1 -1
- package/dist/components/conversation/scroll-follow-core.d.ts +24 -0
- package/dist/components/conversation/scroll-follow-core.d.ts.map +1 -1
- package/dist/components/conversation/scroll-follow-core.js +23 -1
- package/dist/components/conversation/scroll-follow-core.js.map +1 -1
- package/dist/components/conversation/scroll-follow.d.ts +3 -0
- package/dist/components/conversation/scroll-follow.d.ts.map +1 -1
- package/dist/components/conversation/scroll-follow.js +80 -1
- package/dist/components/conversation/scroll-follow.js.map +1 -1
- package/dist/components/ui/attachment/attachment.d.ts +58 -0
- package/dist/components/ui/attachment/attachment.d.ts.map +1 -0
- package/dist/components/ui/attachment/attachment.js +279 -0
- package/dist/components/ui/attachment/attachment.js.map +1 -0
- package/dist/components/ui/attachment/index.d.ts +2 -0
- package/dist/components/ui/attachment/index.d.ts.map +1 -0
- package/dist/components/ui/attachment/index.js +2 -0
- package/dist/components/ui/badge/badge.d.ts +1 -1
- package/dist/components/ui/bubble/bubble.d.ts +33 -0
- package/dist/components/ui/bubble/bubble.d.ts.map +1 -0
- package/dist/components/ui/bubble/bubble.js +95 -0
- package/dist/components/ui/bubble/bubble.js.map +1 -0
- package/dist/components/ui/bubble/index.d.ts +2 -0
- package/dist/components/ui/bubble/index.d.ts.map +1 -0
- package/dist/components/ui/bubble/index.js +2 -0
- package/dist/components/ui/button/button.d.ts +1 -1
- package/dist/components/ui/code-block/code-block.d.ts +56 -3
- package/dist/components/ui/code-block/code-block.d.ts.map +1 -1
- package/dist/components/ui/code-block/code-block.js +231 -50
- package/dist/components/ui/code-block/code-block.js.map +1 -1
- package/dist/components/ui/code-block/index.d.ts +1 -1
- package/dist/components/ui/code-block/index.d.ts.map +1 -1
- package/dist/components/ui/code-block/index.js +2 -2
- package/dist/components/ui/field/number-field.d.ts +21 -4
- package/dist/components/ui/field/number-field.d.ts.map +1 -1
- package/dist/components/ui/field/number-field.js +22 -11
- package/dist/components/ui/field/number-field.js.map +1 -1
- package/dist/components/ui/marker/index.d.ts +2 -0
- package/dist/components/ui/marker/index.d.ts.map +1 -0
- package/dist/components/ui/marker/index.js +2 -0
- package/dist/components/ui/marker/marker.d.ts +35 -0
- package/dist/components/ui/marker/marker.d.ts.map +1 -0
- package/dist/components/ui/marker/marker.js +123 -0
- package/dist/components/ui/marker/marker.js.map +1 -0
- package/dist/components/ui/message/cite-ranges.d.ts +42 -0
- package/dist/components/ui/message/cite-ranges.d.ts.map +1 -0
- package/dist/components/ui/message/cite-ranges.js +105 -0
- package/dist/components/ui/message/cite-ranges.js.map +1 -0
- package/dist/components/ui/message/index.d.ts +4 -0
- package/dist/components/ui/message/index.d.ts.map +1 -0
- package/dist/components/ui/message/index.js +4 -0
- package/dist/components/ui/message/message.d.ts +95 -0
- package/dist/components/ui/message/message.d.ts.map +1 -0
- package/dist/components/ui/message/message.js +443 -0
- package/dist/components/ui/message/message.js.map +1 -0
- package/dist/components/ui/message/parse-message-text.d.ts +93 -0
- package/dist/components/ui/message/parse-message-text.d.ts.map +1 -0
- package/dist/components/ui/message/parse-message-text.js +365 -0
- package/dist/components/ui/message/parse-message-text.js.map +1 -0
- package/dist/components/ui/questionnaire/index.d.ts +2 -0
- package/dist/components/ui/questionnaire/index.d.ts.map +1 -0
- package/dist/components/ui/questionnaire/index.js +2 -0
- package/dist/components/ui/questionnaire/questionnaire.d.ts +83 -0
- package/dist/components/ui/questionnaire/questionnaire.d.ts.map +1 -0
- package/dist/components/ui/questionnaire/questionnaire.js +470 -0
- package/dist/components/ui/questionnaire/questionnaire.js.map +1 -0
- package/dist/components/ui/status-chip/status-chip.d.ts +1 -1
- package/dist/components/ui/switch/switch.js +11 -11
- package/dist/components/ui/switch/switch.js.map +1 -1
- package/dist/components/ui/trace/index.d.ts +2 -0
- package/dist/components/ui/trace/index.d.ts.map +1 -0
- package/dist/components/ui/trace/index.js +2 -0
- package/dist/components/ui/trace/trace.d.ts +72 -0
- package/dist/components/ui/trace/trace.d.ts.map +1 -0
- package/dist/components/ui/trace/trace.js +340 -0
- package/dist/components/ui/trace/trace.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -5
- package/dist/r/attachment.json +25 -0
- package/dist/r/bubble.json +22 -0
- package/dist/r/chain-of-thought.json +26 -0
- package/dist/r/chat.json +24 -0
- package/dist/r/checkpoint.json +35 -0
- package/dist/r/confirmation.json +34 -0
- package/dist/r/context.json +33 -0
- package/dist/r/file-tree.json +32 -0
- package/dist/r/inline-citation.json +35 -0
- package/dist/r/marker.json +22 -0
- package/dist/r/message-scroller.json +31 -0
- package/dist/r/message.json +33 -0
- package/dist/r/model-selector.json +34 -0
- package/dist/r/plan.json +26 -0
- package/dist/r/questionnaire.json +28 -0
- package/dist/r/queue.json +26 -0
- package/dist/r/reasoning.json +26 -0
- package/dist/r/registry.json +811 -52
- package/dist/r/sources.json +32 -0
- package/dist/r/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
- package/dist/r/src/components/composites/chain-of-thought/index.ts +11 -0
- package/dist/r/src/components/composites/chat/chat.tsx +190 -0
- package/dist/r/src/components/composites/chat/index.ts +11 -0
- package/dist/r/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
- package/dist/r/src/components/composites/checkpoint/checkpoint.tsx +214 -0
- package/dist/r/src/components/composites/checkpoint/index.ts +8 -0
- package/dist/r/src/components/composites/confirmation/confirmation-model.ts +83 -0
- package/dist/r/src/components/composites/confirmation/confirmation.tsx +311 -0
- package/dist/r/src/components/composites/confirmation/index.ts +9 -0
- package/dist/r/src/components/composites/context/context-model.ts +168 -0
- package/dist/r/src/components/composites/context/context.tsx +187 -0
- package/dist/r/src/components/composites/context/index.ts +18 -0
- package/dist/r/src/components/composites/file-tree/build-file-tree.ts +456 -0
- package/dist/r/src/components/composites/file-tree/file-tree.tsx +405 -0
- package/dist/r/src/components/composites/file-tree/index.ts +25 -0
- package/dist/r/src/components/composites/inline-citation/citation.ts +78 -0
- package/dist/r/src/components/composites/inline-citation/index.ts +9 -0
- package/dist/r/src/components/composites/inline-citation/inline-citation.tsx +285 -0
- package/dist/r/src/components/composites/message-scroller/index.ts +2 -0
- package/dist/r/src/components/composites/message-scroller/message-scroller.tsx +301 -0
- package/dist/r/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
- package/dist/r/src/components/composites/model-selector/index.ts +14 -0
- package/dist/r/src/components/composites/model-selector/model-selector.tsx +420 -0
- package/dist/r/src/components/composites/model-selector/models.ts +103 -0
- package/dist/r/src/components/composites/plan/index.ts +1 -0
- package/dist/r/src/components/composites/plan/plan.tsx +155 -0
- package/dist/r/src/components/composites/queue/index.ts +10 -0
- package/dist/r/src/components/composites/queue/queue.tsx +264 -0
- package/dist/r/src/components/composites/reasoning/index.ts +1 -0
- package/dist/r/src/components/composites/reasoning/reasoning.tsx +176 -0
- package/dist/r/src/components/composites/sources/index.ts +11 -0
- package/dist/r/src/components/composites/sources/source.ts +116 -0
- package/dist/r/src/components/composites/sources/sources.tsx +163 -0
- package/dist/r/src/components/composites/stack-trace/index.ts +19 -0
- package/dist/r/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
- package/dist/r/src/components/composites/stack-trace/stack-trace.tsx +395 -0
- package/dist/r/src/components/composites/subagent/index.ts +1 -0
- package/dist/r/src/components/composites/subagent/subagent.tsx +159 -0
- package/dist/r/src/components/composites/suggestion/index.ts +1 -0
- package/dist/r/src/components/composites/suggestion/suggestion.tsx +140 -0
- package/dist/r/src/components/composites/task/index.ts +14 -0
- package/dist/r/src/components/composites/task/task.tsx +317 -0
- package/dist/r/src/components/composites/terminal/ansi.ts +674 -0
- package/dist/r/src/components/composites/terminal/index.ts +20 -0
- package/dist/r/src/components/composites/terminal/terminal-model.ts +111 -0
- package/dist/r/src/components/composites/terminal/terminal.tsx +574 -0
- package/dist/r/src/components/composites/test-results/index.ts +20 -0
- package/dist/r/src/components/composites/test-results/test-results-model.ts +368 -0
- package/dist/r/src/components/composites/test-results/test-results.tsx +586 -0
- package/dist/r/src/components/composites/tool/format-tool-value.ts +221 -0
- package/dist/r/src/components/composites/tool/index.ts +2 -0
- package/dist/r/src/components/composites/tool/tool.tsx +228 -0
- package/dist/r/src/components/conversation/conversation-surface.tsx +9 -0
- package/dist/r/src/components/conversation/scroll-follow-core.ts +31 -0
- package/dist/r/src/components/conversation/scroll-follow.ts +92 -0
- package/dist/r/src/components/ui/attachment/attachment.tsx +282 -0
- package/dist/r/src/components/ui/attachment/index.ts +10 -0
- package/dist/r/src/components/ui/bubble/bubble.tsx +86 -0
- package/dist/r/src/components/ui/bubble/index.ts +1 -0
- package/dist/r/src/components/ui/code-block/code-block.tsx +256 -26
- package/dist/r/src/components/ui/code-block/index.ts +9 -1
- package/dist/r/src/components/ui/field/number-field.tsx +51 -14
- package/dist/r/src/components/ui/marker/index.ts +1 -0
- package/dist/r/src/components/ui/marker/marker.tsx +90 -0
- package/dist/r/src/components/ui/message/cite-ranges.ts +144 -0
- package/dist/r/src/components/ui/message/index.ts +23 -0
- package/dist/r/src/components/ui/message/message.tsx +434 -0
- package/dist/r/src/components/ui/message/parse-message-text.ts +450 -0
- package/dist/r/src/components/ui/questionnaire/index.ts +10 -0
- package/dist/r/src/components/ui/questionnaire/questionnaire.tsx +446 -0
- package/dist/r/src/components/ui/trace/index.ts +9 -0
- package/dist/r/src/components/ui/trace/trace.tsx +334 -0
- package/dist/r/src/styles/base.css +34 -0
- package/dist/r/stack-trace.json +32 -0
- package/dist/r/subagent.json +27 -0
- package/dist/r/suggestion.json +24 -0
- package/dist/r/task.json +28 -0
- package/dist/r/terminal.json +35 -0
- package/dist/r/test-results.json +33 -0
- package/dist/r/tool.json +31 -0
- package/dist/r/trace.json +25 -0
- package/package.json +6 -3
- package/registry.json +811 -52
- package/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
- package/src/components/composites/chain-of-thought/index.ts +11 -0
- package/src/components/composites/chat/chat.tsx +190 -0
- package/src/components/composites/chat/index.ts +11 -0
- package/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
- package/src/components/composites/checkpoint/checkpoint.tsx +214 -0
- package/src/components/composites/checkpoint/index.ts +8 -0
- package/src/components/composites/confirmation/confirmation-model.ts +83 -0
- package/src/components/composites/confirmation/confirmation.tsx +311 -0
- package/src/components/composites/confirmation/index.ts +9 -0
- package/src/components/composites/context/context-model.ts +168 -0
- package/src/components/composites/context/context.tsx +187 -0
- package/src/components/composites/context/index.ts +18 -0
- package/src/components/composites/file-tree/build-file-tree.ts +456 -0
- package/src/components/composites/file-tree/file-tree.tsx +405 -0
- package/src/components/composites/file-tree/index.ts +25 -0
- package/src/components/composites/inline-citation/citation.ts +78 -0
- package/src/components/composites/inline-citation/index.ts +9 -0
- package/src/components/composites/inline-citation/inline-citation.tsx +285 -0
- package/src/components/composites/message-scroller/index.ts +2 -0
- package/src/components/composites/message-scroller/message-scroller.tsx +301 -0
- package/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
- package/src/components/composites/model-selector/index.ts +14 -0
- package/src/components/composites/model-selector/model-selector.tsx +420 -0
- package/src/components/composites/model-selector/models.ts +103 -0
- package/src/components/composites/plan/index.ts +1 -0
- package/src/components/composites/plan/plan.tsx +155 -0
- package/src/components/composites/queue/index.ts +10 -0
- package/src/components/composites/queue/queue.tsx +264 -0
- package/src/components/composites/reasoning/index.ts +1 -0
- package/src/components/composites/reasoning/reasoning.tsx +176 -0
- package/src/components/composites/sources/index.ts +11 -0
- package/src/components/composites/sources/source.ts +116 -0
- package/src/components/composites/sources/sources.tsx +163 -0
- package/src/components/composites/stack-trace/index.ts +19 -0
- package/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
- package/src/components/composites/stack-trace/stack-trace.tsx +395 -0
- package/src/components/composites/subagent/index.ts +1 -0
- package/src/components/composites/subagent/subagent.tsx +159 -0
- package/src/components/composites/suggestion/index.ts +1 -0
- package/src/components/composites/suggestion/suggestion.tsx +140 -0
- package/src/components/composites/task/index.ts +14 -0
- package/src/components/composites/task/task.tsx +317 -0
- package/src/components/composites/terminal/ansi.ts +674 -0
- package/src/components/composites/terminal/index.ts +20 -0
- package/src/components/composites/terminal/terminal-model.ts +111 -0
- package/src/components/composites/terminal/terminal.tsx +574 -0
- package/src/components/composites/test-results/index.ts +20 -0
- package/src/components/composites/test-results/test-results-model.ts +368 -0
- package/src/components/composites/test-results/test-results.tsx +586 -0
- package/src/components/composites/tool/format-tool-value.ts +221 -0
- package/src/components/composites/tool/index.ts +2 -0
- package/src/components/composites/tool/tool.tsx +228 -0
- package/src/components/conversation/conversation-surface.tsx +9 -0
- package/src/components/conversation/scroll-follow-core.ts +31 -0
- package/src/components/conversation/scroll-follow.ts +92 -0
- package/src/components/ui/attachment/attachment.tsx +282 -0
- package/src/components/ui/attachment/index.ts +10 -0
- package/src/components/ui/bubble/bubble.tsx +86 -0
- package/src/components/ui/bubble/index.ts +1 -0
- package/src/components/ui/code-block/code-block.tsx +256 -26
- package/src/components/ui/code-block/index.ts +9 -1
- package/src/components/ui/field/number-field.tsx +51 -14
- package/src/components/ui/marker/index.ts +1 -0
- package/src/components/ui/marker/marker.tsx +90 -0
- package/src/components/ui/message/cite-ranges.ts +144 -0
- package/src/components/ui/message/index.ts +23 -0
- package/src/components/ui/message/message.tsx +434 -0
- package/src/components/ui/message/parse-message-text.ts +450 -0
- package/src/components/ui/questionnaire/index.ts +10 -0
- package/src/components/ui/questionnaire/questionnaire.tsx +446 -0
- package/src/components/ui/trace/index.ts +9 -0
- package/src/components/ui/trace/trace.tsx +334 -0
- package/src/index.ts +26 -0
- package/src/styles/base.css +34 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { ListOrdered } from 'lucide-solid'
|
|
2
|
+
import { children as resolveChildren, splitProps, type ComponentProps, type JSX } from 'solid-js'
|
|
3
|
+
import { cn } from '#lib/utils'
|
|
4
|
+
import { Badge } from '../../ui/badge'
|
|
5
|
+
import { Trace, TraceLine, type TraceLineProps, type TraceStatus } from '../../ui/trace'
|
|
6
|
+
|
|
7
|
+
// A function child runs once, when the content mounts (see `deferred` in `tool.tsx`).
|
|
8
|
+
const deferred = (render: () => JSX.Element) => render as unknown as JSX.Element
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* ChainOfThought.
|
|
12
|
+
*
|
|
13
|
+
* A summary line that opens onto the steps behind it: "Searched 3 sources and
|
|
14
|
+
* compared them", then each source and each comparison as its own line. Reach for
|
|
15
|
+
* `Reasoning` when the thinking is prose, for `Plan` when the steps are a
|
|
16
|
+
* proposal still to be carried out, and for a plain `Trace` when each line is a
|
|
17
|
+
* tool call — a step here is a statement about the agent's *method*, whatever
|
|
18
|
+
* the host chooses to put in it.
|
|
19
|
+
*
|
|
20
|
+
* Nothing here knows how the steps were produced. The host passes the summary and
|
|
21
|
+
* the steps it wants shown; the component does not imply there is more, and a
|
|
22
|
+
* summary with no steps is a plain line.
|
|
23
|
+
*
|
|
24
|
+
* ## Steps
|
|
25
|
+
*
|
|
26
|
+
* A `ChainOfThoughtStep` is a `TraceLine` with a three-state `status` — `complete`
|
|
27
|
+
* (keeps its own icon, or a tick), `active` (running mark and shimmer) and
|
|
28
|
+
* `pending` (dashed mark). Every status is also spoken. A step without a status
|
|
29
|
+
* makes no claim at all. A step's `children` are its evidence — search-result
|
|
30
|
+
* badges, a snippet — and are open by default: someone who unfolded the summary
|
|
31
|
+
* to see the working wants to see what the working found, and one more click per
|
|
32
|
+
* step to read it defeats the point of the summary.
|
|
33
|
+
*
|
|
34
|
+
* `description` is a single truncated row beside the label. Anything longer
|
|
35
|
+
* belongs in `children`.
|
|
36
|
+
*
|
|
37
|
+
* Both parts are lines: put a `ChainOfThought` inside a `Trace`, next to the
|
|
38
|
+
* other activity of the turn.
|
|
39
|
+
*/
|
|
40
|
+
export type ChainOfThoughtStepStatus = 'complete' | 'active' | 'pending'
|
|
41
|
+
|
|
42
|
+
/** The words spoken for each step status. */
|
|
43
|
+
export const CHAIN_OF_THOUGHT_STATUS_LABELS: Readonly<Record<ChainOfThoughtStepStatus, string>> = {
|
|
44
|
+
complete: 'Done',
|
|
45
|
+
active: 'In progress',
|
|
46
|
+
pending: 'Pending',
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const TRACE_STATUS: Readonly<Record<ChainOfThoughtStepStatus, TraceStatus>> = {
|
|
50
|
+
complete: 'success',
|
|
51
|
+
active: 'running',
|
|
52
|
+
pending: 'pending',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type ChainOfThoughtProps = Omit<
|
|
56
|
+
TraceLineProps,
|
|
57
|
+
'title' | 'href' | 'onSelect' | 'selectHaspopup'
|
|
58
|
+
> & {
|
|
59
|
+
/** The one-line account of what the steps add up to. */
|
|
60
|
+
summary?: JSX.Element
|
|
61
|
+
/** The steps' accessible name. */
|
|
62
|
+
stepsLabel?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function ChainOfThought(props: ChainOfThoughtProps) {
|
|
66
|
+
const [local, rest] = splitProps(props, ['summary', 'stepsLabel', 'icon', 'children'])
|
|
67
|
+
// Resolved once so the steps are created once: a step keeps its own open state
|
|
68
|
+
// and its DOM while the summary is folded and unfolded.
|
|
69
|
+
const steps = resolveChildren(() => local.children)
|
|
70
|
+
const hasSteps = () => steps.toArray().length > 0
|
|
71
|
+
// A function child runs only when the content mounts, and once.
|
|
72
|
+
const stepList = () => (
|
|
73
|
+
<Trace size="sm" aria-label={local.stepsLabel ?? 'Steps'}>
|
|
74
|
+
{steps()}
|
|
75
|
+
</Trace>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<TraceLine icon={local.icon ?? <ListOrdered />} title={local.summary ?? 'Steps'} {...rest}>
|
|
80
|
+
{hasSteps() ? deferred(stepList) : undefined}
|
|
81
|
+
</TraceLine>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type ChainOfThoughtStepProps = Omit<
|
|
86
|
+
TraceLineProps,
|
|
87
|
+
'title' | 'status' | 'href' | 'onSelect' | 'selectHaspopup'
|
|
88
|
+
> & {
|
|
89
|
+
label: JSX.Element
|
|
90
|
+
status?: ChainOfThoughtStepStatus
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function ChainOfThoughtStep(props: ChainOfThoughtStepProps) {
|
|
94
|
+
const [local, rest] = splitProps(props, ['label', 'status', 'statusLabel', 'defaultOpen'])
|
|
95
|
+
return (
|
|
96
|
+
<TraceLine
|
|
97
|
+
title={local.label}
|
|
98
|
+
status={local.status ? TRACE_STATUS[local.status] : undefined}
|
|
99
|
+
statusLabel={
|
|
100
|
+
local.status
|
|
101
|
+
? (local.statusLabel ?? CHAIN_OF_THOUGHT_STATUS_LABELS[local.status])
|
|
102
|
+
: undefined
|
|
103
|
+
}
|
|
104
|
+
defaultOpen={local.defaultOpen ?? true}
|
|
105
|
+
{...rest}
|
|
106
|
+
/>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Evidence for a step: the sources it searched, as a wrapping row of badges. */
|
|
111
|
+
export function ChainOfThoughtResults(props: ComponentProps<'ul'>) {
|
|
112
|
+
const [local, rest] = splitProps(props, ['class', 'children'])
|
|
113
|
+
return (
|
|
114
|
+
<ul
|
|
115
|
+
role="list"
|
|
116
|
+
data-slot="chain-of-thought-results"
|
|
117
|
+
class={cn('m-0 flex min-w-0 list-none flex-wrap gap-1.5 p-0', local.class)}
|
|
118
|
+
{...rest}
|
|
119
|
+
>
|
|
120
|
+
{local.children}
|
|
121
|
+
</ul>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type ChainOfThoughtResultProps = Omit<ComponentProps<'li'>, 'children'> & {
|
|
126
|
+
/** Rendered as text. A long label truncates and keeps its full text in `title`. */
|
|
127
|
+
label: string
|
|
128
|
+
icon?: JSX.Element
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function ChainOfThoughtResult(props: ChainOfThoughtResultProps) {
|
|
132
|
+
const [local, rest] = splitProps(props, ['class', 'label', 'icon'])
|
|
133
|
+
return (
|
|
134
|
+
<li data-slot="chain-of-thought-result" class={cn('min-w-0 max-w-full', local.class)} {...rest}>
|
|
135
|
+
<Badge variant="outline" class="max-w-full min-w-0" title={local.label}>
|
|
136
|
+
{local.icon}
|
|
137
|
+
<span class="truncate">{local.label}</span>
|
|
138
|
+
</Badge>
|
|
139
|
+
</li>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CHAIN_OF_THOUGHT_STATUS_LABELS,
|
|
3
|
+
ChainOfThought,
|
|
4
|
+
ChainOfThoughtResult,
|
|
5
|
+
ChainOfThoughtResults,
|
|
6
|
+
ChainOfThoughtStep,
|
|
7
|
+
type ChainOfThoughtProps,
|
|
8
|
+
type ChainOfThoughtResultProps,
|
|
9
|
+
type ChainOfThoughtStepProps,
|
|
10
|
+
type ChainOfThoughtStepStatus,
|
|
11
|
+
} from './chain-of-thought'
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { CircleAlert, Info, TriangleAlert } from 'lucide-solid'
|
|
2
|
+
import { Show, splitProps, type ComponentProps, type JSX } from 'solid-js'
|
|
3
|
+
import { Dynamic } from 'solid-js/web'
|
|
4
|
+
import { cn } from '#lib/utils'
|
|
5
|
+
import { cva, type VariantProps } from '#lib/variants'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Chat.
|
|
9
|
+
*
|
|
10
|
+
* The frame a conversation lives in: a header, a strip for things the reader
|
|
11
|
+
* must know before reading anything else, the thread, and the composer. It is a
|
|
12
|
+
* layout and nothing more — the thread is a `MessageScroller`, the input is a
|
|
13
|
+
* composer, and what happens in between is the host's — which is why it takes
|
|
14
|
+
* slots instead of data.
|
|
15
|
+
*
|
|
16
|
+
* ## Why notices have their own row
|
|
17
|
+
*
|
|
18
|
+
* "The connection dropped", "this transcript has a gap", "this session is
|
|
19
|
+
* read-only" are about the whole conversation, not about a turn, and they must
|
|
20
|
+
* not scroll away with the turns. They sit between the header and the thread in
|
|
21
|
+
* their own grid track, so a notice appearing never steals the thread's row and
|
|
22
|
+
* collapses to zero height when there are none. Each notice states its cause in
|
|
23
|
+
* words and carries its own remedy (`action`); one that reports a *change*
|
|
24
|
+
* (`live`) is announced, one that describes a standing condition is not.
|
|
25
|
+
*
|
|
26
|
+
* ## Layout
|
|
27
|
+
*
|
|
28
|
+
* `h-full min-h-0`, so the thread scrolls inside the frame rather than the page
|
|
29
|
+
* growing, and a `min-w-0` track, so a long unbroken token in a turn cannot widen
|
|
30
|
+
* the whole conversation. Nothing here sets a width: the reading column is the
|
|
31
|
+
* turn's, and the composer sets its own measure.
|
|
32
|
+
*/
|
|
33
|
+
export type ChatProps = ComponentProps<'section'> & {
|
|
34
|
+
header?: JSX.Element
|
|
35
|
+
/** `ChatNotice`s. The row collapses when this is empty. */
|
|
36
|
+
notices?: JSX.Element
|
|
37
|
+
/** The composer. */
|
|
38
|
+
composer?: JSX.Element
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function Chat(props: ChatProps) {
|
|
42
|
+
const [local, rest] = splitProps(props, ['class', 'header', 'notices', 'composer', 'children'])
|
|
43
|
+
return (
|
|
44
|
+
<section
|
|
45
|
+
data-slot="chat"
|
|
46
|
+
class={cn(
|
|
47
|
+
'grid h-full min-h-0 min-w-0 grid-cols-[minmax(0,1fr)] grid-rows-[auto_auto_minmax(0,1fr)_auto] bg-background text-foreground',
|
|
48
|
+
local.class
|
|
49
|
+
)}
|
|
50
|
+
{...rest}
|
|
51
|
+
>
|
|
52
|
+
<div class="row-start-1 min-w-0">{local.header}</div>
|
|
53
|
+
<div class="row-start-2 flex min-w-0 flex-col">{local.notices}</div>
|
|
54
|
+
<div class="row-start-3 flex min-h-0 min-w-0 flex-col">{local.children}</div>
|
|
55
|
+
<div class="row-start-4 min-w-0">{local.composer}</div>
|
|
56
|
+
</section>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type ChatHeaderProps = Omit<ComponentProps<'header'>, 'title'> & {
|
|
61
|
+
title: JSX.Element
|
|
62
|
+
/** One line under the title: identity, scope, generation. */
|
|
63
|
+
subtitle?: JSX.Element
|
|
64
|
+
/** The conversation's state in words (a `StatusChip`). */
|
|
65
|
+
status?: JSX.Element
|
|
66
|
+
/** Host actions: rename, archive, hand off. */
|
|
67
|
+
actions?: JSX.Element
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function ChatHeader(props: ChatHeaderProps) {
|
|
71
|
+
const [local, rest] = splitProps(props, ['class', 'title', 'subtitle', 'status', 'actions'])
|
|
72
|
+
return (
|
|
73
|
+
<header
|
|
74
|
+
data-slot="chat-header"
|
|
75
|
+
class={cn(
|
|
76
|
+
'flex min-h-topbar min-w-0 items-center gap-3 border-b border-border px-4 py-2',
|
|
77
|
+
local.class
|
|
78
|
+
)}
|
|
79
|
+
{...rest}
|
|
80
|
+
>
|
|
81
|
+
<div class="flex min-w-0 flex-1 flex-col">
|
|
82
|
+
<h2 class="m-0 truncate text-sm font-semibold tracking-tight">{local.title}</h2>
|
|
83
|
+
<Show when={local.subtitle}>
|
|
84
|
+
<p class="m-0 truncate text-xs text-muted-foreground">{local.subtitle}</p>
|
|
85
|
+
</Show>
|
|
86
|
+
</div>
|
|
87
|
+
<Show when={local.status}>{local.status}</Show>
|
|
88
|
+
<Show when={local.actions}>
|
|
89
|
+
<div class="flex shrink-0 items-center gap-1">{local.actions}</div>
|
|
90
|
+
</Show>
|
|
91
|
+
</header>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const chatNoticeVariants = cva(
|
|
96
|
+
'flex min-w-0 items-start gap-2.5 border-b px-4 py-2 text-sm',
|
|
97
|
+
{
|
|
98
|
+
variants: {
|
|
99
|
+
tone: {
|
|
100
|
+
info: 'border-border bg-muted/40',
|
|
101
|
+
warning: 'border-warning/30 bg-warning-subtle',
|
|
102
|
+
danger: 'border-destructive/30 bg-destructive-subtle',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
defaultVariants: { tone: 'info' },
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
export type ChatNoticeProps = Omit<ComponentProps<'div'>, 'title'> &
|
|
110
|
+
VariantProps<typeof chatNoticeVariants> & {
|
|
111
|
+
title: JSX.Element
|
|
112
|
+
description?: JSX.Element
|
|
113
|
+
/** The remedy: Reconnect, Jump to terminal. */
|
|
114
|
+
action?: JSX.Element
|
|
115
|
+
/** Announce it. Use for a change (connection lost), not a standing condition. */
|
|
116
|
+
live?: 'polite' | 'assertive'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function ChatNotice(props: ChatNoticeProps) {
|
|
120
|
+
const [local, rest] = splitProps(props, [
|
|
121
|
+
'class',
|
|
122
|
+
'tone',
|
|
123
|
+
'title',
|
|
124
|
+
'description',
|
|
125
|
+
'action',
|
|
126
|
+
'live',
|
|
127
|
+
])
|
|
128
|
+
const Glyph = () =>
|
|
129
|
+
local.tone === 'danger' ? CircleAlert : local.tone === 'warning' ? TriangleAlert : Info
|
|
130
|
+
return (
|
|
131
|
+
<div
|
|
132
|
+
data-slot="chat-notice"
|
|
133
|
+
role={local.live === 'assertive' ? 'alert' : local.live === 'polite' ? 'status' : undefined}
|
|
134
|
+
class={cn(chatNoticeVariants({ tone: local.tone }), local.class)}
|
|
135
|
+
{...rest}
|
|
136
|
+
>
|
|
137
|
+
<span
|
|
138
|
+
aria-hidden="true"
|
|
139
|
+
class={cn('mt-0.5 shrink-0 [&_svg]:size-4', {
|
|
140
|
+
'text-muted-foreground': (local.tone ?? 'info') === 'info',
|
|
141
|
+
'text-warning': local.tone === 'warning',
|
|
142
|
+
'text-destructive': local.tone === 'danger',
|
|
143
|
+
})}
|
|
144
|
+
>
|
|
145
|
+
<Dynamic component={Glyph()} />
|
|
146
|
+
</span>
|
|
147
|
+
<div class="min-w-0 flex-1">
|
|
148
|
+
<p class="m-0 font-medium [overflow-wrap:anywhere]">{local.title}</p>
|
|
149
|
+
<Show when={local.description}>
|
|
150
|
+
<p class="m-0 text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
151
|
+
{local.description}
|
|
152
|
+
</p>
|
|
153
|
+
</Show>
|
|
154
|
+
</div>
|
|
155
|
+
<Show when={local.action}>
|
|
156
|
+
<div class="flex shrink-0 items-center gap-1.5">{local.action}</div>
|
|
157
|
+
</Show>
|
|
158
|
+
</div>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export type ChatEmptyProps = Omit<ComponentProps<'div'>, 'title'> & {
|
|
163
|
+
title: JSX.Element
|
|
164
|
+
description?: JSX.Element
|
|
165
|
+
/** Prompt chips (`Suggestions`), shown only when the host has real ones. */
|
|
166
|
+
suggestions?: JSX.Element
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** A conversation with no turns yet. Centred in the thread, never in a card. */
|
|
170
|
+
export function ChatEmpty(props: ChatEmptyProps) {
|
|
171
|
+
const [local, rest] = splitProps(props, ['class', 'title', 'description', 'suggestions'])
|
|
172
|
+
return (
|
|
173
|
+
<div
|
|
174
|
+
data-slot="chat-empty"
|
|
175
|
+
class={cn(
|
|
176
|
+
'mx-auto flex min-h-full w-full max-w-xl flex-col items-center justify-center gap-4 px-6 py-10 text-center',
|
|
177
|
+
local.class
|
|
178
|
+
)}
|
|
179
|
+
{...rest}
|
|
180
|
+
>
|
|
181
|
+
<div class="flex flex-col gap-1">
|
|
182
|
+
<h3 class="m-0 text-base font-semibold tracking-tight text-balance">{local.title}</h3>
|
|
183
|
+
<Show when={local.description}>
|
|
184
|
+
<p class="m-0 text-sm text-muted-foreground text-balance">{local.description}</p>
|
|
185
|
+
</Show>
|
|
186
|
+
</div>
|
|
187
|
+
<Show when={local.suggestions}>{local.suggestions}</Show>
|
|
188
|
+
</div>
|
|
189
|
+
)
|
|
190
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { boundText } from '../sources/source'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Where a restore stands. `idle` is the resting state of a checkpoint that has
|
|
5
|
+
* not been restored from; the other three are only ever set because something
|
|
6
|
+
* happened — the host passes them, or the component sets them from the promise
|
|
7
|
+
* `onRestore` returned.
|
|
8
|
+
*/
|
|
9
|
+
export type CheckpointState = 'idle' | 'restoring' | 'restored' | 'failed'
|
|
10
|
+
|
|
11
|
+
/** The checkpoint's name as drawn; a blank label is the honest generic word. */
|
|
12
|
+
export function checkpointLabel(label: string | undefined): string {
|
|
13
|
+
return (label ? boundText(label, 80) : '') || 'Checkpoint'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The sentence for the status region. `idle` says nothing, because a
|
|
18
|
+
* checkpoint that has not been touched makes no statement. A failure carries the
|
|
19
|
+
* host's text when there is one.
|
|
20
|
+
*/
|
|
21
|
+
export function checkpointStatus(
|
|
22
|
+
state: CheckpointState,
|
|
23
|
+
error?: string,
|
|
24
|
+
disabledReason?: string
|
|
25
|
+
): string | undefined {
|
|
26
|
+
switch (state) {
|
|
27
|
+
case 'restoring':
|
|
28
|
+
return 'Restoring…'
|
|
29
|
+
case 'restored':
|
|
30
|
+
return 'Restored'
|
|
31
|
+
case 'failed': {
|
|
32
|
+
const detail = error ? boundText(error, 240) : ''
|
|
33
|
+
return detail ? `Restore failed: ${detail}` : 'Restore failed'
|
|
34
|
+
}
|
|
35
|
+
case 'idle':
|
|
36
|
+
return disabledReason ? boundText(disabledReason, 240) : undefined
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The confirmation dialog's words. The host's `consequence` is what actually
|
|
42
|
+
* names what will change, so it is used verbatim (bounded); without one the dialog
|
|
43
|
+
* says only what a restore always means and does not guess at the rest.
|
|
44
|
+
*/
|
|
45
|
+
export function restoreDialogCopy(
|
|
46
|
+
label: string | undefined,
|
|
47
|
+
consequence: string | undefined
|
|
48
|
+
): { title: string; description: string } {
|
|
49
|
+
return {
|
|
50
|
+
title: `Restore to “${checkpointLabel(label)}”?`,
|
|
51
|
+
description: consequence
|
|
52
|
+
? boundText(consequence, 400)
|
|
53
|
+
: 'Restoring returns to this checkpoint.',
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether the Restore control exists, and whether it can be used. It exists only
|
|
59
|
+
* when the host passed a handler — a checkpoint that cannot be restored must not
|
|
60
|
+
* look as if it can — and goes once the restore has succeeded.
|
|
61
|
+
*/
|
|
62
|
+
export function restoreControl(
|
|
63
|
+
hasHandler: boolean,
|
|
64
|
+
state: CheckpointState,
|
|
65
|
+
disabledReason: string | undefined
|
|
66
|
+
): { visible: boolean; disabled: boolean } {
|
|
67
|
+
return {
|
|
68
|
+
visible: hasHandler && state !== 'restored',
|
|
69
|
+
disabled: state === 'restoring' || disabledReason !== undefined,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { Flag } from 'lucide-solid'
|
|
2
|
+
import {
|
|
3
|
+
createEffect,
|
|
4
|
+
createMemo,
|
|
5
|
+
createSignal,
|
|
6
|
+
createUniqueId,
|
|
7
|
+
on,
|
|
8
|
+
Show,
|
|
9
|
+
splitProps,
|
|
10
|
+
type ComponentProps,
|
|
11
|
+
} from 'solid-js'
|
|
12
|
+
import { cn } from '#lib/utils'
|
|
13
|
+
import { Button } from '../../ui/button'
|
|
14
|
+
import {
|
|
15
|
+
AlertDialog,
|
|
16
|
+
AlertDialogAction,
|
|
17
|
+
AlertDialogCancel,
|
|
18
|
+
AlertDialogContent,
|
|
19
|
+
AlertDialogDescription,
|
|
20
|
+
AlertDialogFooter,
|
|
21
|
+
AlertDialogHeader,
|
|
22
|
+
AlertDialogTitle,
|
|
23
|
+
AlertDialogTrigger,
|
|
24
|
+
} from '../../ui/alert-dialog'
|
|
25
|
+
import { Marker } from '../../ui/marker'
|
|
26
|
+
import { Spinner } from '../../ui/spinner'
|
|
27
|
+
import { settleDecision } from '../confirmation/confirmation-model'
|
|
28
|
+
import { boundText } from '../sources/source'
|
|
29
|
+
import {
|
|
30
|
+
checkpointLabel,
|
|
31
|
+
checkpointStatus,
|
|
32
|
+
restoreControl,
|
|
33
|
+
restoreDialogCopy,
|
|
34
|
+
type CheckpointState,
|
|
35
|
+
} from './checkpoint-model'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Checkpoint.
|
|
39
|
+
*
|
|
40
|
+
* A point in the conversation the host can name: a divider in the transcript with
|
|
41
|
+
* a label and a time. It always renders — as a `Marker`, the quietest thing in the
|
|
42
|
+
* column — and it is honest about what it is:
|
|
43
|
+
*
|
|
44
|
+
* - **Without `onRestore` it is only a marker.** Not a disabled button, not a
|
|
45
|
+
* greyed-out "Restore": nothing. Whether a checkpoint can be returned to is a
|
|
46
|
+
* fact about the host's storage and permissions, and a control that implies it
|
|
47
|
+
* can would be a claim nobody made.
|
|
48
|
+
* - **With `onRestore` it offers Restore, and Restore asks first.** An
|
|
49
|
+
* `AlertDialog` (Escape and the scrim do nothing; every exit is a named choice)
|
|
50
|
+
* states what will change in the host's own words (`consequence`) before the
|
|
51
|
+
* handler is called. A restore throws work away; the confirmation is the point.
|
|
52
|
+
*
|
|
53
|
+
* ## States
|
|
54
|
+
*
|
|
55
|
+
* `idle` → `restoring` → `restored`, or `failed` with `error`. Pass `state` to
|
|
56
|
+
* drive it from the host; omit it and the component follows the promise
|
|
57
|
+
* `onRestore` returns. The status sentence is a live region that exists from the
|
|
58
|
+
* start, so a change is announced. While restoring, the control stays focusable
|
|
59
|
+
* (`aria-disabled`, not `disabled`) so focus is not dropped when the dialog hands
|
|
60
|
+
* it back; once restored the control goes and focus moves to the status line.
|
|
61
|
+
*
|
|
62
|
+
* A restore that cannot happen now takes `disabledReason`, shown in words under
|
|
63
|
+
* the divider; the host decides, the component explains.
|
|
64
|
+
*/
|
|
65
|
+
export type CheckpointProps = Omit<ComponentProps<'div'>, 'children' | 'onError'> & {
|
|
66
|
+
/** The checkpoint's name. Defaults to "Checkpoint". */
|
|
67
|
+
label?: string
|
|
68
|
+
/** When it was taken, already formatted for the reader. */
|
|
69
|
+
time?: string
|
|
70
|
+
state?: CheckpointState
|
|
71
|
+
/** Supplying this is what makes the checkpoint restorable. */
|
|
72
|
+
onRestore?: () => void | Promise<void>
|
|
73
|
+
/** What restoring will change, in the host's words. Shown in the confirmation. */
|
|
74
|
+
consequence?: string
|
|
75
|
+
restoreLabel?: string
|
|
76
|
+
/** Why Restore cannot be used right now. */
|
|
77
|
+
disabledReason?: string
|
|
78
|
+
/** Why a restore failed. */
|
|
79
|
+
error?: string
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function Checkpoint(props: CheckpointProps) {
|
|
83
|
+
const [local, rest] = splitProps(props, [
|
|
84
|
+
'class',
|
|
85
|
+
'label',
|
|
86
|
+
'time',
|
|
87
|
+
'state',
|
|
88
|
+
'onRestore',
|
|
89
|
+
'consequence',
|
|
90
|
+
'restoreLabel',
|
|
91
|
+
'disabledReason',
|
|
92
|
+
'error',
|
|
93
|
+
])
|
|
94
|
+
const uid = createUniqueId()
|
|
95
|
+
const reasonId = `${uid}-status`
|
|
96
|
+
const [followed, setFollowed] = createSignal<CheckpointState>('idle')
|
|
97
|
+
const [failure, setFailure] = createSignal<string | undefined>(undefined)
|
|
98
|
+
const [confirming, setConfirming] = createSignal(false)
|
|
99
|
+
let inflight = false
|
|
100
|
+
let root: HTMLDivElement | undefined
|
|
101
|
+
let status: HTMLParagraphElement | undefined
|
|
102
|
+
|
|
103
|
+
const state = (): CheckpointState => local.state ?? followed()
|
|
104
|
+
const error = () => local.error ?? failure()
|
|
105
|
+
const control = () => restoreControl(local.onRestore !== undefined, state(), local.disabledReason)
|
|
106
|
+
const copy = () => restoreDialogCopy(local.label, local.consequence)
|
|
107
|
+
const statusText = () => checkpointStatus(state(), error(), local.disabledReason)
|
|
108
|
+
|
|
109
|
+
const restore = async () => {
|
|
110
|
+
if (inflight || control().disabled) return
|
|
111
|
+
inflight = true
|
|
112
|
+
setFailure(undefined)
|
|
113
|
+
setFollowed('restoring')
|
|
114
|
+
const result = await settleDecision(local.onRestore)
|
|
115
|
+
inflight = false
|
|
116
|
+
if (result.ok) {
|
|
117
|
+
setFollowed('restored')
|
|
118
|
+
} else {
|
|
119
|
+
setFailure(result.message)
|
|
120
|
+
setFollowed('failed')
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// The control is replaced by the status line on success; do not strand focus.
|
|
125
|
+
createEffect(
|
|
126
|
+
on(
|
|
127
|
+
() => state() === 'restored',
|
|
128
|
+
(restored) => {
|
|
129
|
+
if (!restored) return
|
|
130
|
+
const active = document.activeElement
|
|
131
|
+
if (active === null || active === document.body || root?.contains(active)) {
|
|
132
|
+
status?.focus()
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{ defer: true }
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
// Built once. `Marker` reads `action` twice (to test it, then to draw it), and a
|
|
140
|
+
// JSX prop re-creates its component on every read: a second AlertDialog root
|
|
141
|
+
// would portal a second, invisible-to-the-tree dialog when this one opens.
|
|
142
|
+
const restoreAction = createMemo(() => (
|
|
143
|
+
<Show when={control().visible}>
|
|
144
|
+
<AlertDialog
|
|
145
|
+
open={confirming()}
|
|
146
|
+
onOpenChange={(open) => setConfirming(open && !control().disabled)}
|
|
147
|
+
>
|
|
148
|
+
<AlertDialogTrigger
|
|
149
|
+
as={Button}
|
|
150
|
+
variant="ghost"
|
|
151
|
+
size="2xs"
|
|
152
|
+
aria-disabled={control().disabled || undefined}
|
|
153
|
+
aria-describedby={statusText() ? reasonId : undefined}
|
|
154
|
+
>
|
|
155
|
+
<Show when={state() === 'restoring'}>
|
|
156
|
+
<Spinner size="xs" label={false} />
|
|
157
|
+
</Show>
|
|
158
|
+
{state() === 'restoring'
|
|
159
|
+
? 'Restoring…'
|
|
160
|
+
: (local.restoreLabel ?? (state() === 'failed' ? 'Try again' : 'Restore'))}
|
|
161
|
+
</AlertDialogTrigger>
|
|
162
|
+
<AlertDialogContent>
|
|
163
|
+
<AlertDialogHeader>
|
|
164
|
+
<AlertDialogTitle>{copy().title}</AlertDialogTitle>
|
|
165
|
+
<AlertDialogDescription class="[overflow-wrap:anywhere]">
|
|
166
|
+
{copy().description}
|
|
167
|
+
</AlertDialogDescription>
|
|
168
|
+
</AlertDialogHeader>
|
|
169
|
+
<AlertDialogFooter>
|
|
170
|
+
<AlertDialogCancel as={Button} variant="ghost">
|
|
171
|
+
Do not restore
|
|
172
|
+
</AlertDialogCancel>
|
|
173
|
+
<AlertDialogAction as={Button} onClick={() => void restore()}>
|
|
174
|
+
{local.restoreLabel ?? 'Restore'}
|
|
175
|
+
</AlertDialogAction>
|
|
176
|
+
</AlertDialogFooter>
|
|
177
|
+
</AlertDialogContent>
|
|
178
|
+
</AlertDialog>
|
|
179
|
+
</Show>
|
|
180
|
+
))
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div
|
|
184
|
+
ref={(element) => (root = element)}
|
|
185
|
+
data-slot="checkpoint"
|
|
186
|
+
data-state={state()}
|
|
187
|
+
class={local.class}
|
|
188
|
+
{...rest}
|
|
189
|
+
>
|
|
190
|
+
<Marker
|
|
191
|
+
variant="rule"
|
|
192
|
+
icon={<Flag />}
|
|
193
|
+
tone={state() === 'failed' ? 'danger' : 'neutral'}
|
|
194
|
+
label={checkpointLabel(local.label)}
|
|
195
|
+
description={local.time ? boundText(local.time, 60) : undefined}
|
|
196
|
+
action={restoreAction()}
|
|
197
|
+
/>
|
|
198
|
+
{/* Always present, so a state change is a change to a live region rather than
|
|
199
|
+
the arrival of one. Empty while idle, which takes no space. */}
|
|
200
|
+
<p
|
|
201
|
+
id={reasonId}
|
|
202
|
+
ref={(element) => (status = element)}
|
|
203
|
+
role="status"
|
|
204
|
+
tabindex="-1"
|
|
205
|
+
class={cn('m-0 text-center text-xs outline-none [overflow-wrap:anywhere]', {
|
|
206
|
+
'text-destructive': state() === 'failed',
|
|
207
|
+
'text-muted-foreground': state() !== 'failed',
|
|
208
|
+
})}
|
|
209
|
+
>
|
|
210
|
+
{statusText()}
|
|
211
|
+
</p>
|
|
212
|
+
</div>
|
|
213
|
+
)
|
|
214
|
+
}
|