@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,83 @@
|
|
|
1
|
+
import { boundText } from '../sources/source'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Where a request for approval stands.
|
|
5
|
+
*
|
|
6
|
+
* - `requested`: waiting on the reader. The only state with live buttons.
|
|
7
|
+
* - `approved` / `denied`: settled; the record of the answer.
|
|
8
|
+
* - `expired`: nobody can answer it any more (the run moved on, a timeout).
|
|
9
|
+
* - `unavailable`: it is still open, but this client cannot answer it right now
|
|
10
|
+
* (offline, no authority, another client holds it). The buttons stay visible and
|
|
11
|
+
* disabled so the reader can see what was asked and why they cannot answer.
|
|
12
|
+
*/
|
|
13
|
+
export type ConfirmationState = 'requested' | 'approved' | 'denied' | 'expired' | 'unavailable'
|
|
14
|
+
|
|
15
|
+
/** Whether the choice is still open, which is exactly when the buttons are drawn. */
|
|
16
|
+
export function isAwaitingAnswer(state: ConfirmationState): boolean {
|
|
17
|
+
return state === 'requested' || state === 'unavailable'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The one line that replaces the buttons once the request settles. Who and when
|
|
22
|
+
* appear only if the host supplied them: "Approved" is a fact the state gives,
|
|
23
|
+
* "by Ana" is a fact only the host knows.
|
|
24
|
+
*/
|
|
25
|
+
export function confirmationOutcome(
|
|
26
|
+
state: ConfirmationState,
|
|
27
|
+
by?: string,
|
|
28
|
+
at?: string
|
|
29
|
+
): string | undefined {
|
|
30
|
+
const base =
|
|
31
|
+
state === 'approved'
|
|
32
|
+
? 'Approved'
|
|
33
|
+
: state === 'denied'
|
|
34
|
+
? 'Denied'
|
|
35
|
+
: state === 'expired'
|
|
36
|
+
? 'Expired without an answer'
|
|
37
|
+
: undefined
|
|
38
|
+
if (base === undefined) return undefined
|
|
39
|
+
const who = by ? boundText(by, 60) : ''
|
|
40
|
+
const when = at ? boundText(at, 40) : ''
|
|
41
|
+
return `${base}${who ? ` by ${who}` : ''}${when ? ` at ${when}` : ''}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type DecisionResult = { ok: true } | { ok: false; message: string }
|
|
45
|
+
|
|
46
|
+
const DEFAULT_FAILURE = 'Your answer could not be sent. Try again.'
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Run a host handler that may be synchronous, asynchronous, or throw, and report
|
|
50
|
+
* the outcome as data. A rejection's own message is shown (bounded) because the
|
|
51
|
+
* host usually knows why; a non-Error rejection gets a plain sentence instead of
|
|
52
|
+
* "[object Object]".
|
|
53
|
+
*/
|
|
54
|
+
export async function settleDecision(
|
|
55
|
+
handler: (() => void | Promise<void>) | undefined
|
|
56
|
+
): Promise<DecisionResult> {
|
|
57
|
+
try {
|
|
58
|
+
await handler?.()
|
|
59
|
+
return { ok: true }
|
|
60
|
+
} catch (error) {
|
|
61
|
+
const message = error instanceof Error ? boundText(error.message, 200) : ''
|
|
62
|
+
return { ok: false, message: message || DEFAULT_FAILURE }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Why a choice is not available, in words. A host `disabledReason` outranks the
|
|
68
|
+
* built-in sentence for a missing handler, and a request that is `unavailable`
|
|
69
|
+
* without a reason still says so rather than showing dead buttons.
|
|
70
|
+
*/
|
|
71
|
+
export function decisionReason(options: {
|
|
72
|
+
state: ConfirmationState
|
|
73
|
+
disabledReason?: string
|
|
74
|
+
hasHandler: boolean
|
|
75
|
+
unavailableFallback: string
|
|
76
|
+
missingFallback: string
|
|
77
|
+
}): string | undefined {
|
|
78
|
+
const hostReason = options.disabledReason ? boundText(options.disabledReason, 240) : ''
|
|
79
|
+
if (hostReason) return hostReason
|
|
80
|
+
if (options.state === 'unavailable') return options.unavailableFallback
|
|
81
|
+
if (!options.hasHandler) return options.missingFallback
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { Ban, Check, Clock, Lock, ShieldQuestion } from 'lucide-solid'
|
|
2
|
+
import {
|
|
3
|
+
createEffect,
|
|
4
|
+
createSignal,
|
|
5
|
+
createUniqueId,
|
|
6
|
+
Show,
|
|
7
|
+
splitProps,
|
|
8
|
+
type ComponentProps,
|
|
9
|
+
type JSX,
|
|
10
|
+
} from 'solid-js'
|
|
11
|
+
import { cn } from '../../../lib/utils'
|
|
12
|
+
import { Button } from '../../ui/button'
|
|
13
|
+
import { CodeBlock } from '../../ui/code-block'
|
|
14
|
+
import { DiffBlock } from '../../ui/diff-block'
|
|
15
|
+
import { Spinner } from '../../ui/spinner'
|
|
16
|
+
import { boundText } from '../sources/source'
|
|
17
|
+
import {
|
|
18
|
+
confirmationOutcome,
|
|
19
|
+
decisionReason,
|
|
20
|
+
isAwaitingAnswer,
|
|
21
|
+
settleDecision,
|
|
22
|
+
type ConfirmationState,
|
|
23
|
+
} from './confirmation-model'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Confirmation.
|
|
27
|
+
*
|
|
28
|
+
* The agent has stopped a tool and will not continue until the person approves or
|
|
29
|
+
* denies it. Like `Questionnaire`, this is one of the two elements in a transcript
|
|
30
|
+
* the reader *must* act on, so it is allowed a card surface — and the border is
|
|
31
|
+
* the focus ring's colour only while it is waiting. Once answered it drops to a
|
|
32
|
+
* hairline and a one-line record, because a settled decision should read as
|
|
33
|
+
* history, not as something still asking.
|
|
34
|
+
*
|
|
35
|
+
* ## It shows what is being approved, and nothing else
|
|
36
|
+
*
|
|
37
|
+
* `title` and `description` say what the tool wants to do; `details` is the
|
|
38
|
+
* evidence, rendered as `CodeBlock size="sm"` (a command, a request) or
|
|
39
|
+
* `DiffBlock` (a patch). Details are text: never interpreted, and a long one
|
|
40
|
+
* scrolls inside its block. Approve and Deny exist only while the request is
|
|
41
|
+
* open; afterwards they are replaced by the outcome, with *who* and *when* only if
|
|
42
|
+
* the host supplied them.
|
|
43
|
+
*
|
|
44
|
+
* ## The host owns authority
|
|
45
|
+
*
|
|
46
|
+
* Whether this client may answer is not decided here. No handler, or a host
|
|
47
|
+
* `disabledReason`, or the `unavailable` state, leaves the buttons visible and
|
|
48
|
+
* disabled with the reason beside them in words — never hidden, because a reader
|
|
49
|
+
* who cannot see the choice cannot tell whether the agent is waiting on them.
|
|
50
|
+
*
|
|
51
|
+
* ## Answering is a round trip
|
|
52
|
+
*
|
|
53
|
+
* `onApprove` / `onDeny` may return a promise. While one is pending both buttons
|
|
54
|
+
* refuse input (a synchronous guard as well as the signal, so a double click in
|
|
55
|
+
* one tick cannot submit twice) and the pressed one shows a spinner. A failure
|
|
56
|
+
* shows `error` (or the rejection's own message) and re-enables the buttons. The
|
|
57
|
+
* buttons use `aria-disabled` rather than `disabled`: a native disabled button
|
|
58
|
+
* drops focus, and the reader's place would be lost mid-decision. When the state
|
|
59
|
+
* settles, focus moves to the outcome line if it was in the card, so a keyboard
|
|
60
|
+
* user is not stranded on a control that no longer exists.
|
|
61
|
+
*/
|
|
62
|
+
export type ConfirmationDetails =
|
|
63
|
+
| Readonly<{ kind: 'code'; code: string; language?: string; title?: string }>
|
|
64
|
+
| Readonly<{ kind: 'diff'; patch: string; title?: string }>
|
|
65
|
+
|
|
66
|
+
export type ConfirmationProps = Omit<ComponentProps<'section'>, 'title' | 'onError'> & {
|
|
67
|
+
state?: ConfirmationState
|
|
68
|
+
/** What the tool wants to do, as a short sentence. */
|
|
69
|
+
title: string
|
|
70
|
+
description?: string
|
|
71
|
+
details?: ConfirmationDetails
|
|
72
|
+
onApprove?: () => void | Promise<void>
|
|
73
|
+
onDeny?: () => void | Promise<void>
|
|
74
|
+
approveLabel?: string
|
|
75
|
+
denyLabel?: string
|
|
76
|
+
/** Why the choice cannot be made right now; shown in words beside the buttons. */
|
|
77
|
+
disabledReason?: string
|
|
78
|
+
/** A failed answer, in words. Overrides the rejection's own message. */
|
|
79
|
+
error?: string
|
|
80
|
+
/** Who answered, once settled. Omit if unknown; nothing is assumed. */
|
|
81
|
+
resolvedBy?: string
|
|
82
|
+
/** When it was answered, already formatted for the reader. Omit if unknown. */
|
|
83
|
+
resolvedAt?: string
|
|
84
|
+
/** Extra content between the details and the buttons. */
|
|
85
|
+
children?: JSX.Element
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type Choice = 'approve' | 'deny'
|
|
89
|
+
|
|
90
|
+
export function Confirmation(props: ConfirmationProps) {
|
|
91
|
+
const [local, rest] = splitProps(props, [
|
|
92
|
+
'class',
|
|
93
|
+
'state',
|
|
94
|
+
'title',
|
|
95
|
+
'description',
|
|
96
|
+
'details',
|
|
97
|
+
'onApprove',
|
|
98
|
+
'onDeny',
|
|
99
|
+
'approveLabel',
|
|
100
|
+
'denyLabel',
|
|
101
|
+
'disabledReason',
|
|
102
|
+
'error',
|
|
103
|
+
'resolvedBy',
|
|
104
|
+
'resolvedAt',
|
|
105
|
+
'children',
|
|
106
|
+
])
|
|
107
|
+
const uid = createUniqueId()
|
|
108
|
+
const titleId = `${uid}-title`
|
|
109
|
+
const reasonId = `${uid}-reason`
|
|
110
|
+
const state = (): ConfirmationState => local.state ?? 'requested'
|
|
111
|
+
const awaiting = () => isAwaitingAnswer(state())
|
|
112
|
+
const [pending, setPending] = createSignal<Choice | undefined>(undefined)
|
|
113
|
+
const [failure, setFailure] = createSignal<string | undefined>(undefined)
|
|
114
|
+
let inflight = false
|
|
115
|
+
let root: HTMLElement | undefined
|
|
116
|
+
let outcome: HTMLParagraphElement | undefined
|
|
117
|
+
|
|
118
|
+
const reasonFor = (handler: (() => void | Promise<void>) | undefined, missing: string) => {
|
|
119
|
+
if (pending() !== undefined) return 'Your answer is being sent.'
|
|
120
|
+
return decisionReason({
|
|
121
|
+
state: state(),
|
|
122
|
+
disabledReason: local.disabledReason,
|
|
123
|
+
hasHandler: handler !== undefined,
|
|
124
|
+
unavailableFallback: 'This request cannot be answered right now.',
|
|
125
|
+
missingFallback: missing,
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
const approveReason = () => reasonFor(local.onApprove, 'Approving is not available here.')
|
|
129
|
+
const denyReason = () => reasonFor(local.onDeny, 'Denying is not available here.')
|
|
130
|
+
// One sentence per distinct reason, so two identical reasons are not read twice.
|
|
131
|
+
const reasons = () => [...new Set([approveReason(), denyReason()].filter(Boolean))].join(' ')
|
|
132
|
+
const error = () => (local.error ? boundText(local.error, 240) : failure())
|
|
133
|
+
|
|
134
|
+
const choose = async (choice: Choice) => {
|
|
135
|
+
const handler = choice === 'approve' ? local.onApprove : local.onDeny
|
|
136
|
+
const blocked = choice === 'approve' ? approveReason() : denyReason()
|
|
137
|
+
if (inflight || blocked || !awaiting()) return
|
|
138
|
+
inflight = true
|
|
139
|
+
setPending(choice)
|
|
140
|
+
setFailure(undefined)
|
|
141
|
+
const result = await settleDecision(handler)
|
|
142
|
+
inflight = false
|
|
143
|
+
setPending(undefined)
|
|
144
|
+
if (!result.ok) setFailure(result.message)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// The buttons are replaced by the outcome line; keep a keyboard reader in the card.
|
|
148
|
+
// The previous value is kept by hand: `on(..., { defer: true })` does not record the
|
|
149
|
+
// input of its skipped first run, so its "previous" is undefined on the first change.
|
|
150
|
+
let wasAwaiting = awaiting()
|
|
151
|
+
createEffect(() => {
|
|
152
|
+
const now = awaiting()
|
|
153
|
+
if (wasAwaiting && !now) {
|
|
154
|
+
const active = document.activeElement
|
|
155
|
+
if (active === null || active === document.body || root?.contains(active)) {
|
|
156
|
+
outcome?.focus()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
wasAwaiting = now
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const buttonProps = (choice: Choice) => {
|
|
163
|
+
const blocked = () => (choice === 'approve' ? approveReason() : denyReason())
|
|
164
|
+
const disabled = () => pending() !== undefined || blocked() !== undefined
|
|
165
|
+
return {
|
|
166
|
+
'aria-disabled': disabled() || undefined,
|
|
167
|
+
'aria-describedby': blocked() ? reasonId : undefined,
|
|
168
|
+
onClick: () => void choose(choice),
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<section
|
|
174
|
+
ref={(element) => (root = element)}
|
|
175
|
+
data-slot="confirmation"
|
|
176
|
+
data-state={state()}
|
|
177
|
+
aria-labelledby={titleId}
|
|
178
|
+
class={cn('flex w-full max-w-xl min-w-0 flex-col gap-3 rounded-xl border bg-card p-4', {
|
|
179
|
+
'border-ring': awaiting(),
|
|
180
|
+
'border-border': !awaiting(),
|
|
181
|
+
})}
|
|
182
|
+
{...rest}
|
|
183
|
+
>
|
|
184
|
+
<header class="flex items-start gap-2.5">
|
|
185
|
+
<span aria-hidden="true" class="mt-0.5 text-muted-foreground [&_svg]:size-4">
|
|
186
|
+
<Show when={state() === 'approved'}>
|
|
187
|
+
<Check class="text-success" />
|
|
188
|
+
</Show>
|
|
189
|
+
<Show when={state() === 'denied'}>
|
|
190
|
+
<Ban />
|
|
191
|
+
</Show>
|
|
192
|
+
<Show when={state() === 'expired'}>
|
|
193
|
+
<Clock />
|
|
194
|
+
</Show>
|
|
195
|
+
<Show when={state() === 'unavailable'}>
|
|
196
|
+
<Lock />
|
|
197
|
+
</Show>
|
|
198
|
+
<Show when={state() === 'requested'}>
|
|
199
|
+
<ShieldQuestion />
|
|
200
|
+
</Show>
|
|
201
|
+
</span>
|
|
202
|
+
<div class="min-w-0 flex-1">
|
|
203
|
+
<h3 id={titleId} class="m-0 text-sm font-semibold [overflow-wrap:anywhere]">
|
|
204
|
+
{boundText(local.title, 200)}
|
|
205
|
+
</h3>
|
|
206
|
+
<Show when={local.description}>
|
|
207
|
+
<p class="m-0 mt-0.5 text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
208
|
+
{boundText(local.description ?? '', 400)}
|
|
209
|
+
</p>
|
|
210
|
+
</Show>
|
|
211
|
+
</div>
|
|
212
|
+
<Show when={awaiting()}>
|
|
213
|
+
<span class="shrink-0 text-xs text-muted-foreground">
|
|
214
|
+
{state() === 'requested' ? 'Needs your answer' : 'Cannot be answered now'}
|
|
215
|
+
</span>
|
|
216
|
+
</Show>
|
|
217
|
+
</header>
|
|
218
|
+
|
|
219
|
+
<Show when={local.details}>{(details) => <Details details={details()} />}</Show>
|
|
220
|
+
|
|
221
|
+
{local.children}
|
|
222
|
+
|
|
223
|
+
<Show
|
|
224
|
+
when={awaiting()}
|
|
225
|
+
fallback={
|
|
226
|
+
<p
|
|
227
|
+
ref={(element) => (outcome = element)}
|
|
228
|
+
tabindex="-1"
|
|
229
|
+
role="status"
|
|
230
|
+
class="m-0 flex items-center gap-1.5 text-xs text-muted-foreground outline-none"
|
|
231
|
+
>
|
|
232
|
+
{confirmationOutcome(state(), local.resolvedBy, local.resolvedAt)}
|
|
233
|
+
</p>
|
|
234
|
+
}
|
|
235
|
+
>
|
|
236
|
+
<Show when={reasons()}>
|
|
237
|
+
<p id={reasonId} role="status" class="m-0 text-xs text-muted-foreground">
|
|
238
|
+
{reasons()}
|
|
239
|
+
</p>
|
|
240
|
+
</Show>
|
|
241
|
+
<Show when={error()}>
|
|
242
|
+
<p role="alert" class="m-0 text-xs text-destructive [overflow-wrap:anywhere]">
|
|
243
|
+
{error()}
|
|
244
|
+
</p>
|
|
245
|
+
</Show>
|
|
246
|
+
<footer class="flex flex-wrap items-center justify-end gap-2">
|
|
247
|
+
<Button type="button" variant="outline" size="sm" {...buttonProps('deny')}>
|
|
248
|
+
<Show when={pending() === 'deny'}>
|
|
249
|
+
<Spinner size="sm" label={false} />
|
|
250
|
+
</Show>
|
|
251
|
+
{local.denyLabel ?? 'Deny'}
|
|
252
|
+
</Button>
|
|
253
|
+
<Button type="button" size="sm" {...buttonProps('approve')}>
|
|
254
|
+
<Show when={pending() === 'approve'}>
|
|
255
|
+
<Spinner size="sm" label={false} />
|
|
256
|
+
</Show>
|
|
257
|
+
{local.approveLabel ?? 'Approve'}
|
|
258
|
+
</Button>
|
|
259
|
+
{/* Present from the start: a live region inserted with its text is not reliably announced. */}
|
|
260
|
+
<span role="status" class="visually-hidden">
|
|
261
|
+
{pending() !== undefined ? 'Sending your answer' : ''}
|
|
262
|
+
</span>
|
|
263
|
+
</footer>
|
|
264
|
+
</Show>
|
|
265
|
+
</section>
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** A name from the host or the model, cleaned and clipped before it reaches a header. */
|
|
270
|
+
function bounded(value: string | undefined, limit: number): string | undefined {
|
|
271
|
+
return value ? boundText(value, limit) || undefined : undefined
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function Details(props: { details: ConfirmationDetails }) {
|
|
275
|
+
return (
|
|
276
|
+
<Show
|
|
277
|
+
when={props.details.kind === 'diff' && props.details}
|
|
278
|
+
fallback={
|
|
279
|
+
<CodeBlock
|
|
280
|
+
size="sm"
|
|
281
|
+
code={(props.details as Extract<ConfirmationDetails, { kind: 'code' }>).code}
|
|
282
|
+
language={bounded(
|
|
283
|
+
(props.details as Extract<ConfirmationDetails, { kind: 'code' }>).language,
|
|
284
|
+
24
|
|
285
|
+
)}
|
|
286
|
+
title={bounded(props.details.title, 80)}
|
|
287
|
+
complete
|
|
288
|
+
wrap
|
|
289
|
+
maxHeight="14rem"
|
|
290
|
+
/>
|
|
291
|
+
}
|
|
292
|
+
>
|
|
293
|
+
{(diff) => (
|
|
294
|
+
// The diff block has no height cap of its own, so the cap lives here; a
|
|
295
|
+
// scroller must be focusable, hence the labelled region and tab stop.
|
|
296
|
+
<div
|
|
297
|
+
role="region"
|
|
298
|
+
aria-label="Proposed changes"
|
|
299
|
+
tabindex="0"
|
|
300
|
+
class="max-h-64 overflow-auto rounded-xl outline-none focus-visible:ring-3 focus-visible:ring-primary-subtle"
|
|
301
|
+
>
|
|
302
|
+
<DiffBlock
|
|
303
|
+
patch={(diff() as Extract<ConfirmationDetails, { kind: 'diff' }>).patch}
|
|
304
|
+
title={bounded(diff().title, 80)}
|
|
305
|
+
complete
|
|
306
|
+
/>
|
|
307
|
+
</div>
|
|
308
|
+
)}
|
|
309
|
+
</Show>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { Confirmation, type ConfirmationDetails, type ConfirmationProps } from './confirmation'
|
|
2
|
+
export {
|
|
3
|
+
confirmationOutcome,
|
|
4
|
+
decisionReason,
|
|
5
|
+
isAwaitingAnswer,
|
|
6
|
+
settleDecision,
|
|
7
|
+
type ConfirmationState,
|
|
8
|
+
type DecisionResult,
|
|
9
|
+
} from './confirmation-model'
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { boundText } from '../sources/source'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The figures a host may know about a context window. Every one is optional and
|
|
5
|
+
* means "the host told us", so absence is never rendered as zero: `used: 0` is a
|
|
6
|
+
* fresh conversation, a missing `used` is an unknown.
|
|
7
|
+
*/
|
|
8
|
+
export type ContextBreakdown = Readonly<{
|
|
9
|
+
input?: number
|
|
10
|
+
output?: number
|
|
11
|
+
cacheRead?: number
|
|
12
|
+
cacheWrite?: number
|
|
13
|
+
reasoning?: number
|
|
14
|
+
}>
|
|
15
|
+
|
|
16
|
+
export type ContextCost = Readonly<{
|
|
17
|
+
amount: number
|
|
18
|
+
/** An ISO 4217 code such as `USD`. Without one the amount is shown unlabelled. */
|
|
19
|
+
currency?: string
|
|
20
|
+
}>
|
|
21
|
+
|
|
22
|
+
export type ContextFigures = Readonly<{
|
|
23
|
+
/** Tokens in the window now. */
|
|
24
|
+
used?: number
|
|
25
|
+
/** The window's size. */
|
|
26
|
+
total?: number
|
|
27
|
+
breakdown?: ContextBreakdown
|
|
28
|
+
cost?: ContextCost
|
|
29
|
+
}>
|
|
30
|
+
|
|
31
|
+
/** A usable figure: a finite, non-negative number. NaN, Infinity and negatives are "unknown". */
|
|
32
|
+
export function isFigure(value: number | undefined): value is number {
|
|
33
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const BREAKDOWN_ROWS = [
|
|
37
|
+
['input', 'Input'],
|
|
38
|
+
['output', 'Output'],
|
|
39
|
+
['cacheRead', 'Cache read'],
|
|
40
|
+
['cacheWrite', 'Cache write'],
|
|
41
|
+
['reasoning', 'Reasoning'],
|
|
42
|
+
] as const
|
|
43
|
+
|
|
44
|
+
/** The breakdown entries the host actually supplied, in a fixed reading order. */
|
|
45
|
+
export function breakdownRows(
|
|
46
|
+
breakdown: ContextBreakdown | undefined
|
|
47
|
+
): readonly { key: string; label: string; value: number }[] {
|
|
48
|
+
if (!breakdown) return []
|
|
49
|
+
const rows: { key: string; label: string; value: number }[] = []
|
|
50
|
+
for (const [key, label] of BREAKDOWN_ROWS) {
|
|
51
|
+
const value = breakdown[key]
|
|
52
|
+
if (isFigure(value)) rows.push({ key, label, value })
|
|
53
|
+
}
|
|
54
|
+
return rows
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether there is anything to show. When there is not, the trigger is not
|
|
59
|
+
* rendered at all: an empty gauge or "0%" would assert an empty window.
|
|
60
|
+
*/
|
|
61
|
+
export function hasContextFigures(figures: ContextFigures): boolean {
|
|
62
|
+
return (
|
|
63
|
+
isFigure(figures.used) ||
|
|
64
|
+
isFigure(figures.total) ||
|
|
65
|
+
breakdownRows(figures.breakdown).length > 0 ||
|
|
66
|
+
(figures.cost !== undefined && isFigure(figures.cost.amount))
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Percentage of the window used, rounded. Needs both figures and a non-empty
|
|
72
|
+
* window; it is not clamped, because "112%" is the truth about an overrun and a
|
|
73
|
+
* clamp would hide it (the ring is what saturates, not the number).
|
|
74
|
+
*/
|
|
75
|
+
export function contextPercent(
|
|
76
|
+
used: number | undefined,
|
|
77
|
+
total: number | undefined
|
|
78
|
+
): number | undefined {
|
|
79
|
+
if (!isFigure(used) || !isFigure(total) || total <= 0) return undefined
|
|
80
|
+
return Math.round((used / total) * 100)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type ContextLevel = 'normal' | 'high' | 'critical' | 'full'
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* How full, in steps. The step changes an icon and a word as well as a colour, so
|
|
87
|
+
* it reads without colour vision and in a screen reader.
|
|
88
|
+
*/
|
|
89
|
+
export function contextLevel(percent: number | undefined): ContextLevel {
|
|
90
|
+
if (percent === undefined) return 'normal'
|
|
91
|
+
if (percent >= 100) return 'full'
|
|
92
|
+
if (percent >= 90) return 'critical'
|
|
93
|
+
if (percent >= 75) return 'high'
|
|
94
|
+
return 'normal'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function contextLevelWord(level: ContextLevel): string | undefined {
|
|
98
|
+
switch (level) {
|
|
99
|
+
case 'high':
|
|
100
|
+
return 'Getting full'
|
|
101
|
+
case 'critical':
|
|
102
|
+
return 'Nearly full'
|
|
103
|
+
case 'full':
|
|
104
|
+
return 'Full'
|
|
105
|
+
case 'normal':
|
|
106
|
+
return undefined
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Compact token count for the trigger: 950, 1.2K, 48.2K, 1.3M. */
|
|
111
|
+
export function formatTokens(value: number, locale = 'en-US'): string {
|
|
112
|
+
return new Intl.NumberFormat(locale, { notation: 'compact', maximumFractionDigits: 1 }).format(
|
|
113
|
+
value
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The exact count for the popover. */
|
|
118
|
+
export function formatExact(value: number, locale = 'en-US'): string {
|
|
119
|
+
return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Money, with its currency symbol when the code is valid. An unrecognised code
|
|
124
|
+
* (`Intl` throws a RangeError) is shown as written, bounded, rather than being
|
|
125
|
+
* swapped for a currency the host never named.
|
|
126
|
+
*/
|
|
127
|
+
export function formatCost(cost: ContextCost, locale = 'en-US'): string {
|
|
128
|
+
const digits = { minimumFractionDigits: 2, maximumFractionDigits: cost.amount < 1 ? 4 : 2 }
|
|
129
|
+
if (!cost.currency) return new Intl.NumberFormat(locale, digits).format(cost.amount)
|
|
130
|
+
try {
|
|
131
|
+
return new Intl.NumberFormat(locale, {
|
|
132
|
+
...digits,
|
|
133
|
+
style: 'currency',
|
|
134
|
+
currency: cost.currency,
|
|
135
|
+
}).format(cost.amount)
|
|
136
|
+
} catch {
|
|
137
|
+
return `${new Intl.NumberFormat(locale, digits).format(cost.amount)} ${boundText(cost.currency, 8)}`
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The trigger's accessible name: the whole claim in words. Percent when both
|
|
143
|
+
* figures are known, else the most informative thing that is.
|
|
144
|
+
*/
|
|
145
|
+
export function contextLabel(figures: ContextFigures, locale = 'en-US'): string | undefined {
|
|
146
|
+
const percent = contextPercent(figures.used, figures.total)
|
|
147
|
+
if (percent !== undefined) {
|
|
148
|
+
const word = contextLevelWord(contextLevel(percent))
|
|
149
|
+
return `${percent}% of context used${word ? `, ${word.toLowerCase()}` : ''}`
|
|
150
|
+
}
|
|
151
|
+
if (isFigure(figures.used)) return `${formatTokens(figures.used, locale)} tokens used`
|
|
152
|
+
if (isFigure(figures.total)) return `${formatTokens(figures.total, locale)} token context window`
|
|
153
|
+
if (breakdownRows(figures.breakdown).length > 0) return 'Token usage'
|
|
154
|
+
if (figures.cost && isFigure(figures.cost.amount))
|
|
155
|
+
return `Cost ${formatCost(figures.cost, locale)}`
|
|
156
|
+
return undefined
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** The short visible text inside the trigger. Always a prefix-compatible part of `contextLabel`. */
|
|
160
|
+
export function contextShort(figures: ContextFigures, locale = 'en-US'): string | undefined {
|
|
161
|
+
const percent = contextPercent(figures.used, figures.total)
|
|
162
|
+
if (percent !== undefined) return `${percent}%`
|
|
163
|
+
if (isFigure(figures.used)) return formatTokens(figures.used, locale)
|
|
164
|
+
if (isFigure(figures.total)) return formatTokens(figures.total, locale)
|
|
165
|
+
if (breakdownRows(figures.breakdown).length > 0) return 'Usage'
|
|
166
|
+
if (figures.cost && isFigure(figures.cost.amount)) return formatCost(figures.cost, locale)
|
|
167
|
+
return undefined
|
|
168
|
+
}
|