@aceshooting/lyra-ui 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/custom-elements.json +21460 -8489
- package/dist/components/app-rail/app-rail.d.ts +171 -0
- package/dist/components/app-rail/app-rail.js +483 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +125 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
- package/dist/components/attachment-chip/attachment-chip.js +312 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
- package/dist/components/chart/box-plot.js +11 -1
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +12 -2
- package/dist/components/chart/chart.js +121 -14
- package/dist/components/chart/histogram-bin.d.ts +4 -1
- package/dist/components/chart/histogram-bin.js +24 -14
- package/dist/components/chart/lite-chart.d.ts +63 -0
- package/dist/components/chart/lite-chart.js +181 -23
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chat-composer/chat-composer.d.ts +92 -0
- package/dist/components/chat-composer/chat-composer.js +285 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +135 -0
- package/dist/components/chat-message/chat-message.d.ts +113 -0
- package/dist/components/chat-message/chat-message.js +291 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +59 -0
- package/dist/components/checkbox/checkbox.js +230 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +70 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +124 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +115 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +300 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +89 -0
- package/dist/components/code-block/code-block.js +317 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +44 -0
- package/dist/components/code-block/code-loader.js +79 -0
- package/dist/components/combobox/combobox.d.ts +19 -1
- package/dist/components/combobox/combobox.js +84 -14
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +150 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +120 -0
- package/dist/components/conversation-item/conversation-item.d.ts +128 -0
- package/dist/components/conversation-item/conversation-item.js +322 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/date-input.d.ts +24 -0
- package/dist/components/date-picker/date-input.js +134 -22
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +85 -16
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +79 -0
- package/dist/components/dialog/dialog.d.ts +85 -0
- package/dist/components/dialog/dialog.js +272 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +52 -0
- package/dist/components/dock-panel/dock-panel.d.ts +134 -0
- package/dist/components/dock-panel/dock-panel.js +345 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +145 -0
- package/dist/components/document-preview/document-preview.d.ts +135 -0
- package/dist/components/document-preview/document-preview.js +372 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.js +2 -0
- package/dist/components/flag/flag.d.ts +42 -5
- package/dist/components/flag/flag.js +70 -3
- package/dist/components/gauge/gauge.js +19 -10
- package/dist/components/generation-status/generation-status.d.ts +109 -0
- package/dist/components/generation-status/generation-status.js +273 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/heatmap/calendar-grid.d.ts +4 -1
- package/dist/components/heatmap/calendar-grid.js +25 -12
- package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
- package/dist/components/heatmap/heatmap-scale.js +7 -1
- package/dist/components/heatmap/heatmap.d.ts +89 -3
- package/dist/components/heatmap/heatmap.js +158 -29
- package/dist/components/json-viewer/json-viewer.d.ts +53 -0
- package/dist/components/json-viewer/json-viewer.js +283 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +176 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +214 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +81 -0
- package/dist/components/live-region/live-region.js +153 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +8 -6
- package/dist/components/map/map.js +44 -8
- package/dist/components/markdown/markdown-loader.d.ts +34 -0
- package/dist/components/markdown/markdown-loader.js +43 -0
- package/dist/components/markdown/markdown.d.ts +81 -0
- package/dist/components/markdown/markdown.js +284 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +82 -0
- package/dist/components/media-card/media-card.d.ts +122 -0
- package/dist/components/media-card/media-card.js +295 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +200 -0
- package/dist/components/mention-popover/mention-popover.js +475 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +62 -0
- package/dist/components/menu/menu-item.js +119 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +67 -0
- package/dist/components/menu/menu.d.ts +143 -0
- package/dist/components/menu/menu.js +365 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +66 -0
- package/dist/components/model-select/model-select.d.ts +125 -0
- package/dist/components/model-select/model-select.js +490 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +189 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +13 -1
- package/dist/components/playback/playback.js +47 -14
- package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
- package/dist/components/responsive-panel/responsive-panel.js +365 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +44 -0
- package/dist/components/result-card/result-card.js +83 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +50 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +45 -1
- package/dist/components/select/select.js +114 -17
- package/dist/components/select/select.styles.js +26 -2
- package/dist/components/slider/slider.d.ts +89 -0
- package/dist/components/slider/slider.js +352 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +92 -0
- package/dist/components/source-card/source-card.js +148 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +122 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +27 -13
- package/dist/components/split/split.d.ts +93 -1
- package/dist/components/split/split.js +284 -15
- package/dist/components/split/split.styles.js +30 -0
- package/dist/components/stat/stat.d.ts +22 -1
- package/dist/components/stat/stat.js +49 -3
- package/dist/components/stat/stat.styles.js +20 -0
- package/dist/components/stream-status/stream-status.d.ts +110 -0
- package/dist/components/stream-status/stream-status.js +210 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +98 -0
- package/dist/components/streaming-text/streaming-text.js +209 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +62 -0
- package/dist/components/switch/switch.d.ts +58 -0
- package/dist/components/switch/switch.js +179 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +73 -4
- package/dist/components/table/table.js +169 -20
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +51 -0
- package/dist/components/tabs/tabs.js +190 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +63 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
- package/dist/components/thinking-panel/thinking-panel.js +235 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
- package/dist/components/toast/toast-item.d.ts +1 -0
- package/dist/components/toast/toast-item.js +31 -6
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
- package/dist/components/tool-param-form/tool-param-form.js +366 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +81 -0
- package/dist/components/tool-result-view/registry.js +84 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
- package/dist/components/tool-result-view/tool-result-view.js +138 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
- package/dist/components/tree/tree-node.d.ts +11 -2
- package/dist/components/tree/tree-node.js +16 -6
- package/dist/components/tree/tree.d.ts +8 -2
- package/dist/components/tree/tree.js +18 -11
- package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
- package/dist/components/typing-indicator/typing-indicator.js +96 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +173 -0
- package/dist/components/virtual-list/virtual-list.js +461 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +44 -0
- package/dist/components/widget/widget.d.ts +10 -0
- package/dist/components/widget/widget.js +24 -1
- package/dist/components/widget/widget.styles.js +9 -2
- package/dist/components/word-cloud/word-cloud-layout.js +14 -1
- package/dist/components/word-cloud/word-cloud.d.ts +6 -0
- package/dist/components/word-cloud/word-cloud.js +25 -14
- package/dist/components/word-cloud/word-cloud.styles.js +4 -2
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +1 -0
- package/dist/internal/form-associated.js +55 -11
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +6 -0
- package/dist/lyra.d.ts +130 -31
- package/dist/lyra.js +94 -26
- package/llms-full.txt +3921 -32
- package/llms.txt +16 -1
- package/package.json +23 -5
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -12
- package/dist/components/chart/lite-chart.stories.js +0 -98
- package/dist/components/chart/pie-chart.stories.d.ts +0 -5
- package/dist/components/chart/pie-chart.stories.js +0 -26
- package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
- package/dist/components/chart/polar-area-chart.stories.js +0 -20
- package/dist/components/chart/radar-chart.stories.d.ts +0 -5
- package/dist/components/chart/radar-chart.stories.js +0 -20
- package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
- package/dist/components/chart/scatter-chart.stories.js +0 -31
- package/dist/components/combobox/combobox.stories.d.ts +0 -24
- package/dist/components/combobox/combobox.stories.js +0 -102
- package/dist/components/date-picker/date-input.stories.d.ts +0 -10
- package/dist/components/date-picker/date-input.stories.js +0 -48
- package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
- package/dist/components/date-picker/date-picker.stories.js +0 -25
- package/dist/components/empty/empty.stories.d.ts +0 -7
- package/dist/components/empty/empty.stories.js +0 -34
- package/dist/components/export-button/export-button.stories.d.ts +0 -7
- package/dist/components/export-button/export-button.stories.js +0 -37
- package/dist/components/file-input/file-input.stories.d.ts +0 -7
- package/dist/components/file-input/file-input.stories.js +0 -19
- package/dist/components/flag/flag.stories.d.ts +0 -5
- package/dist/components/flag/flag.stories.js +0 -17
- package/dist/components/gauge/gauge.stories.d.ts +0 -8
- package/dist/components/gauge/gauge.stories.js +0 -19
- package/dist/components/graph/graph.stories.d.ts +0 -8
- package/dist/components/graph/graph.stories.js +0 -68
- package/dist/components/heatmap/heatmap.stories.d.ts +0 -22
- package/dist/components/heatmap/heatmap.stories.js +0 -154
- package/dist/components/map/map.stories.d.ts +0 -15
- package/dist/components/map/map.stories.js +0 -135
- package/dist/components/playback/playback.stories.d.ts +0 -7
- package/dist/components/playback/playback.stories.js +0 -16
- package/dist/components/select/select.stories.d.ts +0 -19
- package/dist/components/select/select.stories.js +0 -75
- package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
- package/dist/components/skeleton/skeleton.stories.js +0 -16
- package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
- package/dist/components/sparkline/sparkline.stories.js +0 -39
- package/dist/components/split/split.stories.d.ts +0 -7
- package/dist/components/split/split.stories.js +0 -36
- package/dist/components/stat/stat.stories.d.ts +0 -8
- package/dist/components/stat/stat.stories.js +0 -64
- package/dist/components/table/table.stories.d.ts +0 -12
- package/dist/components/table/table.stories.js +0 -67
- package/dist/components/time-range/time-range.stories.d.ts +0 -8
- package/dist/components/time-range/time-range.stories.js +0 -26
- package/dist/components/toast/toast.stories.d.ts +0 -8
- package/dist/components/toast/toast.stories.js +0 -72
- package/dist/components/tree/tree.stories.d.ts +0 -9
- package/dist/components/tree/tree.stories.js +0 -52
- package/dist/components/widget/widget.stories.d.ts +0 -7
- package/dist/components/widget/widget.stories.js +0 -41
- package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
- package/dist/components/word-cloud/word-cloud.stories.js +0 -55
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, svg, nothing } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { place } from '../../internal/positioner.js';
|
|
12
|
+
import { styles } from './tool-call-chip.styles.js';
|
|
13
|
+
// Mirrors the shared icon set's viewBox/stroke conventions
|
|
14
|
+
// (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without adding
|
|
15
|
+
// tool-call-specific glyphs to that module -- it's off limits here -- so
|
|
16
|
+
// these still read as part of the same visual language as the rest of the
|
|
17
|
+
// library's inline icons. Same approach lyra-checkbox's/lyra-chat-message's
|
|
18
|
+
// own local glyphs take for the identical reason, and deliberately the same
|
|
19
|
+
// shapes lyra-tool-result-dialog's own local glyphs use, so a call reads
|
|
20
|
+
// identically whether it's shown as this inline chip or in that dialog.
|
|
21
|
+
const ICON_VIEW_BOX = '0 0 24 24';
|
|
22
|
+
const ICON_STROKE_WIDTH = '1.75';
|
|
23
|
+
function icon(paths) {
|
|
24
|
+
return svg `
|
|
25
|
+
<svg
|
|
26
|
+
width="1em"
|
|
27
|
+
height="1em"
|
|
28
|
+
viewBox=${ICON_VIEW_BOX}
|
|
29
|
+
fill="none"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
stroke-width=${ICON_STROKE_WIDTH}
|
|
32
|
+
stroke-linecap="round"
|
|
33
|
+
stroke-linejoin="round"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
focusable="false"
|
|
36
|
+
>${paths}</svg>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
function pendingIcon() {
|
|
40
|
+
return icon(svg `<circle cx="12" cy="12" r="9"></circle><polyline points="12 7 12 12 15 14"></polyline>`);
|
|
41
|
+
}
|
|
42
|
+
/** A three-quarter arc, spun by the `:host([status="running"]) [part="icon"] svg`
|
|
43
|
+
* CSS animation -- a full circle wouldn't visibly convey rotation. */
|
|
44
|
+
function runningIcon() {
|
|
45
|
+
return icon(svg `<path d="M21 12a9 9 0 1 1-9-9"></path>`);
|
|
46
|
+
}
|
|
47
|
+
function successIcon() {
|
|
48
|
+
return icon(svg `<circle cx="12" cy="12" r="9"></circle><polyline points="8 12.5 11 15.5 16 9.5"></polyline>`);
|
|
49
|
+
}
|
|
50
|
+
function errorIcon() {
|
|
51
|
+
return icon(svg `
|
|
52
|
+
<circle cx="12" cy="12" r="9"></circle>
|
|
53
|
+
<line x1="9" y1="9" x2="15" y2="15"></line>
|
|
54
|
+
<line x1="15" y1="9" x2="9" y2="15"></line>
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
/** A "blocked" glyph (circle + diagonal slash) -- distinct from `errorIcon()`
|
|
58
|
+
* since a denial is a policy rejection, not a runtime failure. */
|
|
59
|
+
function deniedIcon() {
|
|
60
|
+
return icon(svg `<circle cx="12" cy="12" r="9"></circle><line x1="6" y1="18" x2="18" y2="6"></line>`);
|
|
61
|
+
}
|
|
62
|
+
const STATUS_ICON = {
|
|
63
|
+
pending: pendingIcon,
|
|
64
|
+
running: runningIcon,
|
|
65
|
+
success: successIcon,
|
|
66
|
+
error: errorIcon,
|
|
67
|
+
denied: deniedIcon,
|
|
68
|
+
};
|
|
69
|
+
/** Visible (not just color-coded) text for every status. */
|
|
70
|
+
const STATUS_LABEL = {
|
|
71
|
+
pending: 'Pending',
|
|
72
|
+
running: 'Running',
|
|
73
|
+
success: 'Success',
|
|
74
|
+
error: 'Error',
|
|
75
|
+
denied: 'Denied',
|
|
76
|
+
};
|
|
77
|
+
/** `820` -> `"820ms"`; `1500` -> `"1.5s"`; `2000` -> `"2s"`. Sub-second
|
|
78
|
+
* durations are the common case for a single tool call, so they get the
|
|
79
|
+
* more precise unit; once a call runs a full second or longer, trimming to
|
|
80
|
+
* (at most) one decimal place of seconds reads better than a 4-5 digit
|
|
81
|
+
* millisecond count. Identical algorithm to lyra-tool-result-dialog's own
|
|
82
|
+
* `formatDuration` -- duplicated rather than imported (these are two
|
|
83
|
+
* independent, separately-consumable components; see this file's header
|
|
84
|
+
* comment on the icon glyphs for the same rationale) but kept in lockstep
|
|
85
|
+
* so the same call reports the same duration text in both places. */
|
|
86
|
+
function formatDuration(ms) {
|
|
87
|
+
if (!Number.isFinite(ms) || ms < 1000) {
|
|
88
|
+
return `${Math.round(Math.max(0, ms))}ms`;
|
|
89
|
+
}
|
|
90
|
+
const seconds = ms / 1000;
|
|
91
|
+
const rounded = Math.round(seconds * 10) / 10;
|
|
92
|
+
return `${Number.isInteger(rounded) ? rounded.toFixed(0) : rounded.toFixed(1)}s`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* `<lyra-tool-call-chip>` — a compact inline pill representing one tool/
|
|
96
|
+
* function call an agent made mid-conversation, e.g.
|
|
97
|
+
* `web_search: Searching web…` with a `running` spinner. It owns no detail
|
|
98
|
+
* surface of its own: clicking (or Enter/Space-activating) it only fires
|
|
99
|
+
* `lyra-tool-chip-select` — a consumer wires that to opening a
|
|
100
|
+
* `<lyra-tool-result-dialog>` (or anything else) at the call site. Keeping
|
|
101
|
+
* the two decoupled means a chip can be reused wherever a compact call
|
|
102
|
+
* summary is useful, with or without a detail surface behind it.
|
|
103
|
+
*
|
|
104
|
+
* The default slot is *not* the chip's visible content — the chip's own
|
|
105
|
+
* label is always built from `name`/`summary`/`status`/`duration-ms`. It's
|
|
106
|
+
* reserved for optional rich detail content (e.g. the tool's raw arguments,
|
|
107
|
+
* a short preview) shown in a floating tooltip on hover/focus, positioned
|
|
108
|
+
* with `internal/positioner.js`'s `place()` the same way `<lyra-combobox>`
|
|
109
|
+
* positions its listbox. No tooltip is shown at all when the slot carries no
|
|
110
|
+
* content — hovering an empty chip does nothing.
|
|
111
|
+
*
|
|
112
|
+
* The `icon` slot overrides the built-in per-status glyph entirely via the
|
|
113
|
+
* platform's own slot-fallback-content mechanism (`<slot
|
|
114
|
+
* name="icon">${fallback}</slot>` — the same pattern `<lyra-stat>`'s
|
|
115
|
+
* `caption` slot and `<lyra-file-input>`'s default slot already use):
|
|
116
|
+
* whatever is assigned to `slot="icon"` wins; otherwise the `icon` prop is
|
|
117
|
+
* rendered as a literal hint (e.g. an emoji); otherwise the built-in glyph
|
|
118
|
+
* for the current `status` is used.
|
|
119
|
+
*
|
|
120
|
+
* @customElement lyra-tool-call-chip
|
|
121
|
+
* @slot - Rich tooltip/detail content, shown on hover/focus. Nothing renders
|
|
122
|
+
* (no hover affordance at all) when this slot is empty.
|
|
123
|
+
* @slot icon - Overrides the built-in status glyph entirely.
|
|
124
|
+
* @event lyra-tool-chip-select - The chip was activated (click or Enter/Space
|
|
125
|
+
* while focused). `detail: { name, callId }`.
|
|
126
|
+
* @csspart base - The clickable pill (`<button>`).
|
|
127
|
+
* @csspart icon - Wrapper around the status glyph / `icon` slot.
|
|
128
|
+
* @csspart label - Wrapper around `category`, `name` and `summary`.
|
|
129
|
+
* @csspart category - The optional grouping label.
|
|
130
|
+
* @csspart name - The tool/function name.
|
|
131
|
+
* @csspart summary - The short status text.
|
|
132
|
+
* @csspart meta - Wrapper around `status-text` and `duration`.
|
|
133
|
+
* @csspart status-text - The visible text twin of the status glyph/color — carries the state in text, not just color.
|
|
134
|
+
* @csspart duration - The formatted `duration-ms`, when set.
|
|
135
|
+
* @csspart tooltip - The floating detail popup (only meaningful while open).
|
|
136
|
+
*/
|
|
137
|
+
export class LyraToolCallChip extends LyraElement {
|
|
138
|
+
constructor() {
|
|
139
|
+
super(...arguments);
|
|
140
|
+
/** The tool/function name, e.g. `web_search`. */
|
|
141
|
+
this.name = '';
|
|
142
|
+
/** Optional grouping label, e.g. `research`. */
|
|
143
|
+
this.category = '';
|
|
144
|
+
/** The call's current lifecycle state — drives the glyph, color, and `status-text`. */
|
|
145
|
+
this.status = 'pending';
|
|
146
|
+
/** Short human-readable status text, e.g. `Searching web…`. */
|
|
147
|
+
this.summary = '';
|
|
148
|
+
/** Literal icon hint (e.g. an emoji) used when the `icon` slot is empty — see the class doc's
|
|
149
|
+
* icon-precedence note. Ignored once anything is assigned to `slot="icon"`. */
|
|
150
|
+
this.icon = '';
|
|
151
|
+
/** Unique identifier for this specific invocation — echoed back in `lyra-tool-chip-select`'s
|
|
152
|
+
* detail so a listener can correlate the click with the call it fired for. */
|
|
153
|
+
this.callId = '';
|
|
154
|
+
// Same fix lyra-stat's hasIcon/lyra-combobox's hasHintSlot etc. already
|
|
155
|
+
// establish: a `[part]` always contains a literal `<slot>` child regardless
|
|
156
|
+
// of assigned content, so `:empty` never matches -- real emptiness is
|
|
157
|
+
// tracked in JS instead. Only element children count (mirrors lyra-stat's
|
|
158
|
+
// identical default-slot check) since the tooltip's rich content is
|
|
159
|
+
// expected to be markup, not a bare text node.
|
|
160
|
+
this.hasDetailSlot = false;
|
|
161
|
+
this.tooltipOpen = false;
|
|
162
|
+
this.onDetailSlotChange = (e) => {
|
|
163
|
+
this.hasDetailSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
164
|
+
};
|
|
165
|
+
this.showTooltip = () => {
|
|
166
|
+
if (!this.hasDetailSlot || this.tooltipOpen)
|
|
167
|
+
return;
|
|
168
|
+
this.tooltipOpen = true;
|
|
169
|
+
};
|
|
170
|
+
// Unconditional on blur/mouseleave, with no "did the pointer move into the
|
|
171
|
+
// tooltip itself" check -- the default slot is documented as read-only
|
|
172
|
+
// preview content (raw args, a short snippet), not an interactive surface
|
|
173
|
+
// meant to retain focus/hover of its own, so this stays as simple as a
|
|
174
|
+
// native `title` attribute's show/hide instead of adding a second
|
|
175
|
+
// pointer-tracking region.
|
|
176
|
+
this.hideTooltip = () => {
|
|
177
|
+
if (!this.tooltipOpen)
|
|
178
|
+
return;
|
|
179
|
+
this.tooltipOpen = false;
|
|
180
|
+
};
|
|
181
|
+
this.onKeyDown = (e) => {
|
|
182
|
+
// The native <button> already handles Enter/Space activation on its
|
|
183
|
+
// own -- this only needs to cover dismissing the (non-native) tooltip,
|
|
184
|
+
// the same Escape-to-close convention every other popup in this library
|
|
185
|
+
// follows (see lyra-combobox's onKeyDown).
|
|
186
|
+
if (e.key === 'Escape' && this.tooltipOpen) {
|
|
187
|
+
e.stopPropagation();
|
|
188
|
+
this.hideTooltip();
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
this.onClick = () => {
|
|
192
|
+
this.emit('lyra-tool-chip-select', { name: this.name, callId: this.callId });
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
196
|
+
willUpdate() {
|
|
197
|
+
if (!this.hasUpdated) {
|
|
198
|
+
this.hasDetailSlot = Array.from(this.children).some((el) => !el.hasAttribute('slot'));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
updated(changed) {
|
|
202
|
+
if (changed.has('tooltipOpen')) {
|
|
203
|
+
this.cleanupPositioner?.();
|
|
204
|
+
this.cleanupPositioner = undefined;
|
|
205
|
+
if (this.tooltipOpen) {
|
|
206
|
+
const anchor = this.renderRoot.querySelector('[part="base"]');
|
|
207
|
+
const tooltip = this.renderRoot.querySelector('[part="tooltip"]');
|
|
208
|
+
if (anchor && tooltip)
|
|
209
|
+
this.cleanupPositioner = place(anchor, tooltip, { placement: 'top-start' });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
disconnectedCallback() {
|
|
214
|
+
super.disconnectedCallback();
|
|
215
|
+
this.cleanupPositioner?.();
|
|
216
|
+
}
|
|
217
|
+
get accessibleLabel() {
|
|
218
|
+
const parts = [this.name || 'Tool call'];
|
|
219
|
+
if (this.summary)
|
|
220
|
+
parts.push(this.summary);
|
|
221
|
+
parts.push(STATUS_LABEL[this.status]);
|
|
222
|
+
if (this.durationMs != null && Number.isFinite(this.durationMs))
|
|
223
|
+
parts.push(formatDuration(this.durationMs));
|
|
224
|
+
return parts.join(' — ');
|
|
225
|
+
}
|
|
226
|
+
render() {
|
|
227
|
+
const hasCategory = this.category.length > 0;
|
|
228
|
+
const hasSummary = this.summary.length > 0;
|
|
229
|
+
const hasDuration = this.durationMs != null && Number.isFinite(this.durationMs);
|
|
230
|
+
return html `
|
|
231
|
+
<button
|
|
232
|
+
part="base"
|
|
233
|
+
type="button"
|
|
234
|
+
aria-label=${this.getAttribute('aria-label') || this.accessibleLabel}
|
|
235
|
+
@click=${this.onClick}
|
|
236
|
+
@mouseenter=${this.showTooltip}
|
|
237
|
+
@mouseleave=${this.hideTooltip}
|
|
238
|
+
@focus=${this.showTooltip}
|
|
239
|
+
@blur=${this.hideTooltip}
|
|
240
|
+
@keydown=${this.onKeyDown}
|
|
241
|
+
>
|
|
242
|
+
<span part="icon" aria-hidden="true">
|
|
243
|
+
<slot name="icon">${this.icon ? this.icon : STATUS_ICON[this.status]()}</slot>
|
|
244
|
+
</span>
|
|
245
|
+
<span part="label">
|
|
246
|
+
<span part="category" ?hidden=${!hasCategory}>${this.category}</span>
|
|
247
|
+
<span part="name">${this.name || 'Tool call'}</span>
|
|
248
|
+
<span part="summary" ?hidden=${!hasSummary}>${this.summary}</span>
|
|
249
|
+
</span>
|
|
250
|
+
<span part="meta">
|
|
251
|
+
<span part="status-text">${STATUS_LABEL[this.status]}</span>
|
|
252
|
+
<span part="duration" ?hidden=${!hasDuration}>${hasDuration ? formatDuration(this.durationMs) : nothing}</span>
|
|
253
|
+
</span>
|
|
254
|
+
</button>
|
|
255
|
+
<div part="tooltip" role="tooltip" ?hidden=${!this.tooltipOpen}>
|
|
256
|
+
<slot @slotchange=${this.onDetailSlotChange}></slot>
|
|
257
|
+
</div>
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
__decorate([
|
|
262
|
+
property()
|
|
263
|
+
], LyraToolCallChip.prototype, "name", void 0);
|
|
264
|
+
__decorate([
|
|
265
|
+
property()
|
|
266
|
+
], LyraToolCallChip.prototype, "category", void 0);
|
|
267
|
+
__decorate([
|
|
268
|
+
property({ reflect: true })
|
|
269
|
+
], LyraToolCallChip.prototype, "status", void 0);
|
|
270
|
+
__decorate([
|
|
271
|
+
property()
|
|
272
|
+
], LyraToolCallChip.prototype, "summary", void 0);
|
|
273
|
+
__decorate([
|
|
274
|
+
property({ type: Number, attribute: 'duration-ms' })
|
|
275
|
+
], LyraToolCallChip.prototype, "durationMs", void 0);
|
|
276
|
+
__decorate([
|
|
277
|
+
property()
|
|
278
|
+
], LyraToolCallChip.prototype, "icon", void 0);
|
|
279
|
+
__decorate([
|
|
280
|
+
property({ attribute: 'call-id' })
|
|
281
|
+
], LyraToolCallChip.prototype, "callId", void 0);
|
|
282
|
+
__decorate([
|
|
283
|
+
state()
|
|
284
|
+
], LyraToolCallChip.prototype, "hasDetailSlot", void 0);
|
|
285
|
+
__decorate([
|
|
286
|
+
state()
|
|
287
|
+
], LyraToolCallChip.prototype, "tooltipOpen", void 0);
|
|
288
|
+
defineElement('tool-call-chip', LyraToolCallChip);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
max-inline-size: 100%;
|
|
6
|
+
/* Per-status accent -- one custom property swapped by the :host([status])
|
|
7
|
+
rules below rather than repeating background/color per part per status.
|
|
8
|
+
Defaults to the 'pending' tone so an unset/unknown status still reads
|
|
9
|
+
as neutral instead of unstyled. */
|
|
10
|
+
--lyra-tool-call-chip-accent: var(--lyra-color-text-quiet);
|
|
11
|
+
--lyra-tool-call-chip-bg: var(--lyra-color-surface);
|
|
12
|
+
--lyra-tool-call-chip-border: var(--lyra-color-border);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:host([status='running']) {
|
|
16
|
+
--lyra-tool-call-chip-accent: var(--lyra-color-brand);
|
|
17
|
+
--lyra-tool-call-chip-bg: var(--lyra-color-brand-quiet);
|
|
18
|
+
--lyra-tool-call-chip-border: transparent;
|
|
19
|
+
}
|
|
20
|
+
:host([status='success']) {
|
|
21
|
+
--lyra-tool-call-chip-accent: var(--lyra-color-success);
|
|
22
|
+
--lyra-tool-call-chip-bg: var(--lyra-color-success-quiet);
|
|
23
|
+
--lyra-tool-call-chip-border: transparent;
|
|
24
|
+
}
|
|
25
|
+
:host([status='error']) {
|
|
26
|
+
--lyra-tool-call-chip-accent: var(--lyra-color-danger);
|
|
27
|
+
--lyra-tool-call-chip-bg: var(--lyra-color-danger-quiet);
|
|
28
|
+
--lyra-tool-call-chip-border: transparent;
|
|
29
|
+
}
|
|
30
|
+
/* 'denied' reads as a policy rejection, not a runtime failure -- the
|
|
31
|
+
warning (not danger) tint keeps it visually distinct from 'error',
|
|
32
|
+
matching lyra-tool-result-dialog's identical status vocabulary/tone so
|
|
33
|
+
the two components agree on what "denied" looks like. */
|
|
34
|
+
:host([status='denied']) {
|
|
35
|
+
--lyra-tool-call-chip-accent: var(--lyra-color-warning);
|
|
36
|
+
--lyra-tool-call-chip-bg: var(--lyra-color-warning-quiet);
|
|
37
|
+
--lyra-tool-call-chip-border: transparent;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[part='base'] {
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: var(--lyra-space-xs);
|
|
44
|
+
max-inline-size: 100%;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
padding: 0.25rem var(--lyra-space-s);
|
|
47
|
+
border: 1px solid var(--lyra-tool-call-chip-border);
|
|
48
|
+
border-radius: 999px;
|
|
49
|
+
background: var(--lyra-tool-call-chip-bg);
|
|
50
|
+
color: var(--lyra-color-text);
|
|
51
|
+
font: inherit;
|
|
52
|
+
font-size: 0.8125rem;
|
|
53
|
+
line-height: 1.3;
|
|
54
|
+
text-align: start;
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
-webkit-tap-highlight-color: transparent;
|
|
57
|
+
transition:
|
|
58
|
+
background-color var(--lyra-transition-fast),
|
|
59
|
+
border-color var(--lyra-transition-fast);
|
|
60
|
+
}
|
|
61
|
+
[part='base']:hover {
|
|
62
|
+
border-color: var(--lyra-color-brand);
|
|
63
|
+
}
|
|
64
|
+
[part='base']:focus-visible {
|
|
65
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
66
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[part='icon'] {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
flex: 0 0 auto;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
color: var(--lyra-tool-call-chip-accent);
|
|
75
|
+
}
|
|
76
|
+
[part='icon'] svg {
|
|
77
|
+
display: block;
|
|
78
|
+
}
|
|
79
|
+
/* A three-quarter arc (not a full ring) is what actually reads as
|
|
80
|
+
spinning once rotated -- a full circle looks identical at every
|
|
81
|
+
rotation frame. */
|
|
82
|
+
:host([status='running']) [part='icon'] svg {
|
|
83
|
+
animation: lyra-tool-call-chip-spin 1s linear infinite;
|
|
84
|
+
}
|
|
85
|
+
/* Subtler than the spin -- a slow opacity breathe, so a list of several
|
|
86
|
+
still-queued chips doesn't compete visually with any 'running' ones
|
|
87
|
+
next to it. */
|
|
88
|
+
:host([status='pending']) [part='icon'] svg {
|
|
89
|
+
animation: lyra-tool-call-chip-pulse 1.5s ease-in-out infinite;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
[part='label'] {
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
align-items: baseline;
|
|
95
|
+
gap: 0.3em;
|
|
96
|
+
flex: 1 1 auto;
|
|
97
|
+
min-inline-size: 0;
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
}
|
|
100
|
+
[part='category'] {
|
|
101
|
+
flex: 0 0 auto;
|
|
102
|
+
/* Full-strength text, not --lyra-color-text-quiet -- this sits on top of
|
|
103
|
+
the per-status *-quiet tint backgrounds above (e.g. success-quiet),
|
|
104
|
+
and text-quiet's gray fails WCAG AA contrast against several of those
|
|
105
|
+
tints even though it comfortably passes against the plain surface
|
|
106
|
+
background used by the resting/denied states. */
|
|
107
|
+
color: var(--lyra-color-text);
|
|
108
|
+
font-size: 0.6875rem;
|
|
109
|
+
font-weight: 600;
|
|
110
|
+
text-transform: uppercase;
|
|
111
|
+
letter-spacing: 0.04em;
|
|
112
|
+
}
|
|
113
|
+
[part='category']::after {
|
|
114
|
+
content: '·';
|
|
115
|
+
margin-inline-start: 0.3em;
|
|
116
|
+
}
|
|
117
|
+
[part='name'] {
|
|
118
|
+
flex: 0 1 auto;
|
|
119
|
+
min-inline-size: 0;
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
text-overflow: ellipsis;
|
|
122
|
+
white-space: nowrap;
|
|
123
|
+
font-weight: 600;
|
|
124
|
+
}
|
|
125
|
+
[part='summary'] {
|
|
126
|
+
flex: 1 1 auto;
|
|
127
|
+
min-inline-size: 3ch;
|
|
128
|
+
overflow: hidden;
|
|
129
|
+
text-overflow: ellipsis;
|
|
130
|
+
white-space: nowrap;
|
|
131
|
+
/* See [part='category']'s comment above -- same contrast rationale. */
|
|
132
|
+
color: var(--lyra-color-text);
|
|
133
|
+
}
|
|
134
|
+
[part='summary']::before {
|
|
135
|
+
content: ': ';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
[part='meta'] {
|
|
139
|
+
display: inline-flex;
|
|
140
|
+
flex: 0 0 auto;
|
|
141
|
+
align-items: baseline;
|
|
142
|
+
gap: 0.4em;
|
|
143
|
+
margin-inline-start: auto;
|
|
144
|
+
font-size: 0.6875rem;
|
|
145
|
+
}
|
|
146
|
+
[part='status-text'] {
|
|
147
|
+
color: var(--lyra-tool-call-chip-accent);
|
|
148
|
+
font-weight: 600;
|
|
149
|
+
text-transform: uppercase;
|
|
150
|
+
letter-spacing: 0.03em;
|
|
151
|
+
white-space: nowrap;
|
|
152
|
+
}
|
|
153
|
+
[part='duration'] {
|
|
154
|
+
/* See [part='category']'s comment above -- same contrast rationale. */
|
|
155
|
+
color: var(--lyra-color-text);
|
|
156
|
+
font-variant-numeric: tabular-nums;
|
|
157
|
+
white-space: nowrap;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* Positioned by internal/positioner.js's place() -- see combobox's
|
|
161
|
+
[part='listbox'] for the identical fixed/z-index/max-size shape. Unlike
|
|
162
|
+
that popup this one has no open/close transition: a tooltip that
|
|
163
|
+
tracks the pointer/focus target benefits from appearing instantly, not
|
|
164
|
+
chasing a fade. */
|
|
165
|
+
[part='tooltip'] {
|
|
166
|
+
position: fixed;
|
|
167
|
+
z-index: 900;
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
max-inline-size: min(90vw, 24rem);
|
|
170
|
+
padding: var(--lyra-space-s) var(--lyra-space-m);
|
|
171
|
+
background: var(--lyra-color-surface);
|
|
172
|
+
border: 1px solid var(--lyra-color-border);
|
|
173
|
+
border-radius: var(--lyra-radius);
|
|
174
|
+
box-shadow: var(--lyra-shadow);
|
|
175
|
+
font-size: 0.8125rem;
|
|
176
|
+
line-height: 1.4;
|
|
177
|
+
color: var(--lyra-color-text);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@keyframes lyra-tool-call-chip-spin {
|
|
181
|
+
to {
|
|
182
|
+
transform: rotate(360deg);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
@keyframes lyra-tool-call-chip-pulse {
|
|
186
|
+
0%,
|
|
187
|
+
100% {
|
|
188
|
+
opacity: 1;
|
|
189
|
+
}
|
|
190
|
+
50% {
|
|
191
|
+
opacity: 0.35;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
@media (prefers-reduced-motion: reduce) {
|
|
195
|
+
[part='base'] {
|
|
196
|
+
transition: none !important;
|
|
197
|
+
}
|
|
198
|
+
:host([status='running']) [part='icon'] svg,
|
|
199
|
+
:host([status='pending']) [part='icon'] svg {
|
|
200
|
+
animation: none !important;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
`;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
import '../select/select.js';
|
|
4
|
+
import '../combobox/option.js';
|
|
5
|
+
import '../checkbox/checkbox.js';
|
|
6
|
+
/** The four leaf property types this phase's flat-schema renderer understands. */
|
|
7
|
+
export type ToolParamFormPropertyType = 'string' | 'number' | 'integer' | 'boolean';
|
|
8
|
+
/**
|
|
9
|
+
* One `schema.properties` entry. Deliberately shallow — see the class doc for
|
|
10
|
+
* the full scope limitation this type encodes.
|
|
11
|
+
*/
|
|
12
|
+
export interface ToolParamFormProperty {
|
|
13
|
+
type: ToolParamFormPropertyType;
|
|
14
|
+
/** A closed set of string choices, rendered as a `<lyra-select>`. Only meaningful when `type` is `'string'`. */
|
|
15
|
+
enum?: string[];
|
|
16
|
+
/** Helper text rendered under the field. */
|
|
17
|
+
description?: string;
|
|
18
|
+
/** Display label. Falls back to the property key itself when omitted. */
|
|
19
|
+
title?: string;
|
|
20
|
+
/** Pre-filled value used whenever `value` doesn't already have this key. */
|
|
21
|
+
default?: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The (intentionally flat) JSON Schema subset this component can render:
|
|
25
|
+
* a plain object whose every property is a string, number/integer, boolean,
|
|
26
|
+
* or string enum. See the class doc for what's out of scope.
|
|
27
|
+
*/
|
|
28
|
+
export interface ToolParamFormSchema {
|
|
29
|
+
type: 'object';
|
|
30
|
+
properties: Record<string, ToolParamFormProperty>;
|
|
31
|
+
required?: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `<lyra-tool-param-form>` — renders one form control per top-level property
|
|
35
|
+
* of a JSON Schema object, for ad hoc tool invocation or approval-editing UIs
|
|
36
|
+
* (e.g. "the agent wants to call `create_event(title, attendees, allDay)` —
|
|
37
|
+
* let the user tweak the arguments before running it").
|
|
38
|
+
*
|
|
39
|
+
* **Scope limitation (intentional, not accidental):** this phase only
|
|
40
|
+
* understands a *flat* object schema — every `properties` entry must be
|
|
41
|
+
* `'string'`, `'number'`, `'integer'`, `'boolean'`, or a string `enum`.
|
|
42
|
+
* Nested objects, arrays, `oneOf`/`anyOf`/`allOf`, `$ref`, and any other
|
|
43
|
+
* JSON Schema keyword are not read. A full JSON-Schema-to-form renderer is
|
|
44
|
+
* out of scope for this component; a property whose `type` isn't one of the
|
|
45
|
+
* four above renders a visible "Unsupported field type" note instead of
|
|
46
|
+
* silently dropping it or throwing.
|
|
47
|
+
*
|
|
48
|
+
* Fields render in `Object.keys(schema.properties)` order (insertion order,
|
|
49
|
+
* which is reliable for a plain object's string keys). A field's label is
|
|
50
|
+
* `title ?? ` the property key; `description` renders as helper text below
|
|
51
|
+
* the control; a key listed in `required` gets a visible `*` and the
|
|
52
|
+
* underlying control's own `required` wiring.
|
|
53
|
+
*
|
|
54
|
+
* This component owns no Submit/Cancel/Approve chrome — a consumer composes
|
|
55
|
+
* it inside their own dialog (e.g. a tool-approval dialog) and reads
|
|
56
|
+
* `.value`/`.errors`/`checkValidity()` (or calls `reportValidity()` right
|
|
57
|
+
* before acting, which also reveals any inline errors that user interaction
|
|
58
|
+
* hasn't surfaced yet).
|
|
59
|
+
*
|
|
60
|
+
* `value` is exactly what the consumer last set it to — a field with no
|
|
61
|
+
* entry in `value` but a schema `default` displays (and is *emitted*, via
|
|
62
|
+
* `lyra-input`) as that default, but the `value` *property* itself is left
|
|
63
|
+
* alone until the user actually edits that field. This mirrors an
|
|
64
|
+
* uncontrolled `<input placeholder>` not writing to `.value`, and means the
|
|
65
|
+
* very first `lyra-input` a consumer receives already carries every default
|
|
66
|
+
* resolved, so round-tripping `e.detail.value` back into `.value` converges
|
|
67
|
+
* after one edit.
|
|
68
|
+
*
|
|
69
|
+
* Optional native `<form>` participation is implemented via `ElementInternals`
|
|
70
|
+
* attached directly (this component's value is a whole object, not a plain
|
|
71
|
+
* string, so the `FormAssociated` string-value mixin doesn't fit — same
|
|
72
|
+
* shape as `<lyra-combobox>`'s array-valued case). This is a nice-to-have
|
|
73
|
+
* layered on top of the primary integration contract (`value` +
|
|
74
|
+
* `lyra-input`/`lyra-validity-change`), not a requirement: a consumer that
|
|
75
|
+
* never puts this inside a `<form>` loses nothing.
|
|
76
|
+
*
|
|
77
|
+
* @customElement lyra-tool-param-form
|
|
78
|
+
* @event lyra-input - A field's value changed. `detail: { value }` — the
|
|
79
|
+
* full current value object (every property, defaults resolved), not just
|
|
80
|
+
* the field that changed.
|
|
81
|
+
* @event lyra-validity-change - Overall validity changed (a required field
|
|
82
|
+
* became empty/non-empty). `detail: { valid: boolean; errors: Record<string, string> }`.
|
|
83
|
+
* @csspart base - The outer wrapper around all fields.
|
|
84
|
+
* @csspart field - One property's wrapper (label + control + description + error).
|
|
85
|
+
* @csspart label - A field's label.
|
|
86
|
+
* @csspart description - A field's helper text, from `schema.description`.
|
|
87
|
+
* @csspart error - A field's inline validation message (only rendered once the field has been visited).
|
|
88
|
+
*/
|
|
89
|
+
export declare class LyraToolParamForm extends LyraElement {
|
|
90
|
+
static formAssociated: boolean;
|
|
91
|
+
static styles: import("lit").CSSResultGroup[];
|
|
92
|
+
schema: ToolParamFormSchema;
|
|
93
|
+
value: Record<string, unknown>;
|
|
94
|
+
/** Submission key for the optional native `<form>` participation — see the class doc. */
|
|
95
|
+
name: string;
|
|
96
|
+
disabled: boolean;
|
|
97
|
+
private _errors;
|
|
98
|
+
private touchedFields;
|
|
99
|
+
private internals;
|
|
100
|
+
private baseId;
|
|
101
|
+
private lastValidityKey;
|
|
102
|
+
constructor();
|
|
103
|
+
connectedCallback(): void;
|
|
104
|
+
/** `value`, with any property missing from it filled in from `schema`'s own `default` — see the class doc. */
|
|
105
|
+
get effectiveValue(): Record<string, unknown>;
|
|
106
|
+
/**
|
|
107
|
+
* The current per-field validation errors (`{ [propertyKey]: message }`),
|
|
108
|
+
* required-and-empty only — mirrors the last `lyra-validity-change`
|
|
109
|
+
* event's `errors`. Independent of which fields have been visited; a
|
|
110
|
+
* consumer wanting the visited-only, screen-reader-announced subset
|
|
111
|
+
* should read the rendered `[part="error"]` elements instead.
|
|
112
|
+
*/
|
|
113
|
+
get errors(): Record<string, string>;
|
|
114
|
+
/** The current per-field validation errors (required-and-empty only), independent of `touchedFields`. */
|
|
115
|
+
private computeErrors;
|
|
116
|
+
/** Non-mutating validity check — unlike `reportValidity()`, never reveals inline errors. */
|
|
117
|
+
checkValidity(): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Reveals inline errors for every currently-invalid required field (as if
|
|
120
|
+
* each had been visited) and returns overall validity — the hook a
|
|
121
|
+
* consumer's own Submit/Approve button should call right before acting,
|
|
122
|
+
* mirroring a native `<form>`'s `reportValidity()`.
|
|
123
|
+
*/
|
|
124
|
+
reportValidity(): boolean;
|
|
125
|
+
formResetCallback(): void;
|
|
126
|
+
formDisabledCallback(disabled: boolean): void;
|
|
127
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
128
|
+
/** Pushes `effectiveValue`/`errors` into `ElementInternals` — see the class doc's form-participation note. */
|
|
129
|
+
private syncInternals;
|
|
130
|
+
protected updated(changed: PropertyValues): void;
|
|
131
|
+
private setFieldValue;
|
|
132
|
+
private markTouched;
|
|
133
|
+
private onTextInput;
|
|
134
|
+
private onNumberInput;
|
|
135
|
+
private onSelectChange;
|
|
136
|
+
private onCheckboxChange;
|
|
137
|
+
private renderControl;
|
|
138
|
+
private renderField;
|
|
139
|
+
render(): TemplateResult;
|
|
140
|
+
}
|
|
141
|
+
declare global {
|
|
142
|
+
interface HTMLElementTagNameMap {
|
|
143
|
+
'lyra-tool-param-form': LyraToolParamForm;
|
|
144
|
+
}
|
|
145
|
+
}
|