@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,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping the reader's place when content appears above them.
|
|
3
|
+
*
|
|
4
|
+
* The browser's own scroll anchoring does this in some engines for some DOM
|
|
5
|
+
* shapes and not in others (and not at all with `content-visibility`), so it is
|
|
6
|
+
* done explicitly. What is remembered is where the turns around the viewport sit
|
|
7
|
+
* in the document (their distance from the top of the content, which scrolling
|
|
8
|
+
* does not change). After the content moves, the turn the reader is on is found
|
|
9
|
+
* again and the scroll offset is moved by however far it moved in the document, so
|
|
10
|
+
* it sits where it did in the viewport.
|
|
11
|
+
*
|
|
12
|
+
* Only the *content's* movement is undone, because the reader's scrolling does not
|
|
13
|
+
* move a turn in the document. A reader who scrolls while a load is open (a wheel
|
|
14
|
+
* fling or touch momentum that was still running when the load began) keeps the
|
|
15
|
+
* scroll: nothing is restored to an offset captured earlier.
|
|
16
|
+
*
|
|
17
|
+
* It is the turn the reader was on that is measured, found from where the turns sat
|
|
18
|
+
* when the marks were taken and not from where the change has left them: a row above
|
|
19
|
+
* the reader that grows far enough to reach into the view has not become the turn they
|
|
20
|
+
* are reading, and the turn they are reading has moved down by the growth. Nothing
|
|
21
|
+
* below that turn counts: a row further down that sizes itself late (an
|
|
22
|
+
* image, highlighted code, a row leaving `content-visibility`) moves rows below the
|
|
23
|
+
* reader, not the reader. The turns above the reader count, because they are what
|
|
24
|
+
* an insert or a late resize above pushes the view down by.
|
|
25
|
+
*/
|
|
26
|
+
export type ScrollAnchor = {
|
|
27
|
+
/** `data-anchor-id` of the first turn in view when the marks were taken, if any turn has one. */
|
|
28
|
+
id: string | undefined
|
|
29
|
+
/**
|
|
30
|
+
* The document position (px from the top of the content) of the turns around the
|
|
31
|
+
* viewport when the marks were taken, by id: a few above the first one in view, it, and
|
|
32
|
+
* some below. Empty when no turn carries an id.
|
|
33
|
+
*/
|
|
34
|
+
marks: Map<string, number>
|
|
35
|
+
/** The document position of the bottom edge of each marked turn, when the marks were taken. */
|
|
36
|
+
ends: Map<string, number>
|
|
37
|
+
/** Fallback when no turn carries an id: the scroll height at the last restore. */
|
|
38
|
+
scrollHeight: number
|
|
39
|
+
/** The scroll offset at the last restore. */
|
|
40
|
+
scrollTop: number
|
|
41
|
+
/**
|
|
42
|
+
* When set, only these turns are marked: the ones that were there when the load began.
|
|
43
|
+
* A turn that has just landed is still at its estimated height, so a correction taken
|
|
44
|
+
* from it would come from a row about to resize.
|
|
45
|
+
*/
|
|
46
|
+
known?: ReadonlySet<string>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const ANCHOR_ATTRIBUTE = 'data-anchor-id'
|
|
50
|
+
|
|
51
|
+
/** Turns marked above the first one in view, and below it. */
|
|
52
|
+
const MARKS_ABOVE = 8
|
|
53
|
+
const MARKS_BELOW = 12
|
|
54
|
+
|
|
55
|
+
/** The ids of the turns in the scroller now. */
|
|
56
|
+
export function anchorIds(scroller: HTMLElement): Set<string> {
|
|
57
|
+
const ids = new Set<string>()
|
|
58
|
+
for (const element of scroller.querySelectorAll<HTMLElement>(`[${ANCHOR_ATTRIBUTE}]`))
|
|
59
|
+
ids.add(element.getAttribute(ANCHOR_ATTRIBUTE)!)
|
|
60
|
+
return ids
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Mark the turns around the viewport: where each sits in the document now. */
|
|
64
|
+
export function captureAnchor(scroller: HTMLElement, known?: ReadonlySet<string>): ScrollAnchor {
|
|
65
|
+
const box = scroller.getBoundingClientRect()
|
|
66
|
+
const scrollTop = scroller.scrollTop
|
|
67
|
+
const marks = new Map<string, number>()
|
|
68
|
+
const ends = new Map<string, number>()
|
|
69
|
+
const above: Array<[string, number, number]> = []
|
|
70
|
+
let id: string | undefined
|
|
71
|
+
let below = 0
|
|
72
|
+
for (const element of scroller.querySelectorAll<HTMLElement>(`[${ANCHOR_ATTRIBUTE}]`)) {
|
|
73
|
+
const turn = element.getAttribute(ANCHOR_ATTRIBUTE)!
|
|
74
|
+
if (known && !known.has(turn)) continue
|
|
75
|
+
const rect = element.getBoundingClientRect()
|
|
76
|
+
const position = rect.top - box.top + scrollTop
|
|
77
|
+
const end = rect.bottom - box.top + scrollTop
|
|
78
|
+
if (id === undefined) {
|
|
79
|
+
if (rect.bottom > box.top) {
|
|
80
|
+
id = turn
|
|
81
|
+
for (const [earlier, where, bottom] of above) {
|
|
82
|
+
marks.set(earlier, where)
|
|
83
|
+
ends.set(earlier, bottom)
|
|
84
|
+
}
|
|
85
|
+
marks.set(turn, position)
|
|
86
|
+
ends.set(turn, end)
|
|
87
|
+
} else {
|
|
88
|
+
above.push([turn, position, end])
|
|
89
|
+
if (above.length > MARKS_ABOVE) above.shift()
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
marks.set(turn, position)
|
|
93
|
+
ends.set(turn, end)
|
|
94
|
+
below += 1
|
|
95
|
+
if (below >= MARKS_BELOW) break
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { id, marks, ends, scrollHeight: scroller.scrollHeight, scrollTop }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The marked turn the reader is on and where it sits in the document now. The turn is
|
|
103
|
+
* chosen by where the marked turns were (the first one that reached into the view at the
|
|
104
|
+
* scroll offset now, or the last one if every marked turn was above it), among those still
|
|
105
|
+
* in the scroller; its position is read from where the content has put it.
|
|
106
|
+
*/
|
|
107
|
+
function turnInView(
|
|
108
|
+
scroller: HTMLElement,
|
|
109
|
+
anchor: ScrollAnchor
|
|
110
|
+
): { id: string; position: number } | undefined {
|
|
111
|
+
const box = scroller.getBoundingClientRect()
|
|
112
|
+
const scrollTop = scroller.scrollTop
|
|
113
|
+
const present = new Map<string, number>()
|
|
114
|
+
for (const element of scroller.querySelectorAll<HTMLElement>(`[${ANCHOR_ATTRIBUTE}]`)) {
|
|
115
|
+
const id = element.getAttribute(ANCHOR_ATTRIBUTE)!
|
|
116
|
+
if (anchor.marks.has(id))
|
|
117
|
+
present.set(id, element.getBoundingClientRect().top - box.top + scrollTop)
|
|
118
|
+
}
|
|
119
|
+
let last: { id: string; position: number } | undefined
|
|
120
|
+
for (const id of anchor.marks.keys()) {
|
|
121
|
+
const position = present.get(id)
|
|
122
|
+
if (position === undefined) continue
|
|
123
|
+
last = { id, position }
|
|
124
|
+
if ((anchor.ends.get(id) ?? Infinity) > scrollTop) return last
|
|
125
|
+
}
|
|
126
|
+
return last
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Put the reader back where the content's movement left them. Returns the correction
|
|
131
|
+
* applied, in px.
|
|
132
|
+
*
|
|
133
|
+
* The turn the reader is on is found among the marked turns, and the scroll offset is
|
|
134
|
+
* moved by how far that turn has moved in the document since the marks were taken: an
|
|
135
|
+
* insert or a late resize above it moves it, scrolling and growth below it do not.
|
|
136
|
+
* The marks are then taken again around wherever the reader now is, so a second restore
|
|
137
|
+
* after the same change finds nothing left to correct, and a reader who has moved on
|
|
138
|
+
* (before this call, in the same task as a change, or by a scroll event that has not
|
|
139
|
+
* yet arrived) is measured from the turn they are on and not from one they have left.
|
|
140
|
+
* Nothing here depends on seeing the scroll event first.
|
|
141
|
+
*/
|
|
142
|
+
export function restoreAnchor(scroller: HTMLElement, anchor: ScrollAnchor | undefined): number {
|
|
143
|
+
if (!anchor) return 0
|
|
144
|
+
let correction = 0
|
|
145
|
+
if (anchor.marks.size > 0) {
|
|
146
|
+
const turn = turnInView(scroller, anchor)
|
|
147
|
+
if (turn) correction = turn.position - anchor.marks.get(turn.id)!
|
|
148
|
+
} else if (anchor.id === undefined) {
|
|
149
|
+
// No turn carries an id: the growth since the last restore is added to where the
|
|
150
|
+
// reader is, so a second restore after the same insert (the observer and the settle
|
|
151
|
+
// both run one) finds it already applied, and growth that lands later moves the
|
|
152
|
+
// reader only by what is still missing.
|
|
153
|
+
correction = scroller.scrollHeight - anchor.scrollHeight
|
|
154
|
+
}
|
|
155
|
+
if (Math.abs(correction) >= 1) scroller.scrollTop += correction
|
|
156
|
+
const next = captureAnchor(scroller, anchor.known)
|
|
157
|
+
if (next.marks.size > 0 || anchor.marks.size === 0) {
|
|
158
|
+
anchor.id = next.id
|
|
159
|
+
anchor.marks = next.marks
|
|
160
|
+
anchor.ends = next.ends
|
|
161
|
+
} else {
|
|
162
|
+
// None of the turns that were there before the load is in view (the reader is among
|
|
163
|
+
// the rows that landed): keep the old marks, moved by what the content did.
|
|
164
|
+
for (const [id, position] of anchor.marks) anchor.marks.set(id, position + correction)
|
|
165
|
+
for (const [id, end] of anchor.ends) anchor.ends.set(id, end + correction)
|
|
166
|
+
}
|
|
167
|
+
anchor.scrollTop = scroller.scrollTop
|
|
168
|
+
anchor.scrollHeight = scroller.scrollHeight
|
|
169
|
+
return correction
|
|
170
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { ModelSelector, type ModelSelectorProps } from './model-selector'
|
|
2
|
+
export {
|
|
3
|
+
findModel,
|
|
4
|
+
groupModels,
|
|
5
|
+
modelSearchValue,
|
|
6
|
+
MODEL_SEARCH_THRESHOLD,
|
|
7
|
+
needsSearch,
|
|
8
|
+
normalizeEfforts,
|
|
9
|
+
resolveEffort,
|
|
10
|
+
type EffortOption,
|
|
11
|
+
type ModelEffort,
|
|
12
|
+
type ModelGroup,
|
|
13
|
+
type ModelOption,
|
|
14
|
+
} from './models'
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { Brain, Check, ChevronsUpDown } from 'lucide-solid'
|
|
2
|
+
import {
|
|
3
|
+
createEffect,
|
|
4
|
+
createMemo,
|
|
5
|
+
createSignal,
|
|
6
|
+
createUniqueId,
|
|
7
|
+
For,
|
|
8
|
+
Show,
|
|
9
|
+
splitProps,
|
|
10
|
+
} from 'solid-js'
|
|
11
|
+
import { cn } from '#lib/utils'
|
|
12
|
+
import { Button } from '../../ui/button'
|
|
13
|
+
import {
|
|
14
|
+
Command,
|
|
15
|
+
CommandEmpty,
|
|
16
|
+
CommandGroup,
|
|
17
|
+
CommandInput,
|
|
18
|
+
CommandItem,
|
|
19
|
+
CommandList,
|
|
20
|
+
} from '../../ui/command'
|
|
21
|
+
import {
|
|
22
|
+
DropdownMenu,
|
|
23
|
+
DropdownMenuContent,
|
|
24
|
+
DropdownMenuGroup,
|
|
25
|
+
DropdownMenuLabel,
|
|
26
|
+
DropdownMenuRadioGroup,
|
|
27
|
+
DropdownMenuRadioItem,
|
|
28
|
+
DropdownMenuTrigger,
|
|
29
|
+
} from '../../ui/dropdown-menu'
|
|
30
|
+
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover'
|
|
31
|
+
import { boundText } from '../sources/source'
|
|
32
|
+
import {
|
|
33
|
+
findModel,
|
|
34
|
+
groupModels,
|
|
35
|
+
modelSearchValue,
|
|
36
|
+
needsSearch,
|
|
37
|
+
normalizeEfforts,
|
|
38
|
+
resolveEffort,
|
|
39
|
+
type ModelOption,
|
|
40
|
+
} from './models'
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ModelSelector.
|
|
44
|
+
*
|
|
45
|
+
* Two controls in one group beside the composer: *which model*, and *how hard it
|
|
46
|
+
* thinks*. They are one component because the second depends on the first — an
|
|
47
|
+
* effort level belongs to a model, and switching model can make the chosen effort
|
|
48
|
+
* meaningless — so a host should not have to keep two menus consistent by hand.
|
|
49
|
+
*
|
|
50
|
+
* ## What it takes and what it will not decide
|
|
51
|
+
*
|
|
52
|
+
* `models` carries each option's provider, optional description and optional
|
|
53
|
+
* `disabledReason`; `value` and `effort` are the current choice; `onChange` and
|
|
54
|
+
* `onEffortChange` report a new one. The component holds no selection of its own
|
|
55
|
+
* (the host may veto, persist or reset it) and never decides what is allowed:
|
|
56
|
+
*
|
|
57
|
+
* - **An unavailable model stays in the list**, disabled, with the host's reason
|
|
58
|
+
* beside it in words. Hiding it would leave the person guessing where it went.
|
|
59
|
+
* - **No `onChange`, no menu.** The model is then plain text — a read-only
|
|
60
|
+
* statement of what is running — not a button that does nothing. The same holds
|
|
61
|
+
* for effort and `onEffortChange`.
|
|
62
|
+
* - **Effort renders only when the selected model advertises `efforts`.** A model
|
|
63
|
+
* that does not has no effort control, and a stored `effort` the model does not
|
|
64
|
+
* offer is shown as unset rather than as a level the model never had.
|
|
65
|
+
* - **A `value` that is not in the list is shown as given**, not swapped for a
|
|
66
|
+
* model the person did not choose.
|
|
67
|
+
* - `disabledReason` disables both and says why under the group.
|
|
68
|
+
*
|
|
69
|
+
* ## Short list or long
|
|
70
|
+
*
|
|
71
|
+
* Up to `searchThreshold` models (7) the model picker is a `DropdownMenu` with
|
|
72
|
+
* radio rows grouped by provider: arrows, typeahead and Escape come from the menu
|
|
73
|
+
* contract. Beyond it the list is a `Popover` holding a `Command` palette with a
|
|
74
|
+
* search box, because scanning thirty rows is slower than typing four letters.
|
|
75
|
+
* Both close on choice and return focus to the trigger. Triggers use
|
|
76
|
+
* `aria-disabled` so a blocked control is still reachable and its reason read.
|
|
77
|
+
*/
|
|
78
|
+
export type ModelSelectorProps = {
|
|
79
|
+
models: readonly ModelOption[]
|
|
80
|
+
/** The selected model's id. */
|
|
81
|
+
value?: string
|
|
82
|
+
/** The selected effort's id. */
|
|
83
|
+
effort?: string
|
|
84
|
+
onChange?: (id: string) => void
|
|
85
|
+
onEffortChange?: (effort: string) => void
|
|
86
|
+
/** Show a search box above this many models. Default 7. */
|
|
87
|
+
searchThreshold?: number
|
|
88
|
+
/** Why neither control can be used right now. */
|
|
89
|
+
disabledReason?: string
|
|
90
|
+
/** The group's accessible name. */
|
|
91
|
+
label?: string
|
|
92
|
+
class?: string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function ModelSelector(props: ModelSelectorProps) {
|
|
96
|
+
const [local] = splitProps(props, [
|
|
97
|
+
'models',
|
|
98
|
+
'value',
|
|
99
|
+
'effort',
|
|
100
|
+
'onChange',
|
|
101
|
+
'onEffortChange',
|
|
102
|
+
'searchThreshold',
|
|
103
|
+
'disabledReason',
|
|
104
|
+
'label',
|
|
105
|
+
'class',
|
|
106
|
+
])
|
|
107
|
+
const blocked = () => local.disabledReason !== undefined
|
|
108
|
+
const selected = () => findModel(local.models, local.value)
|
|
109
|
+
const efforts = createMemo(() => normalizeEfforts(selected()?.efforts))
|
|
110
|
+
const effortChoice = () => resolveEffort(selected(), local.effort)
|
|
111
|
+
const reason = () => (local.disabledReason ? boundText(local.disabledReason, 240) : undefined)
|
|
112
|
+
const reasonId = `${createUniqueId()}-reason`
|
|
113
|
+
const describedBy = () => (reason() ? reasonId : undefined)
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<div data-slot="model-selector" class={cn('flex min-w-0 flex-col gap-1', local.class)}>
|
|
117
|
+
<div
|
|
118
|
+
role="group"
|
|
119
|
+
aria-label={local.label ?? 'Model and thinking effort'}
|
|
120
|
+
class="flex min-w-0 items-center gap-1"
|
|
121
|
+
>
|
|
122
|
+
<Show
|
|
123
|
+
when={local.onChange}
|
|
124
|
+
fallback={
|
|
125
|
+
<Show when={local.value}>
|
|
126
|
+
<span class="truncate px-2 text-sm text-muted-foreground">
|
|
127
|
+
<span class="visually-hidden">Model: </span>
|
|
128
|
+
{triggerText({ selected: selected(), value: local.value })}
|
|
129
|
+
</span>
|
|
130
|
+
</Show>
|
|
131
|
+
}
|
|
132
|
+
>
|
|
133
|
+
<Show
|
|
134
|
+
when={needsSearch(local.models.length, local.searchThreshold)}
|
|
135
|
+
fallback={
|
|
136
|
+
<ModelMenu
|
|
137
|
+
models={local.models}
|
|
138
|
+
selected={selected()}
|
|
139
|
+
value={local.value}
|
|
140
|
+
blocked={blocked()}
|
|
141
|
+
describedBy={describedBy()}
|
|
142
|
+
onChange={(id) => local.onChange?.(id)}
|
|
143
|
+
/>
|
|
144
|
+
}
|
|
145
|
+
>
|
|
146
|
+
<ModelSearch
|
|
147
|
+
models={local.models}
|
|
148
|
+
selected={selected()}
|
|
149
|
+
value={local.value}
|
|
150
|
+
blocked={blocked()}
|
|
151
|
+
describedBy={describedBy()}
|
|
152
|
+
onChange={(id) => local.onChange?.(id)}
|
|
153
|
+
/>
|
|
154
|
+
</Show>
|
|
155
|
+
</Show>
|
|
156
|
+
<Show when={efforts().length > 0}>
|
|
157
|
+
<Show
|
|
158
|
+
when={local.onEffortChange}
|
|
159
|
+
fallback={
|
|
160
|
+
<Show when={effortChoice()}>
|
|
161
|
+
{(choice) => (
|
|
162
|
+
<span class="flex items-center gap-1 truncate px-2 text-sm text-muted-foreground">
|
|
163
|
+
<Brain aria-hidden="true" class="size-3.5 shrink-0" />
|
|
164
|
+
<span class="visually-hidden">Thinking effort: </span>
|
|
165
|
+
{choice().label}
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
168
|
+
</Show>
|
|
169
|
+
}
|
|
170
|
+
>
|
|
171
|
+
<EffortMenu
|
|
172
|
+
efforts={efforts()}
|
|
173
|
+
value={effortChoice()?.id}
|
|
174
|
+
blocked={blocked()}
|
|
175
|
+
describedBy={describedBy()}
|
|
176
|
+
onChange={(id) => local.onEffortChange?.(id)}
|
|
177
|
+
/>
|
|
178
|
+
</Show>
|
|
179
|
+
</Show>
|
|
180
|
+
</div>
|
|
181
|
+
<Show when={reason()}>
|
|
182
|
+
<p id={reasonId} role="status" class="m-0 text-xs text-muted-foreground">
|
|
183
|
+
{reason()}
|
|
184
|
+
</p>
|
|
185
|
+
</Show>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function triggerText(props: { selected?: ModelOption; value?: string }): string {
|
|
191
|
+
if (props.selected) return boundText(props.selected.label, 60)
|
|
192
|
+
return props.value ? boundText(props.value, 60) : 'Choose a model'
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function ModelOptionBody(props: { model: ModelOption }) {
|
|
196
|
+
return (
|
|
197
|
+
<span class="flex min-w-0 flex-col">
|
|
198
|
+
<span class="[overflow-wrap:anywhere]">{boundText(props.model.label, 60)}</span>
|
|
199
|
+
<Show when={props.model.description}>
|
|
200
|
+
<span class="text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
201
|
+
{boundText(props.model.description ?? '', 160)}
|
|
202
|
+
</span>
|
|
203
|
+
</Show>
|
|
204
|
+
<Show when={props.model.disabledReason}>
|
|
205
|
+
<span class="text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
206
|
+
<span class="visually-hidden">Unavailable: </span>
|
|
207
|
+
{boundText(props.model.disabledReason ?? '', 160)}
|
|
208
|
+
</span>
|
|
209
|
+
</Show>
|
|
210
|
+
</span>
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
type PickerProps = {
|
|
215
|
+
models: readonly ModelOption[]
|
|
216
|
+
selected?: ModelOption
|
|
217
|
+
value?: string
|
|
218
|
+
blocked: boolean
|
|
219
|
+
describedBy?: string
|
|
220
|
+
onChange: (id: string) => void
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function ModelTrigger(props: { selected?: ModelOption; value?: string; empty: boolean }) {
|
|
224
|
+
return (
|
|
225
|
+
<>
|
|
226
|
+
<span class="max-w-48 truncate">
|
|
227
|
+
{props.empty ? 'No models available' : triggerText(props)}
|
|
228
|
+
</span>
|
|
229
|
+
<ChevronsUpDown aria-hidden="true" />
|
|
230
|
+
</>
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function ModelMenu(props: PickerProps) {
|
|
235
|
+
const [open, setOpen] = createSignal(false)
|
|
236
|
+
const groups = createMemo(() => groupModels(props.models))
|
|
237
|
+
const inert = () => props.blocked || props.models.length === 0
|
|
238
|
+
|
|
239
|
+
createEffect(() => {
|
|
240
|
+
if (inert()) setOpen(false)
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
return (
|
|
244
|
+
<DropdownMenu
|
|
245
|
+
open={open()}
|
|
246
|
+
onOpenChange={(next) => setOpen(next && !inert())}
|
|
247
|
+
placement="top-start"
|
|
248
|
+
gutter={6}
|
|
249
|
+
>
|
|
250
|
+
<DropdownMenuTrigger
|
|
251
|
+
as={Button}
|
|
252
|
+
variant="ghost"
|
|
253
|
+
size="sm"
|
|
254
|
+
aria-label={`Model: ${props.models.length === 0 ? 'none available' : triggerText(props)}`}
|
|
255
|
+
aria-disabled={inert() || undefined}
|
|
256
|
+
aria-describedby={props.describedBy}
|
|
257
|
+
>
|
|
258
|
+
<ModelTrigger
|
|
259
|
+
selected={props.selected}
|
|
260
|
+
value={props.value}
|
|
261
|
+
empty={props.models.length === 0}
|
|
262
|
+
/>
|
|
263
|
+
</DropdownMenuTrigger>
|
|
264
|
+
<DropdownMenuContent hideArrow class="w-72 max-w-full">
|
|
265
|
+
<DropdownMenuRadioGroup
|
|
266
|
+
value={props.value ?? ''}
|
|
267
|
+
onChange={(id: unknown) => {
|
|
268
|
+
// Disabled rows cannot be activated, but the guard is the contract.
|
|
269
|
+
const model = typeof id === 'string' ? findModel(props.models, id) : undefined
|
|
270
|
+
if (!props.blocked && model && model.disabledReason === undefined) {
|
|
271
|
+
props.onChange(model.id)
|
|
272
|
+
}
|
|
273
|
+
}}
|
|
274
|
+
>
|
|
275
|
+
<For each={groups()}>
|
|
276
|
+
{(group) => (
|
|
277
|
+
<DropdownMenuGroup>
|
|
278
|
+
<DropdownMenuLabel>{group.provider}</DropdownMenuLabel>
|
|
279
|
+
<For each={group.models}>
|
|
280
|
+
{(model) => (
|
|
281
|
+
<DropdownMenuRadioItem
|
|
282
|
+
value={model.id}
|
|
283
|
+
disabled={inert() || model.disabledReason !== undefined}
|
|
284
|
+
>
|
|
285
|
+
<ModelOptionBody model={model} />
|
|
286
|
+
</DropdownMenuRadioItem>
|
|
287
|
+
)}
|
|
288
|
+
</For>
|
|
289
|
+
</DropdownMenuGroup>
|
|
290
|
+
)}
|
|
291
|
+
</For>
|
|
292
|
+
</DropdownMenuRadioGroup>
|
|
293
|
+
</DropdownMenuContent>
|
|
294
|
+
</DropdownMenu>
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function ModelSearch(props: PickerProps) {
|
|
299
|
+
const [open, setOpen] = createSignal(false)
|
|
300
|
+
const groups = createMemo(() => groupModels(props.models))
|
|
301
|
+
|
|
302
|
+
createEffect(() => {
|
|
303
|
+
if (props.blocked) setOpen(false)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
return (
|
|
307
|
+
<Popover
|
|
308
|
+
open={open()}
|
|
309
|
+
onOpenChange={(next) => setOpen(next && !props.blocked)}
|
|
310
|
+
placement="top-start"
|
|
311
|
+
gutter={6}
|
|
312
|
+
>
|
|
313
|
+
<PopoverTrigger
|
|
314
|
+
as={Button}
|
|
315
|
+
variant="ghost"
|
|
316
|
+
size="sm"
|
|
317
|
+
aria-label={`Model: ${triggerText(props)}`}
|
|
318
|
+
aria-disabled={props.blocked || undefined}
|
|
319
|
+
aria-describedby={props.describedBy}
|
|
320
|
+
>
|
|
321
|
+
<ModelTrigger selected={props.selected} value={props.value} empty={false} />
|
|
322
|
+
</PopoverTrigger>
|
|
323
|
+
<PopoverContent class="w-80 max-w-full">
|
|
324
|
+
<Command label="Choose a model">
|
|
325
|
+
<CommandInput placeholder="Search models" />
|
|
326
|
+
<CommandList>
|
|
327
|
+
<CommandEmpty>No model matches.</CommandEmpty>
|
|
328
|
+
<For each={groups()}>
|
|
329
|
+
{(group) => (
|
|
330
|
+
<CommandGroup heading={group.provider}>
|
|
331
|
+
<For each={group.models}>
|
|
332
|
+
{(model) => (
|
|
333
|
+
<CommandItem
|
|
334
|
+
value={modelSearchValue(model)}
|
|
335
|
+
disabled={props.blocked || model.disabledReason !== undefined}
|
|
336
|
+
onSelect={() => {
|
|
337
|
+
if (props.blocked || model.disabledReason !== undefined) return
|
|
338
|
+
props.onChange(model.id)
|
|
339
|
+
setOpen(false)
|
|
340
|
+
}}
|
|
341
|
+
>
|
|
342
|
+
<ModelOptionBody model={model} />
|
|
343
|
+
<Show when={model.id === props.value}>
|
|
344
|
+
<Check aria-hidden="true" class="ms-auto text-primary" />
|
|
345
|
+
<span class="visually-hidden">Current model</span>
|
|
346
|
+
</Show>
|
|
347
|
+
</CommandItem>
|
|
348
|
+
)}
|
|
349
|
+
</For>
|
|
350
|
+
</CommandGroup>
|
|
351
|
+
)}
|
|
352
|
+
</For>
|
|
353
|
+
</CommandList>
|
|
354
|
+
</Command>
|
|
355
|
+
</PopoverContent>
|
|
356
|
+
</Popover>
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function EffortMenu(props: {
|
|
361
|
+
efforts: ReturnType<typeof normalizeEfforts>
|
|
362
|
+
value?: string
|
|
363
|
+
blocked: boolean
|
|
364
|
+
describedBy?: string
|
|
365
|
+
onChange: (id: string) => void
|
|
366
|
+
}) {
|
|
367
|
+
const [open, setOpen] = createSignal(false)
|
|
368
|
+
const label = () => props.efforts.find((effort) => effort.id === props.value)?.label
|
|
369
|
+
|
|
370
|
+
createEffect(() => {
|
|
371
|
+
if (props.blocked) setOpen(false)
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
return (
|
|
375
|
+
<DropdownMenu
|
|
376
|
+
open={open()}
|
|
377
|
+
onOpenChange={(next) => setOpen(next && !props.blocked)}
|
|
378
|
+
placement="top-start"
|
|
379
|
+
gutter={6}
|
|
380
|
+
>
|
|
381
|
+
<DropdownMenuTrigger
|
|
382
|
+
as={Button}
|
|
383
|
+
variant="ghost"
|
|
384
|
+
size="sm"
|
|
385
|
+
aria-label={`Thinking effort: ${label() ?? 'not set'}`}
|
|
386
|
+
aria-disabled={props.blocked || undefined}
|
|
387
|
+
aria-describedby={props.describedBy}
|
|
388
|
+
>
|
|
389
|
+
<Brain aria-hidden="true" />
|
|
390
|
+
<span aria-hidden="true">{label() ?? 'Effort'}</span>
|
|
391
|
+
</DropdownMenuTrigger>
|
|
392
|
+
<DropdownMenuContent hideArrow class="w-56 max-w-full">
|
|
393
|
+
<DropdownMenuRadioGroup
|
|
394
|
+
value={props.value ?? ''}
|
|
395
|
+
onChange={(id: unknown) => {
|
|
396
|
+
if (!props.blocked && typeof id === 'string') props.onChange(id)
|
|
397
|
+
}}
|
|
398
|
+
>
|
|
399
|
+
<DropdownMenuGroup>
|
|
400
|
+
<DropdownMenuLabel>Thinking effort</DropdownMenuLabel>
|
|
401
|
+
<For each={props.efforts}>
|
|
402
|
+
{(effort) => (
|
|
403
|
+
<DropdownMenuRadioItem value={effort.id} disabled={props.blocked}>
|
|
404
|
+
<span class="flex min-w-0 flex-col">
|
|
405
|
+
<span>{effort.label}</span>
|
|
406
|
+
<Show when={effort.description}>
|
|
407
|
+
<span class="text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
408
|
+
{effort.description}
|
|
409
|
+
</span>
|
|
410
|
+
</Show>
|
|
411
|
+
</span>
|
|
412
|
+
</DropdownMenuRadioItem>
|
|
413
|
+
)}
|
|
414
|
+
</For>
|
|
415
|
+
</DropdownMenuGroup>
|
|
416
|
+
</DropdownMenuRadioGroup>
|
|
417
|
+
</DropdownMenuContent>
|
|
418
|
+
</DropdownMenu>
|
|
419
|
+
)
|
|
420
|
+
}
|