@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,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, safe reading of model and user text.
|
|
3
|
+
*
|
|
4
|
+
* Assistant output is untrusted: it can contain anything a model, a tool result
|
|
5
|
+
* or a pasted web page put there. This parser therefore produces *data* —
|
|
6
|
+
* blocks and inline spans — and the renderer turns that data into text nodes and
|
|
7
|
+
* a fixed set of elements. There is no HTML pass, no `innerHTML`, and no
|
|
8
|
+
* attribute built from the text other than a link `href` that has passed
|
|
9
|
+
* `safeHref`.
|
|
10
|
+
*
|
|
11
|
+
* It reads a deliberately small subset of Markdown: fenced code, headings,
|
|
12
|
+
* flat lists, block quotes, paragraphs, and inline code, bold, italic and links.
|
|
13
|
+
* Anything it does not recognise stays as paragraph text with its line breaks
|
|
14
|
+
* (the paragraph renders `white-space: pre-wrap`), so unsupported syntax
|
|
15
|
+
* degrades to readable source instead of vanishing.
|
|
16
|
+
*
|
|
17
|
+
* A citation marker, `[^1]` or `[^1,2]`, is read only when the caller says how
|
|
18
|
+
* many sources it has (`citations`) and every number names one of them. A marker
|
|
19
|
+
* the host cannot resolve stays literal text: it is never a citation by shape
|
|
20
|
+
* alone, and `arr[1]` or a footnote the model invented is not one either.
|
|
21
|
+
*
|
|
22
|
+
* Streaming is a first-class input. `streaming: true` means the text may end
|
|
23
|
+
* mid-construct, so an unterminated fence is a *partial* code block — shown as
|
|
24
|
+
* code from its first line, flagged incomplete — and an unterminated inline
|
|
25
|
+
* span stays literal until its closing delimiter arrives. Once streaming stops,
|
|
26
|
+
* an unterminated fence is just a code block that ends at the end of the text.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
export type MessageInline =
|
|
30
|
+
| Readonly<{ kind: 'text'; text: string }>
|
|
31
|
+
| Readonly<{ kind: 'code'; text: string }>
|
|
32
|
+
| Readonly<{ kind: 'strong'; children: readonly MessageInline[] }>
|
|
33
|
+
| Readonly<{ kind: 'em'; children: readonly MessageInline[] }>
|
|
34
|
+
| Readonly<{ kind: 'link'; href: string; children: readonly MessageInline[] }>
|
|
35
|
+
/** A resolved citation marker: 1-based source numbers, each within `citations`. */
|
|
36
|
+
| Readonly<{ kind: 'cite'; numbers: readonly number[]; raw: string }>
|
|
37
|
+
|
|
38
|
+
export type MessageBlock =
|
|
39
|
+
| Readonly<{ kind: 'paragraph'; inline: readonly MessageInline[]; raw: string }>
|
|
40
|
+
| Readonly<{
|
|
41
|
+
kind: 'heading'
|
|
42
|
+
level: 1 | 2 | 3 | 4
|
|
43
|
+
inline: readonly MessageInline[]
|
|
44
|
+
raw: string
|
|
45
|
+
}>
|
|
46
|
+
| Readonly<{
|
|
47
|
+
kind: 'list'
|
|
48
|
+
ordered: boolean
|
|
49
|
+
start: number
|
|
50
|
+
items: readonly (readonly MessageInline[])[]
|
|
51
|
+
raw: string
|
|
52
|
+
}>
|
|
53
|
+
| Readonly<{ kind: 'quote'; inline: readonly MessageInline[]; raw: string }>
|
|
54
|
+
| Readonly<{
|
|
55
|
+
kind: 'code'
|
|
56
|
+
language: string | undefined
|
|
57
|
+
code: string
|
|
58
|
+
/** False while the fence is still open and the text may still grow. */
|
|
59
|
+
complete: boolean
|
|
60
|
+
raw: string
|
|
61
|
+
}>
|
|
62
|
+
|
|
63
|
+
const WHITESPACE = /\s/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* An opening fence: up to three spaces, a run of three or more backticks or of
|
|
67
|
+
* three or more tildes, then an info string that holds no backtick. The first
|
|
68
|
+
* word of the info string is the language. This is a scan, not one pattern,
|
|
69
|
+
* because a pattern whose classes overlap (`[^\s`]*` then `[^`]*`) retries every
|
|
70
|
+
* split of a long info string when a stray backtick ends it: three backticks, a
|
|
71
|
+
* long run of `a` and a trailing backtick took quadratic time.
|
|
72
|
+
*/
|
|
73
|
+
function fenceOpen(line: string): Readonly<{ marker: string; language: string }> | undefined {
|
|
74
|
+
let start = 0
|
|
75
|
+
while (start < 3 && line.charCodeAt(start) === 32) start += 1
|
|
76
|
+
const mark = line[start]
|
|
77
|
+
if (mark !== '`' && mark !== '~') return undefined
|
|
78
|
+
let end = start + 1
|
|
79
|
+
while (line[end] === mark) end += 1
|
|
80
|
+
if (end - start < 3) return undefined
|
|
81
|
+
if (line.includes('`', end)) return undefined
|
|
82
|
+
let wordStart = end
|
|
83
|
+
while (line[wordStart] === ' ' || line[wordStart] === '\t') wordStart += 1
|
|
84
|
+
let wordEnd = wordStart
|
|
85
|
+
while (wordEnd < line.length && !WHITESPACE.test(line[wordEnd]!)) wordEnd += 1
|
|
86
|
+
return { marker: line.slice(start, end), language: line.slice(wordStart, wordEnd) }
|
|
87
|
+
}
|
|
88
|
+
// The lookahead after each marker's spaces makes that run maximal, so a line
|
|
89
|
+
// that fails later (`.` stops at U+2028) cannot retry every shorter run.
|
|
90
|
+
const BULLET = /^ {0,3}[-*+][ \t]+(?![ \t])(.*)$/
|
|
91
|
+
const ORDERED = /^ {0,3}(\d{1,9})[.)][ \t]+(?![ \t])(.*)$/
|
|
92
|
+
const QUOTE = /^ {0,3}>[ \t]?(.*)$/
|
|
93
|
+
|
|
94
|
+
const isBlank = (char: string | undefined) => char === ' ' || char === '\t'
|
|
95
|
+
const LINE_TERMINATOR = /[\n\r\u2028\u2029]/
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* An ATX heading: up to three spaces, one to four `#`, spaces or tabs, then the
|
|
99
|
+
* text, with any trailing spaces and closing `#` run removed. This is a scan for
|
|
100
|
+
* the reason `fenceOpen` is: the equivalent pattern (`(.+?)[ \t]*#*[ \t]*$`)
|
|
101
|
+
* retries the closing check from every position of a long run of spaces.
|
|
102
|
+
*/
|
|
103
|
+
function headingOf(line: string): Readonly<{ level: 1 | 2 | 3 | 4; text: string }> | undefined {
|
|
104
|
+
let start = 0
|
|
105
|
+
while (start < 3 && line.charCodeAt(start) === 32) start += 1
|
|
106
|
+
let marks = start
|
|
107
|
+
while (line[marks] === '#') marks += 1
|
|
108
|
+
const level = marks - start
|
|
109
|
+
if (level < 1 || level > 4 || !isBlank(line[marks])) return undefined
|
|
110
|
+
let textStart = marks
|
|
111
|
+
while (isBlank(line[textStart])) textStart += 1
|
|
112
|
+
if (textStart === line.length) {
|
|
113
|
+
// Only blanks follow the marker: the text is the last of them, which needs a second one.
|
|
114
|
+
return textStart - marks >= 2
|
|
115
|
+
? { level: level as 1 | 2 | 3 | 4, text: line[line.length - 1]! }
|
|
116
|
+
: undefined
|
|
117
|
+
}
|
|
118
|
+
if (LINE_TERMINATOR.test(line.slice(textStart))) return undefined
|
|
119
|
+
// Drop the longest tail of blanks, a run of `#`, and blanks again.
|
|
120
|
+
let textEnd = line.length
|
|
121
|
+
while (textEnd > textStart && isBlank(line[textEnd - 1])) textEnd -= 1
|
|
122
|
+
while (textEnd > textStart && line[textEnd - 1] === '#') textEnd -= 1
|
|
123
|
+
while (textEnd > textStart && isBlank(line[textEnd - 1])) textEnd -= 1
|
|
124
|
+
// Text that is nothing but a closing run keeps its first character.
|
|
125
|
+
return {
|
|
126
|
+
level: level as 1 | 2 | 3 | 4,
|
|
127
|
+
text: line.slice(textStart, Math.max(textEnd, textStart + 1)),
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Only these schemes become links; everything else is shown as its text. */
|
|
132
|
+
export function safeHref(value: string): string | undefined {
|
|
133
|
+
const trimmed = value.trim()
|
|
134
|
+
if (trimmed.length === 0 || trimmed.length > 2048) return undefined
|
|
135
|
+
// Control characters and whitespace inside a URL are a scheme-smuggling vector.
|
|
136
|
+
// oxlint-disable-next-line no-control-regex
|
|
137
|
+
if (/[\u0000- \u007f]/.test(trimmed)) return undefined
|
|
138
|
+
try {
|
|
139
|
+
const url = new URL(trimmed)
|
|
140
|
+
return url.protocol === 'http:' || url.protocol === 'https:' || url.protocol === 'mailto:'
|
|
141
|
+
? trimmed
|
|
142
|
+
: undefined
|
|
143
|
+
} catch {
|
|
144
|
+
return undefined
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const MAX_INLINE_DEPTH = 4
|
|
149
|
+
|
|
150
|
+
/** A marker may cite at most this many sources, so one cannot flood a sentence. */
|
|
151
|
+
const MAX_CITED_SOURCES = 6
|
|
152
|
+
const CITATION = /\[\^(\d{1,4}(?:[ \t]*,[ \t]*\d{1,4}){0,5})\]/y
|
|
153
|
+
|
|
154
|
+
export type ParseInlineOptions = {
|
|
155
|
+
/** How many sources the host has. Without it no marker is a citation. */
|
|
156
|
+
citations?: number
|
|
157
|
+
/** Inside a link label, where a citation (itself a button) must not nest. */
|
|
158
|
+
inLink?: boolean
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function citationAt(text: string, index: number, count: number): MessageInline | undefined {
|
|
162
|
+
CITATION.lastIndex = index
|
|
163
|
+
const match = CITATION.exec(text)
|
|
164
|
+
if (!match) return undefined
|
|
165
|
+
const numbers = [...new Set(match[1]!.split(',').map((part) => Number(part.trim())))]
|
|
166
|
+
if (numbers.length > MAX_CITED_SOURCES) return undefined
|
|
167
|
+
if (numbers.some((number) => number < 1 || number > count)) return undefined
|
|
168
|
+
return { kind: 'cite', numbers, raw: match[0] }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Inline spans. Delimiters must close on the same block, or they stay literal. */
|
|
172
|
+
export function parseInline(
|
|
173
|
+
text: string,
|
|
174
|
+
depth = 0,
|
|
175
|
+
options: ParseInlineOptions = {}
|
|
176
|
+
): readonly MessageInline[] {
|
|
177
|
+
const out: MessageInline[] = []
|
|
178
|
+
let brackets: ReadonlyMap<number, number> | undefined
|
|
179
|
+
let paren = -2
|
|
180
|
+
let buffer = ''
|
|
181
|
+
const flush = () => {
|
|
182
|
+
if (buffer) out.push({ kind: 'text', text: buffer })
|
|
183
|
+
buffer = ''
|
|
184
|
+
}
|
|
185
|
+
let index = 0
|
|
186
|
+
while (index < text.length) {
|
|
187
|
+
const char = text[index]!
|
|
188
|
+
if (char === '`') {
|
|
189
|
+
let ticks = 1
|
|
190
|
+
while (text[index + ticks] === '`') ticks += 1
|
|
191
|
+
const fence = '`'.repeat(ticks)
|
|
192
|
+
const close = text.indexOf(fence, index + ticks)
|
|
193
|
+
if (close > index + ticks) {
|
|
194
|
+
flush()
|
|
195
|
+
out.push({ kind: 'code', text: text.slice(index + ticks, close).replace(/^ (.*) $/, '$1') })
|
|
196
|
+
index = close + ticks
|
|
197
|
+
continue
|
|
198
|
+
}
|
|
199
|
+
buffer += fence
|
|
200
|
+
index += ticks
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
if (depth < MAX_INLINE_DEPTH && (char === '*' || char === '_')) {
|
|
204
|
+
const double = text[index + 1] === char
|
|
205
|
+
const delimiter = double ? char + char : char
|
|
206
|
+
const start = index + delimiter.length
|
|
207
|
+
// Word-internal underscores cannot open emphasis. Reject before scanning,
|
|
208
|
+
// and consume both marks so the second cannot rescan the remaining pairs.
|
|
209
|
+
if (char === '_' && index > 0 && /[A-Za-z0-9]/.test(text[index - 1] ?? '')) {
|
|
210
|
+
buffer += delimiter
|
|
211
|
+
index = start
|
|
212
|
+
continue
|
|
213
|
+
}
|
|
214
|
+
const next = text[start]
|
|
215
|
+
// A delimiter opens only before a non-space, so `a * b * c` and `2 * 3` stay arithmetic.
|
|
216
|
+
if (next !== undefined && !/\s/.test(next)) {
|
|
217
|
+
const close = findClosing(text, delimiter, start)
|
|
218
|
+
if (double && !(close > start && !/\s/.test(text[close - 1] ?? ' '))) {
|
|
219
|
+
// An opener that does not close stays literal as a pair. Retrying its
|
|
220
|
+
// second mark as emphasis would scan to the end of the line again, so a
|
|
221
|
+
// line of unclosed `**a ` would be quadratic.
|
|
222
|
+
buffer += delimiter
|
|
223
|
+
index = start
|
|
224
|
+
continue
|
|
225
|
+
}
|
|
226
|
+
if (close > start && !/\s/.test(text[close - 1] ?? ' ')) {
|
|
227
|
+
flush()
|
|
228
|
+
out.push({
|
|
229
|
+
kind: double ? 'strong' : 'em',
|
|
230
|
+
children: parseInline(text.slice(start, close), depth + 1, options),
|
|
231
|
+
})
|
|
232
|
+
index = close + delimiter.length
|
|
233
|
+
continue
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (char === '[' && text[index + 1] === '^' && options.citations && !options.inLink) {
|
|
238
|
+
const cite = citationAt(text, index, options.citations)
|
|
239
|
+
if (cite && cite.kind === 'cite') {
|
|
240
|
+
flush()
|
|
241
|
+
out.push(cite)
|
|
242
|
+
index += cite.raw.length
|
|
243
|
+
continue
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (depth < MAX_INLINE_DEPTH && char === '[') {
|
|
247
|
+
brackets ??= bracketMatches(text)
|
|
248
|
+
const labelEnd = brackets.get(index) ?? -1
|
|
249
|
+
if (labelEnd > index && text[labelEnd + 1] === '(') {
|
|
250
|
+
// The nearest `)` is remembered: a run of `[a](` with no `)` after it
|
|
251
|
+
// would otherwise search to the end of the text from every opener.
|
|
252
|
+
if (paren !== -1 && paren < labelEnd + 2) paren = text.indexOf(')', labelEnd + 2)
|
|
253
|
+
const hrefEnd = paren
|
|
254
|
+
if (hrefEnd > labelEnd + 1) {
|
|
255
|
+
const href = safeHref(text.slice(labelEnd + 2, hrefEnd))
|
|
256
|
+
if (href) {
|
|
257
|
+
flush()
|
|
258
|
+
out.push({
|
|
259
|
+
kind: 'link',
|
|
260
|
+
href,
|
|
261
|
+
children: parseInline(text.slice(index + 1, labelEnd), depth + 1, {
|
|
262
|
+
...options,
|
|
263
|
+
inLink: true,
|
|
264
|
+
}),
|
|
265
|
+
})
|
|
266
|
+
index = hrefEnd + 1
|
|
267
|
+
continue
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
buffer += char
|
|
273
|
+
index += 1
|
|
274
|
+
}
|
|
275
|
+
flush()
|
|
276
|
+
return out
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function findClosing(text: string, delimiter: string, from: number): number {
|
|
280
|
+
let index = from
|
|
281
|
+
while (index < text.length) {
|
|
282
|
+
if (text[index] === '`') {
|
|
283
|
+
// Skip a code span so `**a `**` b**` closes where the code ends.
|
|
284
|
+
const close = text.indexOf('`', index + 1)
|
|
285
|
+
if (close < 0) return -1
|
|
286
|
+
index = close + 1
|
|
287
|
+
continue
|
|
288
|
+
}
|
|
289
|
+
if (text[index] === delimiter[0]) {
|
|
290
|
+
let end = index + 1
|
|
291
|
+
while (text[end] === delimiter[0]) end += 1
|
|
292
|
+
const run = end - index
|
|
293
|
+
if (delimiter.length === 1) {
|
|
294
|
+
// Emphasis closes on a run of one (or an odd run, whose last mark closes).
|
|
295
|
+
// An even run is `**` pairs: strong spans inside the emphasis, which the
|
|
296
|
+
// inner parse reads. One pass, and the scan stops at the next odd run, so
|
|
297
|
+
// a line of unclosed delimiters is still linear.
|
|
298
|
+
if (run % 2 === 1) return end - 1
|
|
299
|
+
} else if (run >= delimiter.length) {
|
|
300
|
+
// Strong closes on the last two marks of a run.
|
|
301
|
+
return end - delimiter.length
|
|
302
|
+
}
|
|
303
|
+
index = end
|
|
304
|
+
continue
|
|
305
|
+
}
|
|
306
|
+
index += 1
|
|
307
|
+
}
|
|
308
|
+
return -1
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* The `]` that closes each `[`, found in one pass. A match never crosses a
|
|
313
|
+
* newline, and an unmatched `[` has no entry. Scanning forward from every `[`
|
|
314
|
+
* instead is quadratic on a long line of unclosed brackets, which a pasted page
|
|
315
|
+
* or a hostile model can use to hang the renderer.
|
|
316
|
+
*/
|
|
317
|
+
function bracketMatches(text: string): ReadonlyMap<number, number> {
|
|
318
|
+
const matches = new Map<number, number>()
|
|
319
|
+
const open: number[] = []
|
|
320
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
321
|
+
const char = text[index]
|
|
322
|
+
if (char === '[') open.push(index)
|
|
323
|
+
else if (char === ']') {
|
|
324
|
+
const start = open.pop()
|
|
325
|
+
if (start !== undefined) matches.set(start, index)
|
|
326
|
+
} else if (char === '\n') open.length = 0
|
|
327
|
+
}
|
|
328
|
+
return matches
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Parse text into blocks. Pure, total, and linear in the length of `text`. */
|
|
332
|
+
export function parseMessageText(
|
|
333
|
+
text: string,
|
|
334
|
+
options: { streaming?: boolean; citations?: number } = {}
|
|
335
|
+
): readonly MessageBlock[] {
|
|
336
|
+
const inline = (source: string) => parseInline(source, 0, { citations: options.citations })
|
|
337
|
+
const lines = text.replace(/\r\n?/g, '\n').split('\n')
|
|
338
|
+
const blocks: MessageBlock[] = []
|
|
339
|
+
let paragraph: string[] = []
|
|
340
|
+
const flushParagraph = () => {
|
|
341
|
+
if (paragraph.length === 0) return
|
|
342
|
+
const raw = paragraph.join('\n')
|
|
343
|
+
blocks.push({ kind: 'paragraph', inline: inline(raw), raw })
|
|
344
|
+
paragraph = []
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
let index = 0
|
|
348
|
+
while (index < lines.length) {
|
|
349
|
+
const line = lines[index]!
|
|
350
|
+
const fence = fenceOpen(line)
|
|
351
|
+
if (fence) {
|
|
352
|
+
flushParagraph()
|
|
353
|
+
const marker = fence.marker
|
|
354
|
+
const language = fence.language || undefined
|
|
355
|
+
const body: string[] = []
|
|
356
|
+
let closed = false
|
|
357
|
+
index += 1
|
|
358
|
+
while (index < lines.length) {
|
|
359
|
+
const candidate = lines[index]!
|
|
360
|
+
const close = /^ {0,3}(`{3,}|~{3,})[ \t]*$/.exec(candidate)
|
|
361
|
+
if (close && close[1]![0] === marker[0] && close[1]!.length >= marker.length) {
|
|
362
|
+
closed = true
|
|
363
|
+
index += 1
|
|
364
|
+
break
|
|
365
|
+
}
|
|
366
|
+
body.push(candidate)
|
|
367
|
+
index += 1
|
|
368
|
+
}
|
|
369
|
+
const code = body.join('\n')
|
|
370
|
+
blocks.push({
|
|
371
|
+
kind: 'code',
|
|
372
|
+
language,
|
|
373
|
+
code,
|
|
374
|
+
complete: closed || !options.streaming,
|
|
375
|
+
raw: `${marker}${language ?? ''}\n${code}${closed ? `\n${marker}` : ''}`,
|
|
376
|
+
})
|
|
377
|
+
continue
|
|
378
|
+
}
|
|
379
|
+
if (line.trim() === '') {
|
|
380
|
+
flushParagraph()
|
|
381
|
+
index += 1
|
|
382
|
+
continue
|
|
383
|
+
}
|
|
384
|
+
const heading = headingOf(line)
|
|
385
|
+
if (heading) {
|
|
386
|
+
flushParagraph()
|
|
387
|
+
blocks.push({
|
|
388
|
+
kind: 'heading',
|
|
389
|
+
level: heading.level,
|
|
390
|
+
inline: inline(heading.text),
|
|
391
|
+
raw: line,
|
|
392
|
+
})
|
|
393
|
+
index += 1
|
|
394
|
+
continue
|
|
395
|
+
}
|
|
396
|
+
const bullet = BULLET.exec(line)
|
|
397
|
+
const ordered = bullet ? null : ORDERED.exec(line)
|
|
398
|
+
if (bullet || ordered) {
|
|
399
|
+
flushParagraph()
|
|
400
|
+
const items: MessageInline[][] = []
|
|
401
|
+
const rawLines: string[] = []
|
|
402
|
+
const isOrdered = ordered !== null
|
|
403
|
+
const start = ordered ? Number(ordered[1]) : 1
|
|
404
|
+
while (index < lines.length) {
|
|
405
|
+
const current = lines[index]!
|
|
406
|
+
const match = isOrdered ? ORDERED.exec(current) : BULLET.exec(current)
|
|
407
|
+
if (match) {
|
|
408
|
+
items.push([...inline(isOrdered ? match[2]! : match[1]!)])
|
|
409
|
+
rawLines.push(current)
|
|
410
|
+
index += 1
|
|
411
|
+
continue
|
|
412
|
+
}
|
|
413
|
+
// An indented continuation belongs to the previous item.
|
|
414
|
+
if (/^ {2,}\S/.test(current) && items.length > 0) {
|
|
415
|
+
// Append in place: copying the accumulated spans on every continuation
|
|
416
|
+
// makes a long item quadratic in its number of lines. Push one span at
|
|
417
|
+
// a time, because spreading a line of many spans into `push` exceeds
|
|
418
|
+
// the engine's argument limit and throws.
|
|
419
|
+
const item = items[items.length - 1]!
|
|
420
|
+
item.push({ kind: 'text', text: ' ' })
|
|
421
|
+
for (const span of inline(current.trim())) item.push(span)
|
|
422
|
+
rawLines.push(current)
|
|
423
|
+
index += 1
|
|
424
|
+
continue
|
|
425
|
+
}
|
|
426
|
+
break
|
|
427
|
+
}
|
|
428
|
+
blocks.push({ kind: 'list', ordered: isOrdered, start, items, raw: rawLines.join('\n') })
|
|
429
|
+
continue
|
|
430
|
+
}
|
|
431
|
+
const quote = QUOTE.exec(line)
|
|
432
|
+
if (quote) {
|
|
433
|
+
flushParagraph()
|
|
434
|
+
const quoted: string[] = []
|
|
435
|
+
while (index < lines.length) {
|
|
436
|
+
const match = QUOTE.exec(lines[index]!)
|
|
437
|
+
if (!match) break
|
|
438
|
+
quoted.push(match[1]!)
|
|
439
|
+
index += 1
|
|
440
|
+
}
|
|
441
|
+
const raw = quoted.join('\n')
|
|
442
|
+
blocks.push({ kind: 'quote', inline: inline(raw), raw })
|
|
443
|
+
continue
|
|
444
|
+
}
|
|
445
|
+
paragraph.push(line)
|
|
446
|
+
index += 1
|
|
447
|
+
}
|
|
448
|
+
flushParagraph()
|
|
449
|
+
return blocks
|
|
450
|
+
}
|