@icen.ai/ui 0.8.1 → 0.10.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/AGENTS.md +176 -75
- package/README.md +66 -88
- package/dist/base.css +208 -179
- package/dist/behaviors/accordion.mjs +8 -8
- package/dist/behaviors/ai-branch.d.mts +19 -0
- package/dist/behaviors/ai-branch.mjs +1133 -0
- package/dist/behaviors/ai-chat.d.mts +12 -10
- package/dist/behaviors/ai-chat.mjs +1125 -155
- package/dist/behaviors/ai-composer.d.mts +44 -12
- package/dist/behaviors/ai-composer.mjs +2084 -523
- package/dist/behaviors/ai-core.d.mts +1 -1
- package/dist/behaviors/ai-core.mjs +1016 -107
- package/dist/behaviors/ai-diff.mjs +1019 -127
- package/dist/behaviors/ai-feedback.d.mts +26 -0
- package/dist/behaviors/ai-feedback.mjs +1212 -0
- package/dist/behaviors/ai-panel.d.mts +21 -7
- package/dist/behaviors/ai-panel.mjs +1308 -264
- package/dist/behaviors/ai-provider.mjs +1003 -101
- package/dist/behaviors/ai-threads.d.mts +38 -0
- package/dist/behaviors/ai-threads.mjs +1233 -0
- package/dist/behaviors/ai-tool.d.mts +2 -2
- package/dist/behaviors/ai-tool.mjs +2042 -396
- package/dist/behaviors/ai-tools.d.mts +89 -16
- package/dist/behaviors/ai-tools.mjs +4453 -372
- package/dist/behaviors/autocomplete.d.mts +53 -0
- package/dist/behaviors/autocomplete.mjs +1600 -0
- package/dist/behaviors/back-top.d.mts +1 -1
- package/dist/behaviors/back-top.mjs +951 -14
- package/dist/behaviors/carousel.d.mts +1 -1
- package/dist/behaviors/carousel.mjs +906 -11
- package/dist/behaviors/cascader.d.mts +48 -0
- package/dist/behaviors/cascader.mjs +1853 -0
- package/dist/behaviors/charts.d.mts +174 -8
- package/dist/behaviors/charts.mjs +2632 -192
- package/dist/behaviors/code-block.d.mts +36 -0
- package/dist/behaviors/code-block.mjs +1611 -0
- package/dist/behaviors/command-palette.d.mts +9 -6
- package/dist/behaviors/command-palette.mjs +161 -59
- package/dist/behaviors/context-menu.d.mts +9 -8
- package/dist/behaviors/context-menu.mjs +1112 -44
- package/dist/behaviors/controls.d.mts +13 -13
- package/dist/behaviors/controls.mjs +989 -130
- package/dist/behaviors/copy.d.mts +21 -2
- package/dist/behaviors/copy.mjs +1206 -42
- package/dist/behaviors/datatable.d.mts +53 -3
- package/dist/behaviors/datatable.mjs +1963 -207
- package/dist/behaviors/date-picker.d.mts +0 -1
- package/dist/behaviors/date-picker.mjs +1340 -293
- package/dist/behaviors/design.d.mts +54 -0
- package/dist/behaviors/design.mjs +109 -0
- package/dist/behaviors/dropdown.d.mts +5 -6
- package/dist/behaviors/dropdown.mjs +262 -110
- package/dist/behaviors/events.d.mts +313 -3
- package/dist/behaviors/events.mjs +47 -2
- package/dist/behaviors/feedback.d.mts +30 -0
- package/dist/behaviors/feedback.mjs +296 -0
- package/dist/behaviors/focus.d.mts +8 -0
- package/dist/behaviors/focus.mjs +24 -0
- package/dist/behaviors/form-validate.d.mts +102 -0
- package/dist/behaviors/form-validate.mjs +6091 -0
- package/dist/behaviors/i18n.d.mts +789 -0
- package/dist/behaviors/i18n.mjs +1711 -0
- package/dist/behaviors/icons.d.mts +93 -0
- package/dist/behaviors/icons.mjs +113 -0
- package/dist/behaviors/input.d.mts +9 -1
- package/dist/behaviors/input.mjs +1056 -60
- package/dist/behaviors/kb-access.d.mts +34 -0
- package/dist/behaviors/kb-access.mjs +2459 -0
- package/dist/behaviors/kb-acl.d.mts +50 -0
- package/dist/behaviors/kb-acl.mjs +1345 -0
- package/dist/behaviors/kb-answer.d.mts +38 -0
- package/dist/behaviors/kb-answer.mjs +3707 -0
- package/dist/behaviors/kb-audit.d.mts +23 -0
- package/dist/behaviors/kb-audit.mjs +1297 -0
- package/dist/behaviors/kb-canvas.d.mts +44 -0
- package/dist/behaviors/kb-canvas.mjs +1512 -0
- package/dist/behaviors/kb-chain.d.mts +15 -0
- package/dist/behaviors/kb-chain.mjs +1192 -0
- package/dist/behaviors/kb-checkpoint.d.mts +16 -0
- package/dist/behaviors/kb-checkpoint.mjs +1492 -0
- package/dist/behaviors/kb-chunks.d.mts +31 -0
- package/dist/behaviors/kb-chunks.mjs +1414 -0
- package/dist/behaviors/kb-citation.d.mts +38 -0
- package/dist/behaviors/kb-citation.mjs +1699 -0
- package/dist/behaviors/kb-clarify.d.mts +20 -0
- package/dist/behaviors/kb-clarify.mjs +1176 -0
- package/dist/behaviors/kb-conflict.d.mts +22 -0
- package/dist/behaviors/kb-conflict.mjs +1206 -0
- package/dist/behaviors/kb-connector.d.mts +17 -0
- package/dist/behaviors/kb-connector.mjs +1303 -0
- package/dist/behaviors/kb-core.d.mts +534 -0
- package/dist/behaviors/kb-core.mjs +1805 -0
- package/dist/behaviors/kb-eval.d.mts +22 -0
- package/dist/behaviors/kb-eval.mjs +2235 -0
- package/dist/behaviors/kb-explain.d.mts +11 -0
- package/dist/behaviors/kb-explain.mjs +1165 -0
- package/dist/behaviors/kb-filter.d.mts +31 -0
- package/dist/behaviors/kb-filter.mjs +2417 -0
- package/dist/behaviors/kb-gap.d.mts +27 -0
- package/dist/behaviors/kb-gap.mjs +1195 -0
- package/dist/behaviors/kb-hittest.d.mts +34 -0
- package/dist/behaviors/kb-hittest.mjs +1352 -0
- package/dist/behaviors/kb-metadata.d.mts +29 -0
- package/dist/behaviors/kb-metadata.mjs +1248 -0
- package/dist/behaviors/kb-passage.d.mts +41 -0
- package/dist/behaviors/kb-passage.mjs +1469 -0
- package/dist/behaviors/kb-pipeline.d.mts +18 -0
- package/dist/behaviors/kb-pipeline.mjs +1301 -0
- package/dist/behaviors/kb-qa.d.mts +26 -0
- package/dist/behaviors/kb-qa.mjs +1260 -0
- package/dist/behaviors/kb-rerank.d.mts +20 -0
- package/dist/behaviors/kb-rerank.mjs +1248 -0
- package/dist/behaviors/kb-retrieval.d.mts +49 -0
- package/dist/behaviors/kb-retrieval.mjs +2585 -0
- package/dist/behaviors/kb-review.d.mts +44 -0
- package/dist/behaviors/kb-review.mjs +2282 -0
- package/dist/behaviors/kb-sandbox.d.mts +33 -0
- package/dist/behaviors/kb-sandbox.mjs +1247 -0
- package/dist/behaviors/kb-segment.d.mts +32 -0
- package/dist/behaviors/kb-segment.mjs +1431 -0
- package/dist/behaviors/kb-select.d.mts +24 -0
- package/dist/behaviors/kb-select.mjs +1989 -0
- package/dist/behaviors/kb-sources.d.mts +27 -0
- package/dist/behaviors/kb-sources.mjs +1287 -0
- package/dist/behaviors/kb-sql.d.mts +43 -0
- package/dist/behaviors/kb-sql.mjs +1865 -0
- package/dist/behaviors/kb-trace.d.mts +16 -0
- package/dist/behaviors/kb-trace.mjs +1328 -0
- package/dist/behaviors/kb-visibility.d.mts +44 -0
- package/dist/behaviors/kb-visibility.mjs +1331 -0
- package/dist/behaviors/kb-who-can.d.mts +32 -0
- package/dist/behaviors/kb-who-can.mjs +2216 -0
- package/dist/behaviors/mentions.d.mts +93 -0
- package/dist/behaviors/mentions.mjs +2152 -0
- package/dist/behaviors/modal.d.mts +4 -3
- package/dist/behaviors/modal.mjs +1055 -33
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +6 -6
- package/dist/behaviors/notification.d.mts +16 -8
- package/dist/behaviors/notification.mjs +1615 -265
- package/dist/behaviors/panel.d.mts +4 -0
- package/dist/behaviors/panel.mjs +994 -0
- package/dist/behaviors/popover.d.mts +28 -5
- package/dist/behaviors/popover.mjs +225 -24
- package/dist/behaviors/select.d.mts +5 -2
- package/dist/behaviors/select.mjs +1410 -117
- package/dist/behaviors/sidebar.d.mts +1 -1
- package/dist/behaviors/sidebar.mjs +13 -13
- package/dist/behaviors/slider.d.mts +1 -1
- package/dist/behaviors/slider.mjs +9 -9
- package/dist/behaviors/split-pane.d.mts +1 -1
- package/dist/behaviors/split-pane.mjs +7 -7
- package/dist/behaviors/suggestions.d.mts +27 -0
- package/dist/behaviors/suggestions.mjs +1089 -0
- package/dist/behaviors/svg-parse.d.mts +14 -0
- package/dist/behaviors/svg-parse.mjs +37 -0
- package/dist/behaviors/tabs.d.mts +2 -2
- package/dist/behaviors/tabs.mjs +25 -25
- package/dist/behaviors/tag-input.d.mts +23 -5
- package/dist/behaviors/tag-input.mjs +1359 -104
- package/dist/behaviors/theme-switcher.d.mts +24 -0
- package/dist/behaviors/theme-switcher.mjs +1981 -0
- package/dist/behaviors/theme.d.mts +15 -8
- package/dist/behaviors/theme.mjs +390 -28
- package/dist/behaviors/toast.d.mts +24 -25
- package/dist/behaviors/toast.mjs +1266 -88
- package/dist/behaviors/tooltip.d.mts +4 -0
- package/dist/behaviors/tooltip.mjs +378 -0
- package/dist/behaviors/tree-select.d.mts +69 -0
- package/dist/behaviors/tree-select.mjs +1907 -0
- package/dist/behaviors/tree.d.mts +1 -1
- package/dist/behaviors/tree.mjs +15 -15
- package/dist/behaviors/upload.d.mts +3 -2
- package/dist/behaviors/upload.mjs +1076 -66
- package/dist/cli.mjs +5 -6
- package/dist/components/ai-branch.mjs +3 -0
- package/dist/components/ai-chat.css +846 -458
- package/dist/components/ai-diff.css +153 -132
- package/dist/components/ai-feedback.mjs +3 -0
- package/dist/components/ai-panel.css +495 -270
- package/dist/components/ai-threads.mjs +3 -0
- package/dist/components/ai-tool.css +393 -238
- package/dist/components/autocomplete.css +61 -0
- package/dist/components/autocomplete.mjs +3 -0
- package/dist/components/back-top.css +34 -31
- package/dist/components/badge.css +44 -41
- package/dist/components/breadcrumb.css +67 -46
- package/dist/components/btn.css +80 -74
- package/dist/components/card.css +117 -106
- package/dist/components/cascader.css +311 -0
- package/dist/components/cascader.mjs +3 -0
- package/dist/components/chart-area.css +8 -2
- package/dist/components/chart-bar.css +95 -33
- package/dist/components/chart-gauge.css +14 -11
- package/dist/components/chart-graph.css +60 -0
- package/dist/components/chart-graph.mjs +4 -0
- package/dist/components/chart-heatmap.css +96 -90
- package/dist/components/chart-line.css +8 -3
- package/dist/components/chart-map.mjs +3 -0
- package/dist/components/chart-pie.css +9 -6
- package/dist/components/chart-radar.css +8 -5
- package/dist/components/chart-scatter.css +9 -6
- package/dist/components/chart-scatter.mjs +1 -1
- package/dist/components/chart-sparkline.css +5 -2
- package/dist/components/chart-stack.css +14 -11
- package/dist/components/charts.css +190 -67
- package/dist/components/charts.mjs +1 -0
- package/dist/components/code-block.css +418 -0
- package/dist/components/code-block.mjs +4 -0
- package/dist/components/command-palette.css +138 -117
- package/dist/components/content.css +257 -251
- package/dist/components/copy.css +72 -44
- package/dist/components/datatable.css +423 -181
- package/dist/components/date-picker.css +135 -104
- package/dist/components/empty.css +68 -65
- package/dist/components/feedback.css +201 -183
- package/dist/components/form-validate.css +120 -0
- package/dist/components/form-validate.mjs +3 -0
- package/dist/components/form.css +150 -127
- package/dist/components/icon.css +102 -0
- package/dist/components/icon.mjs +3 -0
- package/dist/components/input.css +159 -104
- package/dist/components/kb-access.mjs +4 -0
- package/dist/components/kb-acl.mjs +4 -0
- package/dist/components/kb-agent.css +496 -0
- package/dist/components/kb-answer.mjs +4 -0
- package/dist/components/kb-audit.mjs +4 -0
- package/dist/components/kb-canvas.mjs +4 -0
- package/dist/components/kb-chain.mjs +4 -0
- package/dist/components/kb-checkpoint.mjs +4 -0
- package/dist/components/kb-chunks.mjs +4 -0
- package/dist/components/kb-citation.mjs +4 -0
- package/dist/components/kb-clarify.mjs +4 -0
- package/dist/components/kb-conflict.mjs +4 -0
- package/dist/components/kb-connector.mjs +4 -0
- package/dist/components/kb-data.css +653 -0
- package/dist/components/kb-eval.mjs +4 -0
- package/dist/components/kb-explain.mjs +4 -0
- package/dist/components/kb-filter.mjs +4 -0
- package/dist/components/kb-gap.mjs +4 -0
- package/dist/components/kb-ground.css +578 -0
- package/dist/components/kb-hittest.mjs +4 -0
- package/dist/components/kb-ingest.css +882 -0
- package/dist/components/kb-metadata.mjs +4 -0
- package/dist/components/kb-ops.css +554 -0
- package/dist/components/kb-passage.mjs +4 -0
- package/dist/components/kb-perm.css +433 -0
- package/dist/components/kb-pipeline.mjs +4 -0
- package/dist/components/kb-qa.mjs +4 -0
- package/dist/components/kb-rerank.mjs +4 -0
- package/dist/components/kb-retrieval.mjs +4 -0
- package/dist/components/kb-review.mjs +4 -0
- package/dist/components/kb-sandbox.mjs +4 -0
- package/dist/components/kb-search.css +897 -0
- package/dist/components/kb-segment.mjs +4 -0
- package/dist/components/kb-sources.mjs +4 -0
- package/dist/components/kb-sql.mjs +4 -0
- package/dist/components/kb-trace.mjs +4 -0
- package/dist/components/kb-visibility.mjs +4 -0
- package/dist/components/kb-who-can.mjs +4 -0
- package/dist/components/kb.css +263 -0
- package/dist/components/kb.mjs +9 -0
- package/dist/components/layout.css +85 -82
- package/dist/components/material-chinese.css +73 -0
- package/dist/components/material-soviet.css +76 -0
- package/dist/components/material.css +275 -0
- package/dist/components/media.css +220 -166
- package/dist/components/mentions.css +189 -0
- package/dist/components/mentions.mjs +3 -0
- package/dist/components/menu.css +113 -105
- package/dist/components/modal.css +107 -112
- package/dist/components/nav.css +118 -115
- package/dist/components/notification.css +238 -174
- package/dist/components/pagination.css +56 -53
- package/dist/components/panel.css +66 -63
- package/dist/components/panel.mjs +1 -0
- package/dist/components/pill.css +81 -71
- package/dist/components/popover.css +67 -53
- package/dist/components/scroll-area.css +113 -110
- package/dist/components/segmented.css +146 -143
- package/dist/components/select.css +206 -186
- package/dist/components/sidebar.css +137 -127
- package/dist/components/slider.css +117 -114
- package/dist/components/split-pane.css +112 -109
- package/dist/components/stat.css +112 -106
- package/dist/components/steps.css +109 -103
- package/dist/components/switch.css +138 -134
- package/dist/components/table.css +131 -107
- package/dist/components/tabs.css +114 -108
- package/dist/components/tag-input.css +48 -133
- package/dist/components/tag.css +81 -71
- package/dist/components/theme-switcher.css +105 -0
- package/dist/components/theme-switcher.mjs +3 -0
- package/dist/components/toast.css +100 -86
- package/dist/components/toolbar.css +45 -42
- package/dist/components/tooltip.css +102 -43
- package/dist/components/tooltip.mjs +1 -0
- package/dist/components/tree-select.css +416 -0
- package/dist/components/tree-select.mjs +3 -0
- package/dist/components/upload.css +135 -92
- package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
- package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
- package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/README.md +14 -0
- package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
- package/dist/index.d.mts +64 -15
- package/dist/index.mjs +28049 -8595
- package/dist/react.d.mts +91 -0
- package/dist/react.mjs +8208 -0
- package/dist/registry.json +454 -15
- package/dist/tokens/chinese.css +44 -0
- package/dist/tokens/colors.css +365 -1222
- package/dist/tokens/design.css +109 -0
- package/dist/tokens/dtcg.json +11198 -0
- package/dist/tokens/figma.variables.json +7017 -0
- package/dist/tokens/icon-masks.css +78 -0
- package/dist/tokens/pixel.css +50 -0
- package/dist/tokens/soviet.css +44 -0
- package/dist/tokens/style-profiles.css +36 -547
- package/dist/tokens/themes.json +308 -0
- package/dist/tokens/tokens-studio.json +6728 -0
- package/dist/tokens/typography.css +21 -18
- package/dist/tokens.css +1555 -1801
- package/dist/ui.css +16147 -8597
- package/dist/vue.d.mts +344 -0
- package/dist/vue.mjs +7781 -0
- package/docs/spec/ai-input-experience.md +75 -0
- package/docs/spec/ai-native.md +238 -147
- package/docs/spec/design-philosophy.md +189 -0
- package/docs/spec/design-primitives.md +196 -0
- package/docs/spec/kb-family.md +475 -0
- package/package.json +42 -7
- package/dist/retro-effects.css +0 -255
- package/dist/tokens/retro-effects.css +0 -255
|
@@ -1,3 +1,989 @@
|
|
|
1
|
+
// src/behaviors/icons.ts
|
|
2
|
+
var ICON_PATHS = {
|
|
3
|
+
file: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16",
|
|
4
|
+
folder: "M3 5a1.5 1.5 0 0 1 1.5-1.5H8l2 2h5.5A1.5 1.5 0 0 1 17 7v8a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 3 15Z",
|
|
5
|
+
globe: "M17.5 10a7.5 7.5 0 1 1-15 0 7.5 7.5 0 0 1 15 0ZM2.5 10h15M10 2.5c-4 4-4 11 0 15 4-4 4-11 0-15Z",
|
|
6
|
+
document: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16M7 10.5h6M7 13.5h6",
|
|
7
|
+
agent: "M10 6V3M8 3h2M5 6h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2ZM1.5 10h1.5M17 10h1.5M7 10v2M13 10v2M8 14h4",
|
|
8
|
+
paperclip: "M14 7 8.3 12.7a1.6 1.6 0 0 1-2.3-2.3l6.3-6.3a3.2 3.2 0 0 1 4.5 4.5l-7 7a4.7 4.7 0 0 1-6.7-6.7l7-7",
|
|
9
|
+
stop: "M6.5 5h7A1.5 1.5 0 0 1 15 6.5v7a1.5 1.5 0 0 1-1.5 1.5h-7A1.5 1.5 0 0 1 5 13.5v-7A1.5 1.5 0 0 1 6.5 5Z",
|
|
10
|
+
terminal: "M5 3.5h10a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2ZM6 7l3 3-3 3M11 13h3",
|
|
11
|
+
branch: "M6 6v8M14 6v2a4 4 0 0 1-4 4H6M8 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM8 16a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM16 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z",
|
|
12
|
+
"line-numbers": "M3 5h2M3 10h2M3 15h2M8 5h9M8 10h9M8 15h9",
|
|
13
|
+
wrap: "M3 5h14M3 10h10a3 3 0 0 1 0 6h-3M12.5 13.5 10 16l2.5 2.5",
|
|
14
|
+
calendar: "M5.5 4h9A2.5 2.5 0 0 1 17 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 3 14.5v-8A2.5 2.5 0 0 1 5.5 4ZM6.5 2.5v3M13.5 2.5v3M3 8h14M6.5 11h.1M10 11h.1M13.5 11h.1M6.5 14h.1M10 14h.1",
|
|
15
|
+
close: "M6 6l8 8M14 6l-8 8",
|
|
16
|
+
check: "M4.5 10.2l3.6 3.6 7.4-7.6",
|
|
17
|
+
"chevron-down": "M5.5 7.75 10 12.25l4.5-4.5",
|
|
18
|
+
"chevron-up": "M5.5 12.25 10 7.75l4.5 4.5",
|
|
19
|
+
"chevron-right": "M7.75 5.5 12.25 10l-4.5 4.5",
|
|
20
|
+
"chevron-left": "M12.25 5.5 7.75 10l4.5 4.5",
|
|
21
|
+
"arrow-right": "M3.5 10h13M11 4.5l5.5 5.5-5.5 5.5",
|
|
22
|
+
"arrow-left": "M16.5 10h-13M9 4.5 3.5 10 9 15.5",
|
|
23
|
+
"arrow-up": "M10 16.5v-13M4.5 9 10 3.5 15.5 9",
|
|
24
|
+
"arrow-down": "M10 3.5v13M4.5 11l5.5 5.5 5.5-5.5",
|
|
25
|
+
plus: "M10 4v12M4 10h12",
|
|
26
|
+
minus: "M4 10h12",
|
|
27
|
+
sort: "M6 15V4M3 7l3-3 3 3M14 5v11M11 13l3 3 3-3",
|
|
28
|
+
search: "M13.3 13.3 17 17M14.5 8.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0",
|
|
29
|
+
sun: "M13.5 10a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0M10 1.75v1.5M10 16.75v1.5M1.75 10h1.5M16.75 10h1.5M4.17 4.17l1.06 1.06M14.77 14.77l1.06 1.06M4.17 15.83l1.06-1.06M14.77 5.23l1.06-1.06",
|
|
30
|
+
moon: "M17.25 11.15A7.5 7.5 0 0 1 8.85 2.75a7.5 7.5 0 1 0 8.4 8.4Z",
|
|
31
|
+
modern: "M6.5 3h7A3.5 3.5 0 0 1 17 6.5v7a3.5 3.5 0 0 1-3.5 3.5h-7A3.5 3.5 0 0 1 3 13.5v-7A3.5 3.5 0 0 1 6.5 3ZM7 10l3-3 3 3-3 3Z",
|
|
32
|
+
pixel: "M3 3h5v5H3ZM12 3h5v5h-5ZM3 12h5v5H3ZM12 12h5v5h-5Z",
|
|
33
|
+
chinese: "M3 8c3 0 5-2 7-5 2 3 4 5 7 5M4 8h12M6 8v8m8-8v8M3 16h14M8 16v-5h4v5",
|
|
34
|
+
soviet: "M3 17h14M5 17V8h4v9m0-12h6v12M7 8V5h2m2 3h2m-2 3h2m-2 3h2M10 5V3h4v2",
|
|
35
|
+
more: "M4 9.9v.2M10 9.9v.2M16 9.9v.2",
|
|
36
|
+
copy: "M7 7h8a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V7ZM13 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",
|
|
37
|
+
edit: "M11.5 4.5l4 4M4 12l9-9a1.4 1.4 0 0 1 2 0l2 2a1.4 1.4 0 0 1 0 2l-9 9-5 1Z",
|
|
38
|
+
link: "M8 6l2-2a4.2 4.2 0 0 1 6 6l-2 2M12 14l-2 2a4.2 4.2 0 0 1-6-6l2-2M7 13l6-6",
|
|
39
|
+
trash: "M3.5 5.5h13M7 5.5V3h6v2.5M5 5.5l.7 11.5h8.6L15 5.5M8 9v5M12 9v5",
|
|
40
|
+
spinner: "M10 3a7 7 0 1 1-7 7",
|
|
41
|
+
"circle-check": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM6 10l2.7 2.7 5.3-5.4",
|
|
42
|
+
"circle-error": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM7.2 7.2l5.6 5.6M12.8 7.2l-5.6 5.6",
|
|
43
|
+
"circle-info": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM10 9v5M10 6.1v.15",
|
|
44
|
+
"triangle-alert": "M8.7 3.5a1.5 1.5 0 0 1 2.6 0l6.4 11.3a1.5 1.5 0 0 1-1.3 2.2H3.6a1.5 1.5 0 0 1-1.3-2.2ZM10 7.2v4.4M10 14v.15",
|
|
45
|
+
refresh: "M16.5 7.2A7 7 0 0 0 4.3 5.9L2.5 8M2.5 3.5V8H7M3.5 12.8a7 7 0 0 0 12.2 1.3l1.8-2.1M13 12h4.5v4.5",
|
|
46
|
+
external: "M11.5 3H17v5.5M17 3l-8 8M8 3H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3",
|
|
47
|
+
home: "M3.5 10.25 10 4l6.5 6.25M5.75 8.75v7a.75.75 0 0 0 .75.75h7.5a.75.75 0 0 0 .75-.75v-7",
|
|
48
|
+
settings: "M3.5 5.5h13M3.5 10h13M3.5 14.5h13M7 4v3M12.5 8.5v3M8 13v3",
|
|
49
|
+
star: "M10 2.5l2.4 5.1 5.6.4-4.2 3.7 1.3 5.5-5.1-3-5.1 3 1.3-5.5L1.8 8l5.6-.4Z",
|
|
50
|
+
eye: "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8Z",
|
|
51
|
+
"eye-off": "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8ZM3.5 3.5l13 13",
|
|
52
|
+
inbox: "M3.5 12.25h3.7l1.5 2.5h2.6l1.5-2.5h3.7M4.7 5.5l-1.2 6.75v3.25a1.5 1.5 0 0 0 1.5 1.5h10a1.5 1.5 0 0 0 1.5-1.5v-3.25L15.3 5.5a1.3 1.3 0 0 0-1.25-1H5.95a1.3 1.3 0 0 0-1.25 1Z",
|
|
53
|
+
bell: "M10 3.5a4.5 4.5 0 0 1 4.5 4.5c0 4.5 1.8 5.7 2.5 6.5H3c.7-.8 2.5-2 2.5-6.5A4.5 4.5 0 0 1 10 3.5ZM8.5 16.5a1.6 1.6 0 0 0 3 0",
|
|
54
|
+
users: "M13.8 16.5v-1.5a3.5 3.5 0 0 0-3.5-3.5H6.3a3.5 3.5 0 0 0-3.5 3.5v1.5M8.3 8.9a2.7 2.7 0 1 0 0-5.4 2.7 2.7 0 0 0 0 5.4ZM16.5 16.5v-1.3a3.3 3.3 0 0 0-2.3-3.1M12.3 3.7a2.7 2.7 0 0 1 0 5.2",
|
|
55
|
+
activity: "M17 10h-2.6l-2 5.8L8 4.2 6 10H3",
|
|
56
|
+
"trend-up": "M3.5 14.5l4.2-4.2 2.8 2.8 5.9-5.9M12.4 7.2h4.2v4.2",
|
|
57
|
+
"trend-down": "M3.5 5.5l4.2 4.2 2.8-2.8 5.9 5.9M12.4 12.8h4.2V8.6",
|
|
58
|
+
rocket: "M10 2.5c2 1.5 3.2 4 3.2 6.8 0 1.5-.3 2.9-.8 4.2H7.6c-.5-1.3-.8-2.7-.8-4.2 0-2.8 1.2-5.3 3.2-6.8ZM10 8.6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM7.6 12.5 5.6 15.4c-.9.3-1.6 1-2 2M12.4 12.5l2 2.9c.9.3 1.6 1 2 2M8.7 13.8c0 1.8.5 3.1 1.3 4.2.8-1.1 1.3-2.4 1.3-4.2",
|
|
59
|
+
bold: "M6.5 4h4.2a3 3 0 0 1 0 6H6.5M6.5 10h5a3 3 0 0 1 0 6H6.5M6.5 4v12",
|
|
60
|
+
italic: "M8.5 4.5h7M4.5 15.5h7M12.5 4.5l-5 11",
|
|
61
|
+
underline: "M6 4v5.5a4 4 0 0 0 8 0V4M4.5 16h11",
|
|
62
|
+
"align-left": "M3.5 4.5h13M3.5 10h8.5M3.5 15.5h11",
|
|
63
|
+
"align-center": "M3.5 4.5h13M5.75 10h8.5M4.5 15.5h11",
|
|
64
|
+
"align-right": "M3.5 4.5h13M8 10h8.5M5.5 15.5h11",
|
|
65
|
+
list: "M6.5 5h10M6.5 10h10M6.5 15h10M3.5 5h.01M3.5 10h.01M3.5 15h.01",
|
|
66
|
+
server: "M3 3h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 8H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 3ZM3 12h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 17H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 12ZM5 5.5h.01M5 14.5h.01",
|
|
67
|
+
sparkle: "M10 2.5l1.6 4.3 4.3 1.6-4.3 1.6L10 14.3l-1.6-4.3-4.3-1.6 4.3-1.6ZM15.5 12.5l.8 2.1 2.1.8-2.1.8-.8 2.1-.8-2.1-2.1-.8 2.1-.8Z",
|
|
68
|
+
play: "M6.5 4.8v10.4c0 .9 1 1.5 1.8 1l8.3-5.2a1.2 1.2 0 0 0 0-2L8.3 3.8a1.2 1.2 0 0 0-1.8 1Z",
|
|
69
|
+
"chart-line": "M3.5 3.5v13h13M6.5 12l2.8-2.8 2.2 2.2 4-4.4",
|
|
70
|
+
layers: "M10 3.2 3.6 6.5 10 9.8l6.4-3.3ZM4.5 10.4 10 13.2l5.5-2.8M4.5 13.6 10 16.4l5.5-2.8",
|
|
71
|
+
box: "M17 6 10 3.2 3 6v8l7 2.8 7-2.8ZM3 6l7 2.8L17 6M10 9v7.8",
|
|
72
|
+
filter: "M4 4.5h12l-4.4 5.1v5l-3.2-1.6V9.6Z",
|
|
73
|
+
columns: "M3.5 4h13v12h-13ZM8.2 4v12M12.8 4v12",
|
|
74
|
+
download: "M10 3.5v8M6.8 8.3 10 11.5l3.2-3.2M4 15v2.5a1.5 1.5 0 0 0 1.5 1.5h9a1.5 1.5 0 0 0 1.5-1.5V15"
|
|
75
|
+
};
|
|
76
|
+
var custom = /* @__PURE__ */ new Map();
|
|
77
|
+
var escape = (s) => s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
78
|
+
function iconPath(name) {
|
|
79
|
+
return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
|
|
80
|
+
}
|
|
81
|
+
function iconAttributes(o = {}) {
|
|
82
|
+
const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
|
|
83
|
+
return { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", width: String(size), height: String(size), fill: "none", stroke: "currentColor", "stroke-width": "1.6", "stroke-linecap": "round", "stroke-linejoin": "round", focusable: "false", class: ["icen-symbol", o.className].filter(Boolean).join(" "), ...o.label ? { role: "img", "aria-label": o.label } : { "aria-hidden": "true" } };
|
|
84
|
+
}
|
|
85
|
+
function iconHTML(name, o = {}) {
|
|
86
|
+
const path = iconPath(name);
|
|
87
|
+
if (!path) return "";
|
|
88
|
+
return `<svg${Object.entries(iconAttributes(o)).map(([k, v]) => ` ${k}="${escape(v)}"`).join("")}><path d="${escape(path)}"></path></svg>`;
|
|
89
|
+
}
|
|
90
|
+
function createIcon(name, o = {}) {
|
|
91
|
+
if (typeof document === "undefined") return null;
|
|
92
|
+
const path = iconPath(name);
|
|
93
|
+
if (!path) return null;
|
|
94
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
95
|
+
for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
|
|
96
|
+
const line = document.createElementNS(svg.namespaceURI, "path");
|
|
97
|
+
line.setAttribute("d", path);
|
|
98
|
+
svg.append(line);
|
|
99
|
+
return svg;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/behaviors/events.ts
|
|
103
|
+
function emitIcen(source, type, detail) {
|
|
104
|
+
return source.dispatchEvent(
|
|
105
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/behaviors/i18n.ts
|
|
110
|
+
var ICEN_LOCALE_ZH_CN = {
|
|
111
|
+
/* ── aiBranch ── */
|
|
112
|
+
"aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
|
|
113
|
+
"aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
|
|
114
|
+
"aiBranch.version": "\u5206\u652F\u7248\u672C",
|
|
115
|
+
/* ── aiChat ── */
|
|
116
|
+
"aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
|
|
117
|
+
"aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
|
|
118
|
+
"aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
|
|
119
|
+
"aiChat.download": "\u4E0B\u8F7D",
|
|
120
|
+
"aiChat.file": "\u6587\u4EF6",
|
|
121
|
+
"aiChat.roleSystem": "\u7CFB",
|
|
122
|
+
"aiChat.roleTool": "\u5DE5",
|
|
123
|
+
"aiChat.roleUser": "\u6211",
|
|
124
|
+
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
125
|
+
/* ── aiComposer ── */
|
|
126
|
+
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
127
|
+
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
128
|
+
"aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
|
|
129
|
+
"aiComposer.all": "\u5168\u90E8",
|
|
130
|
+
"aiComposer.skills": "\u6280\u80FD",
|
|
131
|
+
"aiComposer.tools": "\u5DE5\u5177",
|
|
132
|
+
"aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
|
|
133
|
+
"aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
|
|
134
|
+
"aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
|
|
135
|
+
"aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
|
|
136
|
+
"aiComposer.filesNeedAdapter": "\u9644\u4EF6\u5C1A\u672A\u63A5\u901A\u4E0A\u4F20\u3002\u8BF7\u914D\u7F6E prepareMessage \u540E\u91CD\u8BD5\uFF0C\u6587\u4EF6\u4ECD\u4FDD\u7559\u5728\u6B64\u8BF7\u6C42\u4E2D\u3002",
|
|
137
|
+
"aiComposer.attachDoc": "\u6587\u6863",
|
|
138
|
+
"aiComposer.attachFile": "\u6587\u4EF6",
|
|
139
|
+
"aiComposer.attachFolder": "\u6587\u4EF6\u5939",
|
|
140
|
+
"aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
|
|
141
|
+
"aiComposer.commands": "\u547D\u4EE4",
|
|
142
|
+
"aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
|
|
143
|
+
"aiComposer.done": "\u5B8C\u6210",
|
|
144
|
+
"aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
|
|
145
|
+
"aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
|
|
146
|
+
"aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
|
|
147
|
+
"aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
|
|
148
|
+
"aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
|
|
149
|
+
"aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
|
|
150
|
+
"aiComposer.refs": "\u5F15\u7528",
|
|
151
|
+
"aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
|
|
152
|
+
"aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
|
|
153
|
+
"aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
|
|
154
|
+
"aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
|
|
155
|
+
"aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
|
|
156
|
+
"aiComposer.send": "\u53D1\u9001",
|
|
157
|
+
"aiComposer.stop": "\u505C\u6B62\u751F\u6210",
|
|
158
|
+
"aiComposer.stopped": "\u5DF2\u505C\u6B62",
|
|
159
|
+
"aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
|
|
160
|
+
"aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
|
|
161
|
+
/* ── aiCore ── */
|
|
162
|
+
"aiCore.kindBrowser": "\u6D4F\u89C8",
|
|
163
|
+
"aiCore.kindChart": "\u56FE\u8868",
|
|
164
|
+
"aiCore.kindDelete": "\u5220\u9664",
|
|
165
|
+
"aiCore.kindEdit": "\u7F16\u8F91",
|
|
166
|
+
"aiCore.kindFetch": "\u8BF7\u6C42",
|
|
167
|
+
"aiCore.kindGlob": "\u5339\u914D",
|
|
168
|
+
"aiCore.kindGrep": "\u641C\u7D22",
|
|
169
|
+
"aiCore.kindNote": "\u7B14\u8BB0",
|
|
170
|
+
"aiCore.kindPlan": "\u8BA1\u5212",
|
|
171
|
+
"aiCore.kindRead": "\u8BFB\u53D6",
|
|
172
|
+
"aiCore.kindSearch": "\u68C0\u7D22",
|
|
173
|
+
"aiCore.kindShell": "\u547D\u4EE4",
|
|
174
|
+
"aiCore.kindSkill": "\u6280\u80FD",
|
|
175
|
+
"aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
|
|
176
|
+
"aiCore.kindTodo": "\u5F85\u529E",
|
|
177
|
+
"aiCore.kindWrite": "\u5199\u5165",
|
|
178
|
+
"aiCore.statusApproval": "\u5F85\u786E\u8BA4",
|
|
179
|
+
"aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
|
|
180
|
+
"aiCore.statusDone": "\u5B8C\u6210",
|
|
181
|
+
"aiCore.statusError": "\u5931\u8D25",
|
|
182
|
+
"aiCore.statusPending": "\u7B49\u5F85",
|
|
183
|
+
"aiCore.statusRunning": "\u6267\u884C\u4E2D",
|
|
184
|
+
"aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
|
|
185
|
+
"aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
|
|
186
|
+
/* ── aiDiff ── */
|
|
187
|
+
"aiDiff.accepted": "\u5DF2\u63A5\u53D7",
|
|
188
|
+
"aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
|
|
189
|
+
"aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
|
|
190
|
+
"aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
|
|
191
|
+
/* ── aiFeedback ── */
|
|
192
|
+
"aiFeedback.helpful": "\u6709\u5E2E\u52A9",
|
|
193
|
+
"aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
|
|
194
|
+
"aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
|
|
195
|
+
"aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
|
|
196
|
+
"aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
|
|
197
|
+
"aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
|
|
198
|
+
"aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
|
|
199
|
+
"aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
|
|
200
|
+
/* ── aiPanel ── */
|
|
201
|
+
"aiPanel.audit": "\u5BA1\u8BA1",
|
|
202
|
+
"aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
|
|
203
|
+
"aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
|
|
204
|
+
"aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
|
|
205
|
+
"aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
|
|
206
|
+
"aiPanel.context": "\u4E0A\u4E0B\u6587",
|
|
207
|
+
"aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
208
|
+
"aiPanel.errorsCount": "{p0} \u5931\u8D25",
|
|
209
|
+
"aiPanel.files": "\u6587\u4EF6 ({p0})",
|
|
210
|
+
"aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
|
|
211
|
+
"aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
|
|
212
|
+
"aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
|
|
213
|
+
"aiPanel.reasoning": "\u63A8\u7406",
|
|
214
|
+
"aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
|
|
215
|
+
"aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
216
|
+
"aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
217
|
+
"aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
218
|
+
"aiPanel.toolsCount": "{p0} \u5DE5\u5177",
|
|
219
|
+
"aiPanel.usage": "\u7528\u91CF",
|
|
220
|
+
"aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
|
|
221
|
+
/* ── aiProvider ── */
|
|
222
|
+
"aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
|
|
223
|
+
"aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
|
|
224
|
+
"aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
|
|
225
|
+
"aiProvider.corsHint": "\uFF1B\u6D4F\u89C8\u5668\u76F4\u8FDE {p0}\uFF08{p1}\uFF09\u5F88\u53EF\u80FD\u88AB CORS \u62E6\u622A\uFF0C\u5EFA\u8BAE\u7ECF\u4EE3\u7406/\u81EA\u5EFA\u7F51\u5173\u8F6C\u53D1",
|
|
226
|
+
"aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
|
|
227
|
+
"aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
|
|
228
|
+
"aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
|
|
229
|
+
"aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
|
|
230
|
+
"aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
|
|
231
|
+
"aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
|
|
232
|
+
"aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
|
|
233
|
+
"aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
|
|
234
|
+
"aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
|
|
235
|
+
"aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
|
|
236
|
+
"aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
|
|
237
|
+
"aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
|
|
238
|
+
"aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
|
|
239
|
+
"aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
|
|
240
|
+
/* ── aiThreads ── */
|
|
241
|
+
"aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
|
|
242
|
+
"aiThreads.archived": "\u5DF2\u5F52\u6863",
|
|
243
|
+
/* ── aiTool ── */
|
|
244
|
+
"aiTool.allow": "\u5141\u8BB8",
|
|
245
|
+
"aiTool.reject": "\u62D2\u7EDD",
|
|
246
|
+
/* ── aiTools ── */
|
|
247
|
+
"aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
|
|
248
|
+
"aiTools.chart.data": "\u4EFB\u610F\u7EF4\u5EA6\u539F\u59CB\u8BB0\u5F55 + dims \u5B57\u6BB5\u6620\u5C04\uFF08\u81EA\u52A8\u900F\u89C6\u6210 \u7C7B\u76EE \xD7 \u7CFB\u5217\uFF09",
|
|
249
|
+
"aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
|
|
250
|
+
"aiTools.chart.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u5F20\u56FE\u8868\u53EF\u89C6\u5316\u3002\u8F93\u5165\u4E00\u4EFD\u56FE\u8868\u89C4\u683C\uFF08\u7EAF JSON\uFF09\uFF1Alabels+values\uFF08\u7C7B\u76EE\u6570\u503C\uFF09\u3001series\uFF08\u591A\u7CFB\u5217\uFF09\u3001segments\uFF08\u5360\u6BD4\uFF09\u3001points\uFF08\u6563\u70B9\u6C14\u6CE1\uFF09\u3001dates\uFF08\u8D21\u732E\u65E5\u5386\uFF09\u4EFB\u7ED9\u5176\u4E00\uFF1Btype \u7F3A\u7701\u65F6\u6309\u6570\u636E\u5F62\u6001\u81EA\u52A8\u9009\u578B\uFF08\u65F6\u95F4\u5E8F\u5217\u2192\u6298\u7EBF\u3001\u5360\u6BD4\u2192\u73AF\u5F62\u3001\u65E5\u671F\u2192\u8D21\u732E\u65E5\u5386\u3001\u5750\u6807\u70B9\u2192\u6563\u70B9\uFF09\u3002\u56FE\u8868\u5E26\u4EA4\u4E92\uFF08\u60AC\u505C\u63D0\u793A/\u70B9\u51FB/\u53F3\u952E\uFF09\u4E0E\u53EF\u9690\u85CF\u56FE\u4F8B\u3002",
|
|
251
|
+
"aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
|
|
252
|
+
"aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
|
|
253
|
+
"aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
|
|
254
|
+
"aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
|
|
255
|
+
"aiTools.chart.lttb": "\u5927\u6570\u636E\u91CF\u964D\u91C7\u6837\uFF1Atrue=\u81EA\u52A8\u4E0A\u9650\uFF0C\u6570\u5B57=\u6700\u5927\u4FDD\u7559\u70B9\u6570\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
|
|
256
|
+
"aiTools.chart.marks": "\u6807\u8BB0\u5C42\uFF08\u9608\u503C\u7EBF/\u53C2\u8003\u533A\u95F4/\u5F3A\u8C03\u70B9\uFF09\uFF0C\u5143\u7D20\u4E3A\u7EAF JSON \u63CF\u8FF0\u5B50\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
|
|
257
|
+
"aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
|
|
258
|
+
"aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
|
|
259
|
+
"aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
|
|
260
|
+
"aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
|
|
261
|
+
"aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
|
|
262
|
+
"aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
|
|
263
|
+
"aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
|
|
264
|
+
"aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
|
|
265
|
+
"aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
|
|
266
|
+
"aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
|
|
267
|
+
"aiTools.datatable.columns": "\u5217\u5B9A\u4E49\u6570\u7EC4\uFF1A\u6BCF\u9879 { key, title, sortable?, filterable? }\uFF08key \u5BF9\u5E94 rows \u5143\u7D20\u5B57\u6BB5\u540D\uFF09",
|
|
268
|
+
"aiTools.datatable.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u4E2A\u53EF\u641C\u7D22\u3001\u5206\u9875\u3001\u53EF\u5BFC\u51FA CSV \u7684\u6570\u636E\u8868\u683C\u3002\u8F93\u5165\u7EAF JSON\uFF1Acolumns \u4E3A\u5217\u5B9A\u4E49\uFF08key/title \u5FC5\u586B\uFF09\uFF0Crows \u4E3A\u884C\u5BF9\u8C61\u6570\u7EC4\uFF08\u5B57\u6BB5\u540D\u5BF9\u9F50\u5217 key\uFF09\u3002\u8FD4\u56DE { title, rows: \u884C\u6570 } \u6458\u8981\u3002",
|
|
269
|
+
"aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
|
|
270
|
+
"aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
|
|
271
|
+
"aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
|
|
272
|
+
"aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
273
|
+
"aiTools.manifestHeader": "\u53EF\u7528 UI \u5DE5\u5177\uFF08\u8C03\u7528\u540E\u5728\u7528\u6237\u754C\u9762\u6302\u8F7D\u53EF\u89C6\u5316\u7ED3\u679C\uFF09\uFF1A",
|
|
274
|
+
"aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
|
|
275
|
+
"aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
|
|
276
|
+
"aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
|
|
277
|
+
"aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
|
|
278
|
+
"aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
|
|
279
|
+
"aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
|
|
280
|
+
"aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
|
|
281
|
+
"aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
|
|
282
|
+
"aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
|
|
283
|
+
"aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
|
|
284
|
+
/* ── autocomplete ── */
|
|
285
|
+
"suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
|
|
286
|
+
"suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
287
|
+
"suggestions.options": "\u5EFA\u8BAE",
|
|
288
|
+
"suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
|
|
289
|
+
"autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
290
|
+
/* ── backTop ── */
|
|
291
|
+
"backTop.label": "\u56DE\u5230\u9876\u90E8",
|
|
292
|
+
/* ── carousel ── */
|
|
293
|
+
"carousel.item": "\u7B2C {p0} \u5F20",
|
|
294
|
+
"carousel.region": "\u8F6E\u64AD",
|
|
295
|
+
"carousel.slide": "\u5E7B\u706F\u7247",
|
|
296
|
+
"carousel.status": "\u7B2C {p0} / {p1} \u5F20",
|
|
297
|
+
/* ── charts ── */
|
|
298
|
+
"charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
|
|
299
|
+
"charts.few": "\u5C11",
|
|
300
|
+
"charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
|
|
301
|
+
"charts.loading": "\u52A0\u8F7D\u4E2D",
|
|
302
|
+
"charts.many": "\u591A",
|
|
303
|
+
"charts.monthLabel": "{p0}\u6708",
|
|
304
|
+
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
305
|
+
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
306
|
+
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
307
|
+
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
308
|
+
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
309
|
+
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
310
|
+
"charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
|
|
311
|
+
"charts.type.heatmap": "\u70ED\u529B\u56FE",
|
|
312
|
+
"charts.type.line": "\u6298\u7EBF\u56FE",
|
|
313
|
+
"charts.type.map": "\u5730\u56FE",
|
|
314
|
+
"charts.type.radar": "\u96F7\u8FBE\u56FE",
|
|
315
|
+
"charts.type.scatter": "\u6563\u70B9\u56FE",
|
|
316
|
+
"charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
|
|
317
|
+
"charts.seriesName": "\u7CFB\u5217{p0}",
|
|
318
|
+
"charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
|
|
319
|
+
"charts.value": "\u6570\u503C",
|
|
320
|
+
/* ── themeSwitcher ── */
|
|
321
|
+
"themeSwitcher.appearance": "\u5916\u89C2",
|
|
322
|
+
"themeSwitcher.theme": "\u4E3B\u9898",
|
|
323
|
+
"themeSwitcher.primitive": "\u539F\u8BED",
|
|
324
|
+
"themeSwitcher.mode": "\u660E\u6697",
|
|
325
|
+
"themeSwitcher.light": "\u6D45\u8272",
|
|
326
|
+
"themeSwitcher.dark": "\u6DF1\u8272",
|
|
327
|
+
"themeSwitcher.modern": "\u73B0\u4EE3",
|
|
328
|
+
"themeSwitcher.dongyun": "\u4E1C\u97F5",
|
|
329
|
+
"themeSwitcher.jugou": "\u5DE8\u6784",
|
|
330
|
+
"themeSwitcher.piano": "\u94A2\u7434",
|
|
331
|
+
"themeSwitcher.monet": "\u83AB\u5948",
|
|
332
|
+
"themeSwitcher.vangogh": "\u68B5\u9AD8",
|
|
333
|
+
"themeSwitcher.chinese": "\u4E2D\u5F0F",
|
|
334
|
+
"themeSwitcher.soviet": "\u82CF\u5F0F",
|
|
335
|
+
"themeSwitcher.pixel": "\u50CF\u7D20",
|
|
336
|
+
/* ── codeBlock ── */
|
|
337
|
+
"codeBlock.collapse": "\u6536\u8D77",
|
|
338
|
+
"codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
|
|
339
|
+
"codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
340
|
+
"codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
|
|
341
|
+
"codeBlock.copy": "\u590D\u5236",
|
|
342
|
+
"codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
|
|
343
|
+
"codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
|
|
344
|
+
"codeBlock.linesTotal": "\u5171 {p0} \u884C",
|
|
345
|
+
"codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
|
|
346
|
+
"codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
|
|
347
|
+
"codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
|
|
348
|
+
"codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
|
|
349
|
+
"codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
|
|
350
|
+
/* ── common ── */
|
|
351
|
+
"common.accept": "\u63A5\u53D7",
|
|
352
|
+
"common.add": "\u65B0\u589E",
|
|
353
|
+
"common.all": "\u5168\u90E8",
|
|
354
|
+
"common.approve": "\u6279\u51C6",
|
|
355
|
+
"common.cancel": "\u53D6\u6D88",
|
|
356
|
+
"common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
357
|
+
"common.close": "\u5173\u95ED",
|
|
358
|
+
"common.confirm": "\u786E\u8BA4",
|
|
359
|
+
"common.copied": "\u5DF2\u590D\u5236",
|
|
360
|
+
"common.copy": "\u590D\u5236",
|
|
361
|
+
"common.delete": "\u5220\u9664",
|
|
362
|
+
"common.enable": "\u542F\u7528",
|
|
363
|
+
"common.exportCsv": "\u5BFC\u51FA CSV",
|
|
364
|
+
"common.healthy": "\u6B63\u5E38",
|
|
365
|
+
"common.input": "\u8F93\u5165",
|
|
366
|
+
"common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
|
|
367
|
+
"common.official": "\u5B98\u65B9",
|
|
368
|
+
"common.output": "\u8F93\u51FA",
|
|
369
|
+
"common.page": "\u7B2C {p0} \u9875",
|
|
370
|
+
"common.reject": "\u62D2\u7EDD",
|
|
371
|
+
"common.remove": "\u79FB\u9664",
|
|
372
|
+
"common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
|
|
373
|
+
"common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
|
|
374
|
+
"common.restricted": "\u53D7\u9650",
|
|
375
|
+
"common.retry": "\u91CD\u8BD5",
|
|
376
|
+
"common.rows": "{p0} \u884C",
|
|
377
|
+
"common.run": "\u8FD0\u884C",
|
|
378
|
+
"common.steps": "{p0} \u6B65",
|
|
379
|
+
"common.submit": "\u63D0\u4EA4",
|
|
380
|
+
"common.unknown": "\u672A\u77E5",
|
|
381
|
+
/* ── contextMenu ── */
|
|
382
|
+
"contextMenu.back": "\u540E\u9000",
|
|
383
|
+
"contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
|
|
384
|
+
"contextMenu.forward": "\u524D\u8FDB",
|
|
385
|
+
"contextMenu.refresh": "\u5237\u65B0",
|
|
386
|
+
/* ── copy ── */
|
|
387
|
+
"copy.copied": "\u5DF2\u590D\u5236",
|
|
388
|
+
"copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
389
|
+
"copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
|
|
390
|
+
"copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
|
|
391
|
+
"copy.unknown": "\u672A\u77E5\u9519\u8BEF",
|
|
392
|
+
/* ── datatable ── */
|
|
393
|
+
"datatable.clear": "\u6E05\u7A7A",
|
|
394
|
+
"datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
|
|
395
|
+
"datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
|
|
396
|
+
"datatable.countUnit": "{p0} \u6761",
|
|
397
|
+
"datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
|
|
398
|
+
"datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
|
|
399
|
+
"datatable.empty": "\u6682\u65E0\u6570\u636E",
|
|
400
|
+
"datatable.emptyValue": "\uFF08\u7A7A\uFF09",
|
|
401
|
+
"datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
|
|
402
|
+
"datatable.expandRow": "\u5C55\u5F00\u884C",
|
|
403
|
+
"datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
|
|
404
|
+
"datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
|
|
405
|
+
"datatable.paginationAria": "\u5206\u9875",
|
|
406
|
+
"datatable.reset": "\u91CD\u7F6E",
|
|
407
|
+
"datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
|
|
408
|
+
"datatable.searchAria": "\u641C\u7D22\u8868\u683C",
|
|
409
|
+
"datatable.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
410
|
+
"datatable.selectAll": "\u5168\u9009",
|
|
411
|
+
"datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
|
|
412
|
+
"datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
|
|
413
|
+
"datatable.totalCount": "\u5171 {p0} \u6761",
|
|
414
|
+
"datatable.totalLabel": "\u5408\u8BA1",
|
|
415
|
+
/* ── datePicker ── */
|
|
416
|
+
"datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
|
|
417
|
+
"datePicker.clear": "\u6E05\u9664",
|
|
418
|
+
"datePicker.nextMonth": "\u4E0B\u4E00\u6708",
|
|
419
|
+
"datePicker.prevMonth": "\u4E0A\u4E00\u6708",
|
|
420
|
+
"datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
|
|
421
|
+
"datePicker.today": "\u4ECA\u5929",
|
|
422
|
+
"datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
|
|
423
|
+
"datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
|
|
424
|
+
"datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
|
|
425
|
+
/* ── formValidate ── */
|
|
426
|
+
"formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
|
|
427
|
+
"formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
|
|
428
|
+
"formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
|
|
429
|
+
"formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
|
|
430
|
+
"formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
|
|
431
|
+
"formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
|
|
432
|
+
"formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
|
|
433
|
+
"formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
|
|
434
|
+
"formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
435
|
+
"formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
|
|
436
|
+
"formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
|
|
437
|
+
"formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
|
|
438
|
+
"formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
|
|
439
|
+
"formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
|
|
440
|
+
"formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
|
|
441
|
+
"formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
|
|
442
|
+
"formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
|
|
443
|
+
"formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
|
|
444
|
+
"formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
|
|
445
|
+
"formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
|
|
446
|
+
"formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
|
|
447
|
+
"formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
|
|
448
|
+
"formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
|
|
449
|
+
"formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
|
|
450
|
+
"formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
|
|
451
|
+
"formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
|
|
452
|
+
"formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
|
|
453
|
+
/* ── input ── */
|
|
454
|
+
"input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
|
|
455
|
+
"input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
|
|
456
|
+
"input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
|
|
457
|
+
"panel.expand": "\u5C55\u5F00",
|
|
458
|
+
"panel.collapse": "\u6298\u53E0",
|
|
459
|
+
"input.showPassword": "\u663E\u793A\u5BC6\u7801",
|
|
460
|
+
/* ── kbAccess ── */
|
|
461
|
+
"kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
462
|
+
"kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
|
|
463
|
+
"kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
464
|
+
"kbAccess.daysLeft": "{p0} \u5929\u540E",
|
|
465
|
+
"kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
|
|
466
|
+
"kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
|
|
467
|
+
"kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
468
|
+
"kbAccess.duration30d": "30 \u5929",
|
|
469
|
+
"kbAccess.duration7d": "7 \u5929",
|
|
470
|
+
"kbAccess.durationForever": "\u6C38\u4E45",
|
|
471
|
+
"kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
|
|
472
|
+
"kbAccess.expired": "\u5DF2\u5230\u671F",
|
|
473
|
+
"kbAccess.expiresAt": "{p0}\u5230\u671F",
|
|
474
|
+
"kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
|
|
475
|
+
"kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
|
|
476
|
+
"kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
|
|
477
|
+
"kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
|
|
478
|
+
"kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
|
|
479
|
+
"kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
|
|
480
|
+
"kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
|
|
481
|
+
"kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
|
|
482
|
+
"kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
|
|
483
|
+
"kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
484
|
+
"kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
|
|
485
|
+
"kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
|
|
486
|
+
"kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
|
|
487
|
+
"kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
|
|
488
|
+
"kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
|
|
489
|
+
"kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
|
|
490
|
+
"kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
|
|
491
|
+
"kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
|
|
492
|
+
"kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
|
|
493
|
+
"kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
|
|
494
|
+
"kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
|
|
495
|
+
/* ── kbAcl ── */
|
|
496
|
+
"kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
|
|
497
|
+
"kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
|
|
498
|
+
"kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
|
|
499
|
+
"kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
|
|
500
|
+
"kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
|
|
501
|
+
"kbAcl.exception": "\u4F8B\u5916",
|
|
502
|
+
"kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
|
|
503
|
+
"kbAcl.expiresIn": "{p0} \u5230\u671F",
|
|
504
|
+
"kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
|
|
505
|
+
"kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
|
|
506
|
+
"kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
|
|
507
|
+
"kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
|
|
508
|
+
"kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
|
|
509
|
+
"kbAcl.noLinks": "\u65E0\u94FE\u63A5",
|
|
510
|
+
"kbAcl.removeEntry": "\u79FB\u9664 {p0}",
|
|
511
|
+
"kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
|
|
512
|
+
"kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
|
|
513
|
+
"kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
|
|
514
|
+
"kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
|
|
515
|
+
"kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
|
|
516
|
+
"kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
|
|
517
|
+
"kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
|
|
518
|
+
/* ── kbAnswer ── */
|
|
519
|
+
"kbAnswer.chartBar": "\u67F1\u72B6",
|
|
520
|
+
"kbAnswer.chartLine": "\u6298\u7EBF",
|
|
521
|
+
"kbAnswer.chartPie": "\u997C\u56FE",
|
|
522
|
+
"kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
|
|
523
|
+
"kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
|
|
524
|
+
"kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
|
|
525
|
+
"kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
|
|
526
|
+
"kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
|
|
527
|
+
"kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
|
|
528
|
+
"kbAnswer.kindFunction": "\u51FD\u6570",
|
|
529
|
+
"kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
|
|
530
|
+
"kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
|
|
531
|
+
"kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
|
|
532
|
+
"kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
|
|
533
|
+
"kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
|
|
534
|
+
/* ── kbAudit ── */
|
|
535
|
+
"kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
|
|
536
|
+
"kbAudit.actionLabel": "\u5904\u7F6E",
|
|
537
|
+
"kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
|
|
538
|
+
"kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
|
|
539
|
+
"kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
|
|
540
|
+
"kbAudit.channelRead": "\u8BFB\u53D6",
|
|
541
|
+
"kbAudit.channelRequest": "\u7533\u8BF7",
|
|
542
|
+
"kbAudit.channelSystem": "\u7CFB\u7EDF",
|
|
543
|
+
"kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
|
|
544
|
+
"kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
|
|
545
|
+
"kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
|
|
546
|
+
"kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
|
|
547
|
+
/* ── kbCanvas ── */
|
|
548
|
+
"kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
|
|
549
|
+
"kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
|
|
550
|
+
/* ── kbCheckpoint ── */
|
|
551
|
+
"kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
|
|
552
|
+
"kbCheckpoint.label": "\u68C0\u67E5\u70B9",
|
|
553
|
+
"kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
|
|
554
|
+
"kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
|
|
555
|
+
"kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
|
|
556
|
+
"kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
|
|
557
|
+
"kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
|
|
558
|
+
/* ── kbChunks ── */
|
|
559
|
+
"kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
|
|
560
|
+
"kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
|
|
561
|
+
"kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
|
|
562
|
+
"kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
|
|
563
|
+
"kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
|
|
564
|
+
"kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
|
|
565
|
+
"kbChunks.edited": "\u5DF2\u7F16\u8F91",
|
|
566
|
+
"kbChunks.empty": "\u6682\u65E0 chunk",
|
|
567
|
+
"kbChunks.modeFull": "\u5168\u6587",
|
|
568
|
+
"kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
|
|
569
|
+
"kbChunks.modeVector": "\u8BED\u4E49",
|
|
570
|
+
"kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
|
|
571
|
+
"kbChunks.searchAria": "\u641C\u7D22 chunk",
|
|
572
|
+
"kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
|
|
573
|
+
"kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
|
|
574
|
+
/* ── kbCitation ── */
|
|
575
|
+
"kbCitation.sourceN": "\u6765\u6E90 {p0}",
|
|
576
|
+
"kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
|
|
577
|
+
/* ── kbClarify ── */
|
|
578
|
+
"kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
|
|
579
|
+
/* ── kbConflict ── */
|
|
580
|
+
"kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
|
|
581
|
+
/* ── kbConnector ── */
|
|
582
|
+
"kbConnector.changeRate": "\u53D8\u66F4\u7387",
|
|
583
|
+
"kbConnector.crawlRate": "\u6293\u53D6\u7387",
|
|
584
|
+
"kbConnector.credentials": "\u51ED\u8BC1",
|
|
585
|
+
"kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
|
|
586
|
+
"kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
|
|
587
|
+
"kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
|
|
588
|
+
"kbConnector.failing": "\u5F02\u5E38",
|
|
589
|
+
"kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
|
|
590
|
+
"kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
|
|
591
|
+
"kbConnector.notConfigured": "\u672A\u914D\u7F6E",
|
|
592
|
+
"kbConnector.off": "\u5DF2\u505C\u7528",
|
|
593
|
+
"kbConnector.perDay": "{p0}/\u5929",
|
|
594
|
+
"kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
|
|
595
|
+
"kbConnector.stale": "\u505C\u6EDE",
|
|
596
|
+
"kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
|
|
597
|
+
"kbConnector.synced": "\u5DF2\u540C\u6B65",
|
|
598
|
+
/* ── kbCore ── */
|
|
599
|
+
"kbCore.accessDenied": "\u672A\u901A\u8FC7",
|
|
600
|
+
"kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
|
|
601
|
+
"kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
|
|
602
|
+
"kbCore.accessGranted": "\u5DF2\u5F00\u901A",
|
|
603
|
+
"kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
|
|
604
|
+
"kbCore.accessPending": "\u5F85\u5BA1\u6279",
|
|
605
|
+
"kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
|
|
606
|
+
"kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
|
|
607
|
+
"kbCore.auditApprove": "\u6279\u51C6",
|
|
608
|
+
"kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
|
|
609
|
+
"kbCore.auditDelegation": "\u59D4\u6D3E",
|
|
610
|
+
"kbCore.auditDeny": "\u62D2\u7EDD",
|
|
611
|
+
"kbCore.auditGrant": "\u6388\u4E88",
|
|
612
|
+
"kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
|
|
613
|
+
"kbCore.auditPreview": "\u9884\u89C8",
|
|
614
|
+
"kbCore.auditRead": "\u8BFB\u53D6",
|
|
615
|
+
"kbCore.auditRequest": "\u7533\u8BF7",
|
|
616
|
+
"kbCore.auditRevoke": "\u6536\u56DE",
|
|
617
|
+
"kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
|
|
618
|
+
"kbCore.daysAgo": "{p0} \u5929\u524D",
|
|
619
|
+
"kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
|
|
620
|
+
"kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
|
|
621
|
+
"kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
|
|
622
|
+
"kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
|
|
623
|
+
"kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
|
|
624
|
+
"kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
|
|
625
|
+
"kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
|
|
626
|
+
"kbCore.justNow": "\u521A\u521A",
|
|
627
|
+
"kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
|
|
628
|
+
"kbCore.levelEdit": "\u53EF\u7F16\u8F91",
|
|
629
|
+
"kbCore.levelNone": "\u65E0\u6743\u9650",
|
|
630
|
+
"kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
|
|
631
|
+
"kbCore.levelView": "\u53EF\u67E5\u770B",
|
|
632
|
+
"kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
|
|
633
|
+
"kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
|
|
634
|
+
"kbCore.runDone": "\u5DF2\u5B8C\u6210",
|
|
635
|
+
"kbCore.runFailed": "\u5931\u8D25",
|
|
636
|
+
"kbCore.runQueued": "\u6392\u961F\u4E2D",
|
|
637
|
+
"kbCore.runRunning": "\u8FDB\u884C\u4E2D",
|
|
638
|
+
"kbCore.runUnstarted": "\u672A\u5F00\u59CB",
|
|
639
|
+
"kbCore.stageAgent": "\u4EE3\u7406",
|
|
640
|
+
"kbCore.stageChunk": "\u5207\u7247",
|
|
641
|
+
"kbCore.stageEmbed": "\u5411\u91CF\u5316",
|
|
642
|
+
"kbCore.stageGeneration": "\u751F\u6210",
|
|
643
|
+
"kbCore.stageGuard": "\u62A4\u680F",
|
|
644
|
+
"kbCore.stageQuery": "\u67E5\u8BE2",
|
|
645
|
+
"kbCore.stageRerank": "\u91CD\u6392",
|
|
646
|
+
"kbCore.stageRetrieval": "\u68C0\u7D22",
|
|
647
|
+
"kbCore.stageTool": "\u5DE5\u5177",
|
|
648
|
+
"kbCore.typeApi": "\u63A5\u53E3",
|
|
649
|
+
"kbCore.typeCode": "\u4EE3\u7801",
|
|
650
|
+
"kbCore.typeDatabase": "\u6570\u636E\u5E93",
|
|
651
|
+
"kbCore.typeDocument": "\u6587\u6863",
|
|
652
|
+
"kbCore.typeEmail": "\u90AE\u4EF6",
|
|
653
|
+
"kbCore.typeImage": "\u56FE\u7247",
|
|
654
|
+
"kbCore.typeKb": "\u77E5\u8BC6\u5E93",
|
|
655
|
+
"kbCore.typeTable": "\u8868\u683C",
|
|
656
|
+
"kbCore.typeTicket": "\u5DE5\u5355",
|
|
657
|
+
"kbCore.typeWebpage": "\u7F51\u9875",
|
|
658
|
+
"kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
|
|
659
|
+
"kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
|
|
660
|
+
"kbCore.visHidden": "\u4E0D\u53EF\u89C1",
|
|
661
|
+
"kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
|
|
662
|
+
"kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
|
|
663
|
+
"kbCore.visVisible": "\u53EF\u89C1",
|
|
664
|
+
/* ── kbEval ── */
|
|
665
|
+
"kbEval.avgA": "A \u5747\u5206 {p0}",
|
|
666
|
+
"kbEval.avgB": "B \u5747\u5206 {p0}",
|
|
667
|
+
"kbEval.compare": "\u5BF9\u6BD4",
|
|
668
|
+
"kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
|
|
669
|
+
"kbEval.expected": "\u671F\u671B",
|
|
670
|
+
"kbEval.gradeImprovement": "\u63D0\u5347",
|
|
671
|
+
"kbEval.gradeRegression": "\u56DE\u5F52",
|
|
672
|
+
"kbEval.gradeTie": "\u6301\u5E73",
|
|
673
|
+
"kbEval.gradeTradeoff": "\u6743\u8861",
|
|
674
|
+
"kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
|
|
675
|
+
"kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
|
|
676
|
+
"kbEval.outputA": "\u8F93\u51FA A",
|
|
677
|
+
"kbEval.outputB": "\u8F93\u51FA B",
|
|
678
|
+
"kbEval.outputN": "\u8F93\u51FA {p0}",
|
|
679
|
+
/* ── kbExplain ── */
|
|
680
|
+
"kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
|
|
681
|
+
"kbExplain.groupAgg": "\u805A\u5408",
|
|
682
|
+
"kbExplain.groupColumn": "\u5217",
|
|
683
|
+
"kbExplain.groupFilter": "\u7B5B\u9009",
|
|
684
|
+
"kbExplain.groupTable": "\u8868",
|
|
685
|
+
"kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
|
|
686
|
+
"kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
|
|
687
|
+
/* ── kbFilter ── */
|
|
688
|
+
"kbFilter.addGroup": "+ \u7EC4",
|
|
689
|
+
"kbFilter.addRule": "+ \u89C4\u5219",
|
|
690
|
+
"kbFilter.and": "\u4E14",
|
|
691
|
+
"kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
|
|
692
|
+
"kbFilter.copyDsl": "\u590D\u5236 DSL",
|
|
693
|
+
"kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
|
|
694
|
+
"kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
|
|
695
|
+
"kbFilter.fieldLabel": "\u5B57\u6BB5",
|
|
696
|
+
"kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
|
|
697
|
+
"kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
|
|
698
|
+
"kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
|
|
699
|
+
"kbFilter.opContains": "\u5305\u542B",
|
|
700
|
+
"kbFilter.opEq": "\u7B49\u4E8E",
|
|
701
|
+
"kbFilter.opExists": "\u5B58\u5728",
|
|
702
|
+
"kbFilter.opGt": "\u5927\u4E8E",
|
|
703
|
+
"kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
|
|
704
|
+
"kbFilter.opIn": "\u5C5E\u4E8E",
|
|
705
|
+
"kbFilter.opLt": "\u5C0F\u4E8E",
|
|
706
|
+
"kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
707
|
+
"kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
|
|
708
|
+
"kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
|
|
709
|
+
"kbFilter.or": "\u6216",
|
|
710
|
+
"kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
|
|
711
|
+
"kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
|
|
712
|
+
"kbFilter.valueLabel": "\u503C",
|
|
713
|
+
"kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
|
|
714
|
+
/* ── kbGap ── */
|
|
715
|
+
"kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
|
|
716
|
+
"kbGap.colCount": "\u6B21\u6570",
|
|
717
|
+
"kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
|
|
718
|
+
"kbGap.colQuery": "\u67E5\u8BE2",
|
|
719
|
+
"kbGap.colShare": "\u5360\u6BD4",
|
|
720
|
+
"kbGap.createDoc": "\u5EFA\u6587\u6863",
|
|
721
|
+
"kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
|
|
722
|
+
"kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
|
|
723
|
+
"kbGap.zeroClickHint": "\u7528\u6237\u53EF\u80FD\u5DF2\u4ECE\u5F15\u7528\u7247\u6BB5\u5F97\u5230\u7B54\u6848\uFF1B\u96F6\u70B9\u51FB\u9700\u4EBA\u5DE5\u5224\u8BFB\uFF0C\u4E0D\u76F4\u63A5\u89C6\u4E3A\u5931\u8D25",
|
|
724
|
+
"kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
|
|
725
|
+
"kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
|
|
726
|
+
/* ── kbHittest ── */
|
|
727
|
+
"kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
|
|
728
|
+
"kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
|
|
729
|
+
"kbHittest.avgScore": "\u5747\u5206",
|
|
730
|
+
"kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
|
|
731
|
+
"kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
|
|
732
|
+
"kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
|
|
733
|
+
"kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
|
|
734
|
+
"kbHittest.hitRate": "\u547D\u4E2D\u7387",
|
|
735
|
+
"kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
|
|
736
|
+
"kbHittest.notRun": "\u672A\u8FD0\u884C",
|
|
737
|
+
"kbHittest.pass": "\u901A\u8FC7",
|
|
738
|
+
"kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
|
|
739
|
+
"kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
|
|
740
|
+
"kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
741
|
+
"kbHittest.sessionOnlyHint": "\u6D4B\u8BD5\u8FD0\u884C\u7684\u68C0\u7D22\u53C2\u6570\uFF08topK/\u9608\u503C/\u91CD\u6392\uFF09\u4E0D\u843D\u5E93\uFF0C\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
742
|
+
"kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
|
|
743
|
+
/* ── kbMetadata ── */
|
|
744
|
+
"kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
|
|
745
|
+
"kbMetadata.builtIn": "\u5185\u7F6E",
|
|
746
|
+
"kbMetadata.colField": "\u5B57\u6BB5",
|
|
747
|
+
"kbMetadata.colType": "\u7C7B\u578B",
|
|
748
|
+
"kbMetadata.colValue": "\u503C",
|
|
749
|
+
"kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
|
|
750
|
+
"kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
|
|
751
|
+
"kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
|
|
752
|
+
"kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
|
|
753
|
+
"kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
|
|
754
|
+
"kbMetadata.valueOf": "{p0} \u7684\u503C",
|
|
755
|
+
/* ── kbPassage ── */
|
|
756
|
+
"kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
|
|
757
|
+
"kbPassage.close": "\u5173\u95ED\u539F\u6587",
|
|
758
|
+
"kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
|
|
759
|
+
"kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
|
|
760
|
+
"kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
|
|
761
|
+
"kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
|
|
762
|
+
"kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
|
|
763
|
+
"kbPassage.unitByte": "\u5B57\u8282",
|
|
764
|
+
"kbPassage.unitChar": "\u5B57\u7B26",
|
|
765
|
+
/* ── kbPipeline ── */
|
|
766
|
+
"kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
|
|
767
|
+
"kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
|
|
768
|
+
"kbPipeline.rerun": "\u91CD\u8DD1",
|
|
769
|
+
"kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
|
|
770
|
+
/* ── kbQa ── */
|
|
771
|
+
"kbQa.colAnswer": "\u7B54\u6848",
|
|
772
|
+
"kbQa.colQuestion": "\u95EE\u9898",
|
|
773
|
+
"kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
|
|
774
|
+
"kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
|
|
775
|
+
"kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
|
|
776
|
+
"kbQa.importCsv": "\u5BFC\u5165 CSV",
|
|
777
|
+
/* ── kbRerank ── */
|
|
778
|
+
"kbRerank.after": "\u91CD\u6392\u540E",
|
|
779
|
+
"kbRerank.before": "\u91CD\u6392\u524D",
|
|
780
|
+
"kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
|
|
781
|
+
"kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
|
|
782
|
+
"kbRerank.dropped": "\u843D\u9009",
|
|
783
|
+
"kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
|
|
784
|
+
"kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
|
|
785
|
+
"kbRerank.newIn": "\u65B0\u8FDB",
|
|
786
|
+
"kbRerank.unmarked": "\u672A\u6807",
|
|
787
|
+
"kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
|
|
788
|
+
/* ── kbRetrieval ── */
|
|
789
|
+
"kbRetrieval.breakdown": "\u62C6\u89E3",
|
|
790
|
+
"kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
|
|
791
|
+
"kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
|
|
792
|
+
"kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
793
|
+
"kbRetrieval.failOpenNotice": "fail-open\uFF1A\u5F53\u524D\u67E5\u8BE2\u672A\u643A\u5E26\u8EAB\u4EFD\u8FC7\u6EE4\uFF0C\u5C06\u8FD4\u56DE\u5168\u90E8\u5019\u9009\uFF08\u4EC5\u9650\u8C03\u8BD5\uFF09",
|
|
794
|
+
"kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
|
|
795
|
+
"kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
|
|
796
|
+
"kbRetrieval.identityShort": "\u8EAB\u4EFD",
|
|
797
|
+
"kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
|
|
798
|
+
"kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
|
|
799
|
+
"kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
|
|
800
|
+
"kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
|
|
801
|
+
"kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
|
|
802
|
+
"kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
|
|
803
|
+
"kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
|
|
804
|
+
"kbRetrieval.modeHybrid": "\u6DF7\u5408",
|
|
805
|
+
"kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
|
|
806
|
+
"kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
|
|
807
|
+
"kbRetrieval.modeVector": "\u5411\u91CF",
|
|
808
|
+
"kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
|
|
809
|
+
"kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
|
|
810
|
+
"kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
|
|
811
|
+
"kbRetrieval.rerankLabel": "\u91CD\u6392",
|
|
812
|
+
"kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
|
|
813
|
+
"kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
|
|
814
|
+
"kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
|
|
815
|
+
"kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
|
|
816
|
+
"kbRetrieval.thresholdValue": "\u9608\u503C N/A",
|
|
817
|
+
"kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
|
|
818
|
+
"kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
|
|
819
|
+
"kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
|
|
820
|
+
/* ── kbReview ── */
|
|
821
|
+
"kbReview.assignee": "\u5206\u914D\u4EBA",
|
|
822
|
+
"kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
|
|
823
|
+
"kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
|
|
824
|
+
"kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
|
|
825
|
+
"kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
|
|
826
|
+
"kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
|
|
827
|
+
"kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
|
|
828
|
+
"kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
|
|
829
|
+
"kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
|
|
830
|
+
"kbReview.shortcuts": "? \u5FEB\u6377\u952E",
|
|
831
|
+
"kbReview.typeAnswer": "\u56DE\u7B54",
|
|
832
|
+
"kbReview.typeMessage": "\u6D88\u606F",
|
|
833
|
+
"kbReview.typeTrace": "\u8F68\u8FF9",
|
|
834
|
+
"kbReview.unassigned": "\u672A\u5206\u914D",
|
|
835
|
+
/* ── kbSandbox ── */
|
|
836
|
+
"kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
|
|
837
|
+
"kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
|
|
838
|
+
"kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
|
|
839
|
+
"kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
840
|
+
"kbSandbox.title": "MCP App \u6C99\u7BB1",
|
|
841
|
+
/* ── kbSegment ── */
|
|
842
|
+
"kbSegment.avgLength": "\u5747\u957F {p0}",
|
|
843
|
+
"kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
|
|
844
|
+
"kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
|
|
845
|
+
"kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
|
|
846
|
+
"kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
|
|
847
|
+
"kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
|
|
848
|
+
"kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
|
|
849
|
+
"kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
|
|
850
|
+
"kbSegment.modeAuto": "\u81EA\u52A8",
|
|
851
|
+
"kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
|
|
852
|
+
"kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
|
|
853
|
+
"kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
|
|
854
|
+
"kbSegment.modeParentChild": "\u7236\u5B50",
|
|
855
|
+
"kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
|
|
856
|
+
"kbSegment.overlapLabel": "\u91CD\u53E0",
|
|
857
|
+
"kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
|
|
858
|
+
"kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
|
|
859
|
+
"kbSegment.segmentsCount": "{p0} \u6BB5",
|
|
860
|
+
"kbSegment.separatorLabel": "\u5206\u9694\u7B26",
|
|
861
|
+
"kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
|
|
862
|
+
"kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
|
|
863
|
+
/* ── kbSources ── */
|
|
864
|
+
"kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
|
|
865
|
+
"kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
866
|
+
/* ── kbSql ── */
|
|
867
|
+
"kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
|
|
868
|
+
"kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
|
|
869
|
+
"kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
|
|
870
|
+
"kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
|
|
871
|
+
"kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
|
|
872
|
+
"kbSql.generated": "\u751F\u6210\u7684 SQL",
|
|
873
|
+
/* ── kbTrace ── */
|
|
874
|
+
"kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
|
|
875
|
+
"kbTrace.hits": "\u547D\u4E2D {p0}",
|
|
876
|
+
/* ── kbVisibility ── */
|
|
877
|
+
"kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
|
|
878
|
+
"kbVisibility.adminWarn": "admin \u5BA1\u8BA1\u89C6\u56FE\u2014\u2014\u547D\u4E2D\u5DEE\u5F02\u5BF9\u7167\u5BF9\u666E\u901A\u7528\u6237\u6784\u6210\u6CC4\u9732\uFF0C\u52FF\u5D4C\u5165\u7EC8\u7AEF\u7528\u6237\u754C\u9762",
|
|
879
|
+
"kbVisibility.failOpenNote": "fail-open\uFF1AKendra \u65E0\u8EAB\u4EFD\u4E0A\u4E0B\u6587\u8FD4\u56DE\u5168\u90E8\u6587\u6863\u2014\u2014\u68C0\u7D22\u5FC5\u987B\u643A\u5E26\u670D\u52A1\u7AEF\u8EAB\u4EFD",
|
|
880
|
+
"kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
|
|
881
|
+
"kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
|
|
882
|
+
"kbVisibility.leakageNote": "\u8BA1\u6570\u5DEE\u5F02\u5373 volume leakage\uFF1A\u5BF9\u666E\u901A\u7528\u6237\u53EA\u53EF\u7ED9\u300C\u5DF2\u6309\u6743\u9650\u8FC7\u6EE4\u300D\u6052\u5B9A\u6587\u6848\uFF0C\u7F13\u89E3\u53EA\u6709 padding \u53D6\u6574",
|
|
883
|
+
"kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
|
|
884
|
+
"kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
|
|
885
|
+
"kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
|
|
886
|
+
"kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
|
|
887
|
+
"kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
|
|
888
|
+
/* ── kbWhoCan ── */
|
|
889
|
+
"kbWhoCan.check": "\u68C0\u67E5",
|
|
890
|
+
"kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
|
|
891
|
+
"kbWhoCan.daysUntil": "{p0} \u5929\u540E",
|
|
892
|
+
"kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
|
|
893
|
+
"kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
|
|
894
|
+
"kbWhoCan.direct": "\u76F4\u63A5",
|
|
895
|
+
"kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
|
|
896
|
+
"kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
|
|
897
|
+
"kbWhoCan.inherit": "\u7EE7\u627F",
|
|
898
|
+
"kbWhoCan.link": "\u94FE\u63A5",
|
|
899
|
+
"kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
|
|
900
|
+
"kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
|
|
901
|
+
"kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
|
|
902
|
+
"kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
|
|
903
|
+
"kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
|
|
904
|
+
/* ── mentions ── */
|
|
905
|
+
"mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
|
|
906
|
+
"mentions.customBadge": "\u81EA\u5B9A\u4E49",
|
|
907
|
+
"mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
908
|
+
/* ── notification ── */
|
|
909
|
+
"notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
|
|
910
|
+
"notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
|
|
911
|
+
"notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
|
|
912
|
+
"notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
|
|
913
|
+
"notification.ariaLabel": "\u901A\u77E5",
|
|
914
|
+
"notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
|
|
915
|
+
/* ── pagination ── */
|
|
916
|
+
"pagination.next": "\u4E0B\u4E00\u9875",
|
|
917
|
+
"pagination.pageSize": "{p0} \u6761/\u9875",
|
|
918
|
+
"pagination.prev": "\u4E0A\u4E00\u9875",
|
|
919
|
+
/* ── select ── */
|
|
920
|
+
"select.fieldLabel": "\u9009\u62E9\u9009\u9879",
|
|
921
|
+
"select.noMatch": "\u65E0\u5339\u914D\u9879",
|
|
922
|
+
"select.remove": "\u79FB\u9664 {p0}",
|
|
923
|
+
"select.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
924
|
+
/* ── cascader / tree-select ── */
|
|
925
|
+
"cascader.placeholder": "\u8BF7\u9009\u62E9",
|
|
926
|
+
"cascader.noMatch": "\u65E0\u5339\u914D",
|
|
927
|
+
"cascader.search": "\u641C\u7D22",
|
|
928
|
+
"treeSelect.placeholder": "\u8BF7\u9009\u62E9",
|
|
929
|
+
"treeSelect.noMatch": "\u65E0\u5339\u914D",
|
|
930
|
+
"treeSelect.search": "\u641C\u7D22",
|
|
931
|
+
/* ── tagInput ── */
|
|
932
|
+
"tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
|
|
933
|
+
"tagInput.remove": "\u79FB\u9664 {p0}",
|
|
934
|
+
"tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
|
|
935
|
+
"tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
|
|
936
|
+
"tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
|
|
937
|
+
"tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
|
|
938
|
+
"tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
|
|
939
|
+
/* ── upload ── */
|
|
940
|
+
"upload.remove": "\u79FB\u9664 {p0}",
|
|
941
|
+
"upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
|
|
942
|
+
"upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
|
|
943
|
+
"upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
|
|
944
|
+
};
|
|
945
|
+
var current = { ...ICEN_LOCALE_ZH_CN };
|
|
946
|
+
function t(key, vars) {
|
|
947
|
+
const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
|
|
948
|
+
if (vars == null || Array.isArray(raw)) return raw;
|
|
949
|
+
return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/behaviors/svg-parse.ts
|
|
953
|
+
function parseSvg(source) {
|
|
954
|
+
if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
|
|
955
|
+
const trimmed = source.trimStart();
|
|
956
|
+
if (!trimmed.startsWith("<svg")) return null;
|
|
957
|
+
const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
|
|
958
|
+
let parsed;
|
|
959
|
+
try {
|
|
960
|
+
parsed = new DOMParser().parseFromString(src, "image/svg+xml");
|
|
961
|
+
} catch {
|
|
962
|
+
return null;
|
|
963
|
+
}
|
|
964
|
+
const root = parsed.documentElement;
|
|
965
|
+
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
|
|
966
|
+
const sanitize = (el) => {
|
|
967
|
+
for (const attr of Array.from(el.attributes)) {
|
|
968
|
+
const name = attr.name.toLowerCase();
|
|
969
|
+
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
970
|
+
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
971
|
+
el.removeAttribute(attr.name);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
for (const child of Array.from(el.children)) {
|
|
975
|
+
const tag = child.tagName.toLowerCase();
|
|
976
|
+
if (tag === "script" || tag === "foreignobject") {
|
|
977
|
+
child.remove();
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
sanitize(child);
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
sanitize(root);
|
|
984
|
+
return document.importNode(root, true);
|
|
985
|
+
}
|
|
986
|
+
|
|
1
987
|
// src/behaviors/ai-core.ts
|
|
2
988
|
var USAGE_KEYS = ["input", "output", "cacheRead", "cacheWrite", "reasoning", "total"];
|
|
3
989
|
function addUsage(sum2, u) {
|
|
@@ -8,54 +994,23 @@ function addUsage(sum2, u) {
|
|
|
8
994
|
}
|
|
9
995
|
return out;
|
|
10
996
|
}
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
);
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
);
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
);
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
var ICON_SCAN_SEARCH = svg(
|
|
30
|
-
'<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/>'
|
|
31
|
-
);
|
|
32
|
-
var ICON_GLOBE = svg(
|
|
33
|
-
'<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>'
|
|
34
|
-
);
|
|
35
|
-
var ICON_DOWNLOAD = svg(
|
|
36
|
-
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>'
|
|
37
|
-
);
|
|
38
|
-
var ICON_BLOCKS = svg(
|
|
39
|
-
'<rect width="7" height="7" x="4" y="4" rx="1"/><rect width="7" height="7" x="13" y="4" rx="1"/><rect width="7" height="7" x="4" y="13" rx="1"/><rect width="7" height="7" x="13" y="13" rx="1"/>'
|
|
40
|
-
);
|
|
41
|
-
var ICON_ZAP = svg(
|
|
42
|
-
'<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>'
|
|
43
|
-
);
|
|
44
|
-
var ICON_LIST = svg(
|
|
45
|
-
'<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>'
|
|
46
|
-
);
|
|
47
|
-
var ICON_LIST_CHECKS = svg(
|
|
48
|
-
'<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>'
|
|
49
|
-
);
|
|
50
|
-
var ICON_BOT = svg(
|
|
51
|
-
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
52
|
-
);
|
|
53
|
-
var ICON_CHART = svg(
|
|
54
|
-
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
55
|
-
);
|
|
56
|
-
var ICON_FILE_TEXT = svg(
|
|
57
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
58
|
-
);
|
|
997
|
+
var ICON_TERMINAL = iconHTML("terminal");
|
|
998
|
+
var ICON_FILE = iconHTML("file");
|
|
999
|
+
var ICON_FILE_PEN = iconHTML("edit");
|
|
1000
|
+
var ICON_FILE_PLUS = iconHTML("plus");
|
|
1001
|
+
var ICON_TRASH = iconHTML("trash");
|
|
1002
|
+
var ICON_SEARCH = iconHTML("search");
|
|
1003
|
+
var ICON_FOLDER_SEARCH = iconHTML("folder");
|
|
1004
|
+
var ICON_SCAN_SEARCH = iconHTML("search");
|
|
1005
|
+
var ICON_GLOBE = iconHTML("globe");
|
|
1006
|
+
var ICON_DOWNLOAD = iconHTML("download");
|
|
1007
|
+
var ICON_BLOCKS = iconHTML("server");
|
|
1008
|
+
var ICON_ZAP = iconHTML("sparkle");
|
|
1009
|
+
var ICON_LIST = iconHTML("list");
|
|
1010
|
+
var ICON_LIST_CHECKS = iconHTML("list");
|
|
1011
|
+
var ICON_BOT = iconHTML("agent");
|
|
1012
|
+
var ICON_CHART = iconHTML("chart-line");
|
|
1013
|
+
var ICON_FILE_TEXT = iconHTML("document");
|
|
59
1014
|
function isObj(v) {
|
|
60
1015
|
return typeof v === "object" && v !== null;
|
|
61
1016
|
}
|
|
@@ -105,32 +1060,32 @@ var sum = (fn) => {
|
|
|
105
1060
|
return (input) => fn(input) ?? "";
|
|
106
1061
|
};
|
|
107
1062
|
var BUILTIN_KINDS = {
|
|
108
|
-
shell: { label: "
|
|
109
|
-
read: { label: "
|
|
110
|
-
edit: { label: "
|
|
111
|
-
write: { label: "
|
|
112
|
-
rm: { label: "
|
|
113
|
-
grep: { label: "
|
|
114
|
-
glob: { label: "
|
|
115
|
-
browser: { label: "
|
|
116
|
-
search: { label: "
|
|
117
|
-
fetch: { label: "
|
|
1063
|
+
shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
1064
|
+
read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
1065
|
+
edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
1066
|
+
write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
1067
|
+
rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
1068
|
+
grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
1069
|
+
glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
1070
|
+
browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
1071
|
+
search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
1072
|
+
fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
118
1073
|
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
119
|
-
skill: { label: "
|
|
1074
|
+
skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
120
1075
|
todo: {
|
|
121
|
-
label: "
|
|
1076
|
+
label: t("aiCore.kindTodo"),
|
|
122
1077
|
icon: ICON_LIST,
|
|
123
1078
|
tint: "info",
|
|
124
1079
|
summarize: sum((input) => {
|
|
125
1080
|
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
126
1081
|
const done = items.filter((it) => it?.status === "done").length;
|
|
127
|
-
return items.length > 0 ?
|
|
1082
|
+
return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
|
|
128
1083
|
})
|
|
129
1084
|
},
|
|
130
|
-
plan: { label: "
|
|
131
|
-
subagent: { label: "
|
|
132
|
-
note: { label: "
|
|
133
|
-
chart: { label: "
|
|
1085
|
+
plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
|
|
1086
|
+
subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
1087
|
+
note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
|
|
1088
|
+
chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
134
1089
|
};
|
|
135
1090
|
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
136
1091
|
function normalizeUsage(raw) {
|
|
@@ -185,51 +1140,45 @@ function contextEstimate(usage) {
|
|
|
185
1140
|
return (u.input ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0) + (u.output ?? 0) + (u.reasoning ?? 0);
|
|
186
1141
|
}
|
|
187
1142
|
function h(tag, className, text) {
|
|
1143
|
+
if (typeof document === "undefined") throw new Error("h() \u4EC5\u6D4F\u89C8\u5668\u73AF\u5883\u53EF\u7528\uFF08SSR \u65F6\u7531\u8C03\u7528\u65B9\u5B88\u536B\uFF0C\u89C1\u6A21\u5757\u5934\u6CE8\u91CA\uFF09");
|
|
188
1144
|
const node = document.createElement(tag);
|
|
189
1145
|
if (className) node.className = className;
|
|
190
1146
|
if (text != null) node.textContent = text;
|
|
191
1147
|
return node;
|
|
192
1148
|
}
|
|
193
|
-
function svgIcon(
|
|
194
|
-
|
|
195
|
-
let parsed;
|
|
196
|
-
try {
|
|
197
|
-
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
198
|
-
} catch {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
const root = parsed.documentElement;
|
|
202
|
-
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
const sanitize = (el) => {
|
|
206
|
-
for (const attr of Array.from(el.attributes)) {
|
|
207
|
-
const name = attr.name.toLowerCase();
|
|
208
|
-
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
209
|
-
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
210
|
-
el.removeAttribute(attr.name);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
for (const child of Array.from(el.children)) {
|
|
214
|
-
const tag = child.tagName.toLowerCase();
|
|
215
|
-
if (tag === "script" || tag === "foreignobject") {
|
|
216
|
-
child.remove();
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
sanitize(child);
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
sanitize(root);
|
|
223
|
-
return document.importNode(root, true);
|
|
1149
|
+
function svgIcon(svg) {
|
|
1150
|
+
return parseSvg(svg);
|
|
224
1151
|
}
|
|
225
1152
|
|
|
226
1153
|
// src/behaviors/popover.ts
|
|
1154
|
+
function revealPopoverItem(item, scrollport, opts = {}) {
|
|
1155
|
+
if (typeof document === "undefined") return;
|
|
1156
|
+
if (opts.focus) item.focus({ preventScroll: true });
|
|
1157
|
+
const rect = item.getBoundingClientRect(), bounds = scrollport.getBoundingClientRect();
|
|
1158
|
+
const style = getComputedStyle(scrollport);
|
|
1159
|
+
const inset = (value, extent) => {
|
|
1160
|
+
const amount = Number.parseFloat(value) || 0;
|
|
1161
|
+
return value.endsWith("%") ? amount * extent / 100 : amount;
|
|
1162
|
+
};
|
|
1163
|
+
if (opts.axis !== "inline") {
|
|
1164
|
+
const top = bounds.top + scrollport.clientTop + inset(style.scrollPaddingTop, scrollport.clientHeight);
|
|
1165
|
+
const bottom = bounds.top + scrollport.clientTop + scrollport.clientHeight - inset(style.scrollPaddingBottom, scrollport.clientHeight);
|
|
1166
|
+
if (rect.top < top) scrollport.scrollTop -= top - rect.top;
|
|
1167
|
+
else if (rect.bottom > bottom) scrollport.scrollTop += rect.bottom - bottom;
|
|
1168
|
+
}
|
|
1169
|
+
if (opts.axis === "inline" || opts.axis === "both") {
|
|
1170
|
+
const left = bounds.left + scrollport.clientLeft + inset(style.scrollPaddingLeft, scrollport.clientWidth);
|
|
1171
|
+
const right = bounds.left + scrollport.clientLeft + scrollport.clientWidth - inset(style.scrollPaddingRight, scrollport.clientWidth);
|
|
1172
|
+
if (rect.left < left) scrollport.scrollLeft -= left - rect.left;
|
|
1173
|
+
else if (rect.right > right) scrollport.scrollLeft += rect.right - right;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
227
1176
|
var PANEL_SIZING_ATTRS = {
|
|
228
|
-
width: "data-panel-width",
|
|
229
|
-
minWidth: "data-panel-min",
|
|
230
|
-
maxWidth: "data-panel-max",
|
|
231
|
-
minHeight: "data-panel-min-height",
|
|
232
|
-
maxHeight: "data-panel-max-height"
|
|
1177
|
+
width: "data-icen-panel-width",
|
|
1178
|
+
minWidth: "data-icen-panel-min",
|
|
1179
|
+
maxWidth: "data-icen-panel-max",
|
|
1180
|
+
minHeight: "data-icen-panel-min-height",
|
|
1181
|
+
maxHeight: "data-icen-panel-max-height"
|
|
233
1182
|
};
|
|
234
1183
|
function readPanelSizing(el) {
|
|
235
1184
|
const out = {};
|
|
@@ -289,10 +1238,10 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
289
1238
|
const preferredSide = opts.side ?? "top";
|
|
290
1239
|
const align = opts.align ?? "start";
|
|
291
1240
|
if (preferredSide === "left" || preferredSide === "right") {
|
|
1241
|
+
const minWidth2 = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
292
1242
|
const availableLeft = Math.max(0, anchor.left - margin - offset);
|
|
293
1243
|
const availableRight = Math.max(0, viewport.width - anchor.right - margin - offset);
|
|
294
|
-
const side2 = (preferredSide === "left" ? availableLeft : availableRight) >=
|
|
295
|
-
const minWidth2 = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
1244
|
+
const side2 = (preferredSide === "left" ? availableLeft : availableRight) >= minWidth2 ? preferredSide : preferredSide === "left" ? "right" : "left";
|
|
296
1245
|
const maxWidth2 = Math.min(
|
|
297
1246
|
Math.max(opts.maxWidth ?? DEFAULT_MAX_WIDTH, minWidth2),
|
|
298
1247
|
side2 === "left" ? availableLeft : availableRight
|
|
@@ -321,7 +1270,7 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
321
1270
|
const minHeight = Math.min(Math.max(80, opts.minHeight ?? DEFAULT_MIN_HEIGHT), availableHeight);
|
|
322
1271
|
const requestedMaxHeight = Math.max(minHeight, opts.maxHeight ?? DEFAULT_MAX_HEIGHT);
|
|
323
1272
|
const fallbackHeight = Math.min(260, requestedMaxHeight);
|
|
324
|
-
const contentHeight =
|
|
1273
|
+
const contentHeight = opts.contentHeightHint != null && opts.contentHeightHint > 0 ? opts.contentHeightHint : fallbackHeight;
|
|
325
1274
|
const desiredHeight = clamp(contentHeight, minHeight, Math.min(requestedMaxHeight, availableHeight));
|
|
326
1275
|
const side = chooseSide(preferredSide, availableTop, availableBottom, desiredHeight);
|
|
327
1276
|
const sideSpace = side === "top" ? availableTop : availableBottom;
|
|
@@ -338,6 +1287,9 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
338
1287
|
return { side, left, top, width, maxHeight };
|
|
339
1288
|
}
|
|
340
1289
|
var openPanels = /* @__PURE__ */ new Map();
|
|
1290
|
+
var closingPanels = /* @__PURE__ */ new Map();
|
|
1291
|
+
var EXIT_FALLBACK_MS = 240;
|
|
1292
|
+
var menuCloser = null;
|
|
341
1293
|
function rectFromElement(el) {
|
|
342
1294
|
const r = el.getBoundingClientRect();
|
|
343
1295
|
return { left: r.left, top: r.top, right: r.right, bottom: r.bottom, width: r.width, height: r.height };
|
|
@@ -355,21 +1307,54 @@ function relayout(state) {
|
|
|
355
1307
|
closePopover(state.panel);
|
|
356
1308
|
return;
|
|
357
1309
|
}
|
|
358
|
-
|
|
1310
|
+
let layout = computePopoverLayout(
|
|
359
1311
|
anchor,
|
|
360
1312
|
{ width: window.innerWidth, height: window.innerHeight },
|
|
361
1313
|
state.opts
|
|
362
1314
|
);
|
|
363
1315
|
const { panel } = state;
|
|
1316
|
+
const scrollPositions = [panel, ...panel.querySelectorAll("*")].filter((node) => node.scrollTop !== 0 || node.scrollLeft !== 0).map((node) => ({ node, top: node.scrollTop, left: node.scrollLeft }));
|
|
1317
|
+
panel.style.width = `${layout.width}px`;
|
|
1318
|
+
if (state.opts.contentHeightHint == null && (layout.side === "top" || layout.side === "bottom")) {
|
|
1319
|
+
panel.style.maxHeight = `${Math.min(state.opts.maxHeight ?? DEFAULT_MAX_HEIGHT, Math.max(80, window.innerHeight - (state.opts.margin ?? 12) * 2))}px`;
|
|
1320
|
+
const measured = panel.offsetHeight;
|
|
1321
|
+
if (measured > 0) layout = computePopoverLayout(anchor, { width: window.innerWidth, height: window.innerHeight }, { ...state.opts, contentHeightHint: measured });
|
|
1322
|
+
}
|
|
364
1323
|
panel.style.left = `${layout.left}px`;
|
|
365
|
-
panel.style.top = `${layout.top}px`;
|
|
366
1324
|
panel.style.width = `${layout.width}px`;
|
|
367
1325
|
panel.style.maxHeight = `${layout.maxHeight}px`;
|
|
368
|
-
|
|
1326
|
+
let top = layout.top;
|
|
1327
|
+
const actualHeight = panel.offsetHeight;
|
|
1328
|
+
if (actualHeight > 0 && (layout.side === "top" || layout.side === "bottom")) {
|
|
1329
|
+
const desired = layout.side === "top" ? anchor.top - (state.opts.offset ?? 8) - actualHeight : anchor.bottom + (state.opts.offset ?? 8);
|
|
1330
|
+
const margin = state.opts.margin ?? 12;
|
|
1331
|
+
top = clamp(desired, margin, window.innerHeight - margin - actualHeight);
|
|
1332
|
+
}
|
|
1333
|
+
panel.style.top = `${top}px`;
|
|
1334
|
+
for (const pos of scrollPositions) {
|
|
1335
|
+
pos.node.scrollTop = pos.top;
|
|
1336
|
+
pos.node.scrollLeft = pos.left;
|
|
1337
|
+
}
|
|
1338
|
+
panel.dataset.icenSide = layout.side;
|
|
369
1339
|
panel.style.visibility = state.prevVisibility;
|
|
370
1340
|
}
|
|
371
|
-
function
|
|
372
|
-
|
|
1341
|
+
function observeOpenPanel(state) {
|
|
1342
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
1343
|
+
state.resizeObserver = new ResizeObserver(() => {
|
|
1344
|
+
if (state.layoutFrame != null) return;
|
|
1345
|
+
state.layoutFrame = window.requestAnimationFrame(() => {
|
|
1346
|
+
state.layoutFrame = void 0;
|
|
1347
|
+
if (openPanels.get(state.panel) === state) relayout(state);
|
|
1348
|
+
});
|
|
1349
|
+
});
|
|
1350
|
+
state.resizeObserver.observe(state.panel);
|
|
1351
|
+
if (state.anchor instanceof Element) state.resizeObserver.observe(state.anchor);
|
|
1352
|
+
}
|
|
1353
|
+
function onWindowChange(event) {
|
|
1354
|
+
openPanels.forEach((state) => {
|
|
1355
|
+
if (event?.type === "scroll" && event.target instanceof Node && state.panel.contains(event.target)) return;
|
|
1356
|
+
relayout(state);
|
|
1357
|
+
});
|
|
373
1358
|
}
|
|
374
1359
|
function onOutsidePointerDown(e) {
|
|
375
1360
|
const target = e.target;
|
|
@@ -381,18 +1366,40 @@ function onOutsidePointerDown(e) {
|
|
|
381
1366
|
});
|
|
382
1367
|
}
|
|
383
1368
|
function onKeyDown(e) {
|
|
384
|
-
if (e.key !== "Escape") return;
|
|
1369
|
+
if (e.key !== "Escape" || e.defaultPrevented || e.isComposing || e.keyCode === 229 || menuCloser) return;
|
|
385
1370
|
const states = Array.from(openPanels.values());
|
|
386
1371
|
const top = states[states.length - 1];
|
|
387
1372
|
if (top) {
|
|
388
1373
|
e.preventDefault();
|
|
1374
|
+
e.stopPropagation();
|
|
389
1375
|
closePopover(top.panel);
|
|
390
1376
|
}
|
|
391
1377
|
}
|
|
392
1378
|
function openPopover(panel, options) {
|
|
393
1379
|
if (typeof document === "undefined") return;
|
|
1380
|
+
const pending = closingPanels.get(panel);
|
|
1381
|
+
if (pending) {
|
|
1382
|
+
window.clearTimeout(pending.timer);
|
|
1383
|
+
panel.removeEventListener("transitionend", pending.onEnd);
|
|
1384
|
+
closingPanels.delete(panel);
|
|
1385
|
+
delete panel.dataset.icenState;
|
|
1386
|
+
openPanels.set(panel, pending.state);
|
|
1387
|
+
panel.hidden = false;
|
|
1388
|
+
panel.style.visibility = "hidden";
|
|
1389
|
+
relayout(pending.state);
|
|
1390
|
+
observeOpenPanel(pending.state);
|
|
1391
|
+
if (openPanels.size === 1) {
|
|
1392
|
+
window.addEventListener("resize", onWindowChange);
|
|
1393
|
+
window.addEventListener("scroll", onWindowChange, true);
|
|
1394
|
+
document.addEventListener("pointerdown", onOutsidePointerDown, true);
|
|
1395
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
1396
|
+
}
|
|
1397
|
+
const ifs = options.initialFocus;
|
|
1398
|
+
if (ifs && panel.contains(ifs)) ifs.focus({ preventScroll: true });
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
394
1401
|
if (openPanels.has(panel)) closePopover(panel);
|
|
395
|
-
const { anchor, onClose, sizing, ...rest } = options;
|
|
1402
|
+
const { anchor, onClose, sizing, initialFocus, restoreFocus, ...rest } = options;
|
|
396
1403
|
const layoutOpts = sizingToLayout(resolvePanelSizing(panel, sizing), rest);
|
|
397
1404
|
const placeholder = document.createComment("popover-anchor");
|
|
398
1405
|
panel.parentNode?.insertBefore(placeholder, panel);
|
|
@@ -405,25 +1412,25 @@ function openPopover(panel, options) {
|
|
|
405
1412
|
onClose,
|
|
406
1413
|
placeholder,
|
|
407
1414
|
wasHidden,
|
|
408
|
-
prevVisibility
|
|
1415
|
+
prevVisibility,
|
|
1416
|
+
returnFocus: restoreFocus === false ? null : anchor instanceof HTMLElement ? anchor : document.activeElement instanceof HTMLElement ? document.activeElement : null
|
|
409
1417
|
};
|
|
410
1418
|
openPanels.set(panel, state);
|
|
411
1419
|
document.body.appendChild(panel);
|
|
412
1420
|
panel.hidden = false;
|
|
413
1421
|
panel.style.visibility = "hidden";
|
|
414
1422
|
relayout(state);
|
|
1423
|
+
observeOpenPanel(state);
|
|
1424
|
+
if (initialFocus && panel.contains(initialFocus)) initialFocus.focus({ preventScroll: true });
|
|
415
1425
|
if (openPanels.size === 1) {
|
|
416
1426
|
window.addEventListener("resize", onWindowChange);
|
|
417
1427
|
window.addEventListener("scroll", onWindowChange, true);
|
|
418
1428
|
document.addEventListener("pointerdown", onOutsidePointerDown, true);
|
|
419
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1429
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
420
1430
|
}
|
|
421
1431
|
}
|
|
422
|
-
function
|
|
423
|
-
|
|
424
|
-
const state = openPanels.get(panel);
|
|
425
|
-
if (!state) return;
|
|
426
|
-
openPanels.delete(panel);
|
|
1432
|
+
function finalizeClose(panel, state) {
|
|
1433
|
+
delete panel.dataset.icenState;
|
|
427
1434
|
panel.style.visibility = state.prevVisibility;
|
|
428
1435
|
if (typeof state.wasHidden === "string") panel.setAttribute("hidden", state.wasHidden);
|
|
429
1436
|
else panel.hidden = state.wasHidden;
|
|
@@ -431,55 +1438,90 @@ function closePopover(panel) {
|
|
|
431
1438
|
panel.style.top = "";
|
|
432
1439
|
panel.style.width = "";
|
|
433
1440
|
panel.style.maxHeight = "";
|
|
434
|
-
delete panel.dataset.
|
|
1441
|
+
delete panel.dataset.icenSide;
|
|
435
1442
|
if (state.placeholder.parentNode) {
|
|
436
1443
|
state.placeholder.parentNode.insertBefore(panel, state.placeholder);
|
|
437
1444
|
state.placeholder.remove();
|
|
438
1445
|
}
|
|
1446
|
+
}
|
|
1447
|
+
function closePopover(panel, opts) {
|
|
1448
|
+
if (typeof document === "undefined") return;
|
|
1449
|
+
const state = openPanels.get(panel);
|
|
1450
|
+
if (!state) return;
|
|
1451
|
+
openPanels.delete(panel);
|
|
1452
|
+
state.resizeObserver?.disconnect();
|
|
1453
|
+
if (state.layoutFrame != null) {
|
|
1454
|
+
window.cancelAnimationFrame(state.layoutFrame);
|
|
1455
|
+
state.layoutFrame = void 0;
|
|
1456
|
+
}
|
|
1457
|
+
const ownsFocus = panel.contains(document.activeElement);
|
|
1458
|
+
if (ownsFocus && state.returnFocus?.isConnected) state.returnFocus.focus({ preventScroll: true });
|
|
439
1459
|
if (openPanels.size === 0) {
|
|
440
1460
|
window.removeEventListener("resize", onWindowChange);
|
|
441
1461
|
window.removeEventListener("scroll", onWindowChange, true);
|
|
442
1462
|
document.removeEventListener("pointerdown", onOutsidePointerDown, true);
|
|
443
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1463
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
444
1464
|
}
|
|
445
1465
|
state.onClose?.();
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
)
|
|
1466
|
+
const calm = opts?.immediate || typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1467
|
+
if (calm || !panel.isConnected) {
|
|
1468
|
+
finalizeClose(panel, state);
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
panel.dataset.icenState = "closing";
|
|
1472
|
+
const finalize = () => {
|
|
1473
|
+
const pending = closingPanels.get(panel);
|
|
1474
|
+
if (!pending || pending.state !== state) return;
|
|
1475
|
+
window.clearTimeout(pending.timer);
|
|
1476
|
+
panel.removeEventListener("transitionend", pending.onEnd);
|
|
1477
|
+
closingPanels.delete(panel);
|
|
1478
|
+
finalizeClose(panel, state);
|
|
1479
|
+
};
|
|
1480
|
+
const onEnd = (event) => {
|
|
1481
|
+
if (event.target === panel && event.propertyName === "opacity") finalize();
|
|
1482
|
+
};
|
|
1483
|
+
panel.addEventListener("transitionend", onEnd);
|
|
1484
|
+
closingPanels.set(panel, {
|
|
1485
|
+
state,
|
|
1486
|
+
timer: window.setTimeout(finalize, EXIT_FALLBACK_MS),
|
|
1487
|
+
onEnd
|
|
1488
|
+
});
|
|
453
1489
|
}
|
|
454
1490
|
|
|
455
1491
|
// src/behaviors/ai-panel.ts
|
|
456
1492
|
function buildTodoHead(done, total) {
|
|
457
|
-
const head = h("div", "ai-todo-head");
|
|
458
|
-
head.appendChild(h("span", "ai-todo-progress", `${done}/${total}`));
|
|
459
|
-
const bar = h("div", "ai-todo-bar");
|
|
1493
|
+
const head = h("div", "icen-ai-todo-head");
|
|
1494
|
+
head.appendChild(h("span", "icen-ai-todo-progress", `${done}/${total}`));
|
|
1495
|
+
const bar = h("div", "icen-ai-todo-bar");
|
|
460
1496
|
bar.setAttribute("role", "progressbar");
|
|
461
1497
|
bar.setAttribute("aria-valuemin", "0");
|
|
462
1498
|
bar.setAttribute("aria-valuemax", String(total));
|
|
463
1499
|
bar.setAttribute("aria-valuenow", String(done));
|
|
464
|
-
bar.setAttribute("aria-label", "
|
|
1500
|
+
bar.setAttribute("aria-label", t("aiPanel.taskProgress"));
|
|
465
1501
|
const fill = document.createElement("i");
|
|
466
1502
|
fill.style.width = total > 0 ? `${Math.round(done / total * 100)}%` : "0%";
|
|
467
1503
|
bar.appendChild(fill);
|
|
468
1504
|
head.appendChild(bar);
|
|
469
1505
|
return head;
|
|
470
1506
|
}
|
|
1507
|
+
var ICON_TODO_CHECK = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m3.5 12.5 5 5L20.5 6" pathLength="1"/></svg>';
|
|
471
1508
|
function buildTodoItem(item, index) {
|
|
472
|
-
const row = h("div", `ai-todo-item is-${item.status}`);
|
|
473
|
-
row.dataset.
|
|
474
|
-
row.appendChild(h("span", "ai-item-status"));
|
|
475
|
-
|
|
476
|
-
|
|
1509
|
+
const row = h("div", `icen-ai-todo-item is-${item.status}`);
|
|
1510
|
+
row.dataset.icenIndex = String(index);
|
|
1511
|
+
row.appendChild(h("span", "icen-ai-item-status"));
|
|
1512
|
+
const check = h("span", "icen-ai-todo-check is-anim");
|
|
1513
|
+
check.setAttribute("aria-hidden", "true");
|
|
1514
|
+
const checkSvg = svgIcon(ICON_TODO_CHECK);
|
|
1515
|
+
if (checkSvg) check.appendChild(checkSvg);
|
|
1516
|
+
row.appendChild(check);
|
|
1517
|
+
row.appendChild(h("span", "icen-ai-todo-text", item.content));
|
|
1518
|
+
row.appendChild(h("span", "icen-ai-todo-active", item.activeForm ?? item.content));
|
|
477
1519
|
return row;
|
|
478
1520
|
}
|
|
479
1521
|
function renderAiTodo(el, items) {
|
|
480
1522
|
if (typeof document === "undefined") return el;
|
|
481
1523
|
el.textContent = "";
|
|
482
|
-
const root = h("div", "ai-todo");
|
|
1524
|
+
const root = h("div", "icen-ai-todo");
|
|
483
1525
|
const list = Array.isArray(items) ? items : [];
|
|
484
1526
|
const done = list.filter((i) => i.status === "done").length;
|
|
485
1527
|
root.appendChild(buildTodoHead(done, list.length));
|
|
@@ -488,46 +1530,66 @@ function renderAiTodo(el, items) {
|
|
|
488
1530
|
el.appendChild(root);
|
|
489
1531
|
return el;
|
|
490
1532
|
}
|
|
1533
|
+
function metricField(src, key) {
|
|
1534
|
+
return typeof src === "object" && src !== null ? src[key] : void 0;
|
|
1535
|
+
}
|
|
1536
|
+
function metricNum(v) {
|
|
1537
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
1538
|
+
}
|
|
1539
|
+
function metricStr(v) {
|
|
1540
|
+
return typeof v === "string" && v ? v : void 0;
|
|
1541
|
+
}
|
|
1542
|
+
function trimNum(v) {
|
|
1543
|
+
return String(Math.round(v * 10) / 10);
|
|
1544
|
+
}
|
|
491
1545
|
function renderAiUsage(el, usage, opts = {}) {
|
|
492
1546
|
if (typeof document === "undefined") return el;
|
|
493
1547
|
const u = normalizeUsage(usage);
|
|
494
1548
|
const segs = [
|
|
495
|
-
{ key: "input", className: "ai-usage-seg--input", label: "
|
|
496
|
-
{ key: "output", className: "ai-usage-seg--output", label: "
|
|
497
|
-
{ key: "cacheRead", className: "ai-usage-seg--cache-read", label: "
|
|
498
|
-
{ key: "cacheWrite", className: "ai-usage-seg--cache-write", label: "
|
|
499
|
-
{ key: "reasoning", className: "ai-usage-seg--reasoning", label: "
|
|
1549
|
+
{ key: "input", className: "icen-ai-usage-seg--input", label: t("common.input"), value: u.input ?? 0 },
|
|
1550
|
+
{ key: "output", className: "icen-ai-usage-seg--output", label: t("common.output"), value: u.output ?? 0 },
|
|
1551
|
+
{ key: "cacheRead", className: "icen-ai-usage-seg--cache-read", label: t("aiPanel.cacheRead"), value: u.cacheRead ?? 0 },
|
|
1552
|
+
{ key: "cacheWrite", className: "icen-ai-usage-seg--cache-write", label: t("aiPanel.cacheWrite"), value: u.cacheWrite ?? 0 },
|
|
1553
|
+
{ key: "reasoning", className: "icen-ai-usage-seg--reasoning", label: t("aiPanel.reasoning"), value: u.reasoning ?? 0 }
|
|
500
1554
|
];
|
|
501
1555
|
const activeSegs = segs.filter((s) => s.value > 0);
|
|
502
1556
|
const sum2 = activeSegs.reduce((acc, s) => acc + s.value, 0);
|
|
503
1557
|
const total = u.total ?? sum2;
|
|
504
1558
|
el.textContent = "";
|
|
505
|
-
const root = h("div", "ai-usage");
|
|
506
|
-
const bar = h("div", "ai-usage-bar");
|
|
507
|
-
const summary = activeSegs.length > 0 ? activeSegs.map((s) => `${s.label} ${formatTokens(s.value)}`).join("\uFF0C") : "
|
|
1559
|
+
const root = h("div", "icen-ai-usage");
|
|
1560
|
+
const bar = h("div", "icen-ai-usage-bar");
|
|
1561
|
+
const summary = activeSegs.length > 0 ? activeSegs.map((s) => `${s.label} ${formatTokens(s.value)}`).join("\uFF0C") : t("aiPanel.noUsage");
|
|
508
1562
|
bar.setAttribute("role", "img");
|
|
509
|
-
bar.setAttribute("aria-label",
|
|
1563
|
+
bar.setAttribute("aria-label", t("aiPanel.usageAria", { p0: summary }));
|
|
510
1564
|
for (const s of activeSegs) {
|
|
511
1565
|
const seg = document.createElement("i");
|
|
512
|
-
seg.className = `ai-usage-seg ${s.className}`;
|
|
1566
|
+
seg.className = `icen-ai-usage-seg ${s.className}`;
|
|
513
1567
|
seg.style.width = sum2 > 0 ? `${s.value / sum2 * 100}%` : "0%";
|
|
514
1568
|
bar.appendChild(seg);
|
|
515
1569
|
}
|
|
516
1570
|
root.appendChild(bar);
|
|
517
1571
|
if (activeSegs.length > 0) {
|
|
518
|
-
const legend = h("div", "ai-usage-legend");
|
|
1572
|
+
const legend = h("div", "icen-ai-usage-legend");
|
|
519
1573
|
for (const s of activeSegs) {
|
|
520
|
-
const item = h("span", "ai-usage-legend-item");
|
|
1574
|
+
const item = h("span", "icen-ai-usage-legend-item");
|
|
521
1575
|
const dot = document.createElement("i");
|
|
522
|
-
dot.className = `ai-usage-dot ${s.className}`;
|
|
1576
|
+
dot.className = `icen-ai-usage-dot ${s.className}`;
|
|
523
1577
|
dot.setAttribute("aria-hidden", "true");
|
|
524
1578
|
item.appendChild(dot);
|
|
525
|
-
item.appendChild(h("span", "ai-usage-legend-label", s.label));
|
|
526
|
-
item.appendChild(h("span", "ai-usage-legend-value", formatTokens(s.value)));
|
|
1579
|
+
item.appendChild(h("span", "icen-ai-usage-legend-label", s.label));
|
|
1580
|
+
item.appendChild(h("span", "icen-ai-usage-legend-value", formatTokens(s.value)));
|
|
527
1581
|
legend.appendChild(item);
|
|
528
1582
|
}
|
|
529
1583
|
root.appendChild(legend);
|
|
530
1584
|
}
|
|
1585
|
+
const ttft = metricNum(opts.metrics?.ttftMs) ?? metricNum(metricField(usage, "ttftMs"));
|
|
1586
|
+
const tps = metricNum(opts.metrics?.tokensPerSec) ?? metricNum(metricField(usage, "tokensPerSec"));
|
|
1587
|
+
const finish = metricStr(opts.metrics?.finishReason) ?? metricStr(metricField(usage, "finishReason"));
|
|
1588
|
+
const metricBits = [];
|
|
1589
|
+
if (ttft != null) metricBits.push(`TTFT ${formatDuration(ttft)}`);
|
|
1590
|
+
if (tps != null && tps > 0) metricBits.push(`${trimNum(tps)} tok/s`);
|
|
1591
|
+
if (finish) metricBits.push(`finish: ${finish}`);
|
|
1592
|
+
if (metricBits.length > 0) root.appendChild(h("div", "icen-ai-usage-metrics", metricBits.join(" \xB7 ")));
|
|
531
1593
|
const totalParts = [formatTokens(total)];
|
|
532
1594
|
if (typeof opts.total === "number" && opts.total > 0) {
|
|
533
1595
|
const pct = Math.min(100, Math.round(total / opts.total * 100));
|
|
@@ -536,7 +1598,7 @@ function renderAiUsage(el, usage, opts = {}) {
|
|
|
536
1598
|
if (typeof opts.cost === "number" && Number.isFinite(opts.cost)) {
|
|
537
1599
|
totalParts.push(` \xB7 $${opts.cost.toFixed(4)}`);
|
|
538
1600
|
}
|
|
539
|
-
root.appendChild(h("div", "ai-usage-total", totalParts.join("")));
|
|
1601
|
+
root.appendChild(h("div", "icen-ai-usage-total", totalParts.join("")));
|
|
540
1602
|
el.appendChild(root);
|
|
541
1603
|
return el;
|
|
542
1604
|
}
|
|
@@ -547,31 +1609,33 @@ function renderAiUsageRing(el, usage, opts = {}) {
|
|
|
547
1609
|
const hasLimit = typeof opts.total === "number" && opts.total > 0;
|
|
548
1610
|
const pct = hasLimit ? Math.min(100, Math.max(0, Math.round(used / opts.total * 100))) : 0;
|
|
549
1611
|
el.textContent = "";
|
|
550
|
-
const btn = h("button", "ai-usage-ring");
|
|
1612
|
+
const btn = h("button", "icen-ai-usage-ring");
|
|
551
1613
|
btn.type = "button";
|
|
552
1614
|
btn.classList.add(pct >= 85 ? "is-hot" : pct >= 60 ? "is-warn" : "is-ok");
|
|
553
1615
|
btn.setAttribute("aria-haspopup", "true");
|
|
554
1616
|
btn.setAttribute(
|
|
555
1617
|
"aria-label",
|
|
556
|
-
hasLimit ?
|
|
1618
|
+
hasLimit ? t("aiPanel.ringPercent", { p0: pct }) : t("aiPanel.ringUsed", { p0: formatTokens(used) })
|
|
557
1619
|
);
|
|
558
1620
|
const NS = "http://www.w3.org/2000/svg";
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
|
|
1621
|
+
const svg = document.createElementNS(NS, "svg");
|
|
1622
|
+
svg.setAttribute("viewBox", "0 0 36 36");
|
|
1623
|
+
svg.setAttribute("width", "36");
|
|
1624
|
+
svg.setAttribute("height", "36");
|
|
1625
|
+
svg.setAttribute("aria-hidden", "true");
|
|
562
1626
|
const track = document.createElementNS(NS, "circle");
|
|
563
|
-
track.setAttribute("class", "ai-usage-ring-track");
|
|
1627
|
+
track.setAttribute("class", "icen-ai-usage-ring-track");
|
|
564
1628
|
const fill = document.createElementNS(NS, "circle");
|
|
565
|
-
fill.setAttribute("class", "ai-usage-ring-fill");
|
|
1629
|
+
fill.setAttribute("class", "icen-ai-usage-ring-fill");
|
|
566
1630
|
fill.setAttribute("stroke-dasharray", `${pct} 100`);
|
|
567
1631
|
for (const c of [track, fill]) {
|
|
568
1632
|
c.setAttribute("cx", "18");
|
|
569
1633
|
c.setAttribute("cy", "18");
|
|
570
1634
|
c.setAttribute("r", "15.9155");
|
|
571
|
-
|
|
1635
|
+
svg.appendChild(c);
|
|
572
1636
|
}
|
|
573
|
-
btn.appendChild(
|
|
574
|
-
btn.appendChild(h("span", "ai-usage-ring-pct", hasLimit ? `${pct}%` : formatTokens(used)));
|
|
1637
|
+
btn.appendChild(svg);
|
|
1638
|
+
btn.appendChild(h("span", "icen-ai-usage-ring-pct", hasLimit ? `${pct}%` : formatTokens(used)));
|
|
575
1639
|
let panel = null;
|
|
576
1640
|
const closePanel = () => {
|
|
577
1641
|
if (!panel) return;
|
|
@@ -585,9 +1649,9 @@ function renderAiUsageRing(el, usage, opts = {}) {
|
|
|
585
1649
|
closePanel();
|
|
586
1650
|
return;
|
|
587
1651
|
}
|
|
588
|
-
const p = h("div", "popover ai-usage-popover");
|
|
1652
|
+
const p = h("div", "icen-popover icen-ai-usage-popover");
|
|
589
1653
|
p.hidden = true;
|
|
590
|
-
p.appendChild(h("div", "ai-usage-popover-title", opts.title ?? "
|
|
1654
|
+
p.appendChild(h("div", "icen-ai-usage-popover-title", opts.title ?? t("aiPanel.contextWindow")));
|
|
591
1655
|
const body = h("div", "ai-usage-popover-body");
|
|
592
1656
|
renderAiUsage(body, usage, opts);
|
|
593
1657
|
p.appendChild(body);
|
|
@@ -624,15 +1688,75 @@ var ICON_SPARKLES = svgWrap(
|
|
|
624
1688
|
);
|
|
625
1689
|
|
|
626
1690
|
// src/behaviors/ai-chat.ts
|
|
627
|
-
var ICON_COPY =
|
|
628
|
-
var ICON_RETRY =
|
|
1691
|
+
var ICON_COPY = iconHTML("copy");
|
|
1692
|
+
var ICON_RETRY = iconHTML("refresh");
|
|
1693
|
+
function emit(target, name, detail) {
|
|
1694
|
+
emitIcen(target, name, detail);
|
|
1695
|
+
}
|
|
1696
|
+
var REASONING_AUTO_CLOSE_MS = 1e3;
|
|
1697
|
+
function setReasoningOpen(reasoning, open) {
|
|
1698
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1699
|
+
const body = reasoning.querySelector(".icen-ai-reasoning-body");
|
|
1700
|
+
head?.setAttribute("aria-expanded", String(open));
|
|
1701
|
+
reasoning.classList.toggle("is-open", open);
|
|
1702
|
+
if (body) body.hidden = !open;
|
|
1703
|
+
}
|
|
1704
|
+
function clearContinueSlot(scope) {
|
|
1705
|
+
scope?.querySelectorAll(".icen-ai-msg-continue").forEach((n) => n.remove());
|
|
1706
|
+
}
|
|
629
1707
|
function createAiStream(el) {
|
|
630
|
-
const reasoning = el.closest(".ai-reasoning");
|
|
1708
|
+
const reasoning = el.closest(".icen-ai-reasoning");
|
|
1709
|
+
const msgBody = el.closest(".icen-ai-msg-body");
|
|
1710
|
+
const msg = el.closest(".icen-ai-msg");
|
|
631
1711
|
const startedAt = Date.now();
|
|
632
1712
|
let state = "streaming";
|
|
633
1713
|
el.classList.add("is-streaming");
|
|
634
1714
|
el.setAttribute("aria-busy", "true");
|
|
635
|
-
reasoning
|
|
1715
|
+
if (reasoning) {
|
|
1716
|
+
reasoning.classList.add("is-streaming");
|
|
1717
|
+
setReasoningOpen(reasoning, true);
|
|
1718
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1719
|
+
if (head && head.dataset.icenReasoningStart == null) head.dataset.icenReasoningStart = String(startedAt);
|
|
1720
|
+
}
|
|
1721
|
+
clearContinueSlot(msg ?? msgBody ?? el);
|
|
1722
|
+
const fillReasoningTime = () => {
|
|
1723
|
+
if (!reasoning) return;
|
|
1724
|
+
const time = reasoning.querySelector(".icen-ai-reasoning-time");
|
|
1725
|
+
if (!time) return;
|
|
1726
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1727
|
+
const raw = Number(head?.dataset.icenReasoningStart ?? "");
|
|
1728
|
+
const t0 = Number.isFinite(raw) && raw > 0 ? raw : startedAt;
|
|
1729
|
+
time.textContent = t("aiChat.thinking", { p0: formatDuration(Math.max(0, Date.now() - t0)) });
|
|
1730
|
+
};
|
|
1731
|
+
const scheduleReasoningAutoClose = () => {
|
|
1732
|
+
if (!reasoning) return;
|
|
1733
|
+
const r = reasoning;
|
|
1734
|
+
if (r.__icenReasonUserTouched || r.__icenReasonAutoClosed) return;
|
|
1735
|
+
const close = () => {
|
|
1736
|
+
if (r.__icenReasonUserTouched || r.__icenReasonAutoClosed) return;
|
|
1737
|
+
r.__icenReasonAutoClosed = true;
|
|
1738
|
+
setReasoningOpen(r, false);
|
|
1739
|
+
};
|
|
1740
|
+
if (typeof window === "undefined") {
|
|
1741
|
+
close();
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1744
|
+
window.setTimeout(close, REASONING_AUTO_CLOSE_MS);
|
|
1745
|
+
};
|
|
1746
|
+
const appendContinueSlot = () => {
|
|
1747
|
+
if (typeof document === "undefined") return;
|
|
1748
|
+
const mount = msgBody ?? msg ?? (el.parentElement instanceof HTMLElement ? el.parentElement : null);
|
|
1749
|
+
if (!mount || mount.querySelector(":scope > .icen-ai-msg-continue")) return;
|
|
1750
|
+
const btn = document.createElement("button");
|
|
1751
|
+
btn.type = "button";
|
|
1752
|
+
btn.className = "icen-ai-msg-continue";
|
|
1753
|
+
btn.textContent = t("aiChat.continue");
|
|
1754
|
+
btn.addEventListener("click", () => {
|
|
1755
|
+
const target = msg ?? btn;
|
|
1756
|
+
emit(target, "icen:ai-retry", { el: target });
|
|
1757
|
+
});
|
|
1758
|
+
mount.appendChild(btn);
|
|
1759
|
+
};
|
|
636
1760
|
const settle = (finished) => {
|
|
637
1761
|
if (state !== "streaming") return;
|
|
638
1762
|
state = finished ? "done" : "cancelled";
|
|
@@ -641,12 +1765,8 @@ function createAiStream(el) {
|
|
|
641
1765
|
if (!reasoning) return;
|
|
642
1766
|
reasoning.classList.remove("is-streaming");
|
|
643
1767
|
if (!finished) return;
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
head?.setAttribute("aria-expanded", "false");
|
|
647
|
-
if (body) body.hidden = true;
|
|
648
|
-
const time = reasoning.querySelector(".ai-reasoning-time");
|
|
649
|
-
if (time) time.textContent = formatDuration(Date.now() - startedAt);
|
|
1768
|
+
fillReasoningTime();
|
|
1769
|
+
scheduleReasoningAutoClose();
|
|
650
1770
|
};
|
|
651
1771
|
return {
|
|
652
1772
|
append(text) {
|
|
@@ -658,6 +1778,7 @@ function createAiStream(el) {
|
|
|
658
1778
|
},
|
|
659
1779
|
cancel() {
|
|
660
1780
|
settle(false);
|
|
1781
|
+
appendContinueSlot();
|
|
661
1782
|
},
|
|
662
1783
|
fail() {
|
|
663
1784
|
if (state !== "streaming") return;
|
|
@@ -665,15 +1786,20 @@ function createAiStream(el) {
|
|
|
665
1786
|
el.classList.remove("is-streaming");
|
|
666
1787
|
el.removeAttribute("aria-busy");
|
|
667
1788
|
el.classList.add("is-error");
|
|
668
|
-
reasoning
|
|
1789
|
+
if (reasoning) {
|
|
1790
|
+
reasoning.classList.remove("is-streaming");
|
|
1791
|
+
fillReasoningTime();
|
|
1792
|
+
scheduleReasoningAutoClose();
|
|
1793
|
+
}
|
|
1794
|
+
appendContinueSlot();
|
|
669
1795
|
}
|
|
670
1796
|
};
|
|
671
1797
|
}
|
|
672
1798
|
var ROLE_AVATAR = {
|
|
673
|
-
user: "
|
|
1799
|
+
user: t("aiChat.roleUser"),
|
|
674
1800
|
assistant: "AI",
|
|
675
|
-
system: "
|
|
676
|
-
tool: "
|
|
1801
|
+
system: t("aiChat.roleSystem"),
|
|
1802
|
+
tool: t("aiChat.roleTool")
|
|
677
1803
|
};
|
|
678
1804
|
function safeHref(uri) {
|
|
679
1805
|
const s = uri.trim().toLowerCase();
|
|
@@ -682,7 +1808,7 @@ function safeHref(uri) {
|
|
|
682
1808
|
}
|
|
683
1809
|
function renderAiContentPart(part) {
|
|
684
1810
|
if (part.type === "text") {
|
|
685
|
-
const span = h("span", "ai-msg-text");
|
|
1811
|
+
const span = h("span", "icen-ai-msg-text");
|
|
686
1812
|
span.textContent = part.text;
|
|
687
1813
|
if (part.state === "streaming") span.classList.add("is-streaming");
|
|
688
1814
|
return span;
|
|
@@ -691,7 +1817,7 @@ function renderAiContentPart(part) {
|
|
|
691
1817
|
const src = aiContentUrl(part);
|
|
692
1818
|
if (!src) return void 0;
|
|
693
1819
|
const img = document.createElement("img");
|
|
694
|
-
img.className = "ai-msg-media ai-msg-media--image";
|
|
1820
|
+
img.className = "icen-ai-msg-media icen-ai-msg-media--image";
|
|
695
1821
|
img.alt = part.alt ?? "";
|
|
696
1822
|
img.setAttribute("loading", "lazy");
|
|
697
1823
|
img.setAttribute("src", src);
|
|
@@ -701,7 +1827,7 @@ function renderAiContentPart(part) {
|
|
|
701
1827
|
const src = aiContentUrl(part);
|
|
702
1828
|
if (!src) return void 0;
|
|
703
1829
|
const audio = document.createElement("audio");
|
|
704
|
-
audio.className = "ai-msg-media ai-msg-media--audio";
|
|
1830
|
+
audio.className = "icen-ai-msg-media icen-ai-msg-media--audio";
|
|
705
1831
|
audio.controls = true;
|
|
706
1832
|
audio.setAttribute("src", src);
|
|
707
1833
|
return audio;
|
|
@@ -710,28 +1836,28 @@ function renderAiContentPart(part) {
|
|
|
710
1836
|
const src = aiContentUrl(part);
|
|
711
1837
|
if (!src) return void 0;
|
|
712
1838
|
const video = document.createElement("video");
|
|
713
|
-
video.className = "ai-msg-media ai-msg-media--video";
|
|
1839
|
+
video.className = "icen-ai-msg-media icen-ai-msg-media--video";
|
|
714
1840
|
video.controls = true;
|
|
715
1841
|
video.setAttribute("playsinline", "");
|
|
716
1842
|
video.setAttribute("src", src);
|
|
717
1843
|
return video;
|
|
718
1844
|
}
|
|
719
1845
|
if (part.type === "file") {
|
|
720
|
-
const chip = h("span", "ai-msg-file");
|
|
721
|
-
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? "
|
|
1846
|
+
const chip = h("span", "icen-ai-msg-file");
|
|
1847
|
+
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? t("aiChat.file")));
|
|
722
1848
|
const href2 = part.url ? safeHref(part.url) : void 0;
|
|
723
1849
|
if (href2 && /^(https?:|data:)/i.test(href2)) {
|
|
724
1850
|
const a2 = document.createElement("a");
|
|
725
|
-
a2.className = "ai-msg-file-link";
|
|
1851
|
+
a2.className = "icen-ai-msg-file-link";
|
|
726
1852
|
a2.href = href2;
|
|
727
1853
|
a2.download = part.filename ?? "";
|
|
728
|
-
a2.textContent = "
|
|
1854
|
+
a2.textContent = t("aiChat.download");
|
|
729
1855
|
chip.appendChild(a2);
|
|
730
1856
|
}
|
|
731
1857
|
return chip;
|
|
732
1858
|
}
|
|
733
1859
|
const a = document.createElement("a");
|
|
734
|
-
a.className = "ai-msg-link";
|
|
1860
|
+
a.className = "icen-ai-msg-link";
|
|
735
1861
|
const href = safeHref(part.uri);
|
|
736
1862
|
if (href) a.href = href;
|
|
737
1863
|
a.textContent = part.name ?? part.uri;
|
|
@@ -748,9 +1874,9 @@ function renderAiMessage(scrollEl, model) {
|
|
|
748
1874
|
stream: () => createAiStream(scrollEl)
|
|
749
1875
|
};
|
|
750
1876
|
}
|
|
751
|
-
const row = h("div", `ai-msg ai-msg--${model.role}`);
|
|
752
|
-
const avatar = h("span", "ai-msg-avatar", ROLE_AVATAR[model.role] ?? "");
|
|
753
|
-
const body = h("div", "ai-msg-body");
|
|
1877
|
+
const row = h("div", `icen-ai-msg icen-ai-msg--${model.role}`);
|
|
1878
|
+
const avatar = h("span", "icen-ai-msg-avatar", ROLE_AVATAR[model.role] ?? "");
|
|
1879
|
+
const body = h("div", "icen-ai-msg-body");
|
|
754
1880
|
row.appendChild(avatar);
|
|
755
1881
|
row.appendChild(body);
|
|
756
1882
|
const parts = typeof model.content === "string" ? [{ type: "text", text: model.content }] : model.content;
|
|
@@ -758,21 +1884,21 @@ function renderAiMessage(scrollEl, model) {
|
|
|
758
1884
|
const node = renderAiContentPart(part);
|
|
759
1885
|
if (node) body.appendChild(node);
|
|
760
1886
|
}
|
|
761
|
-
if (model.model) body.appendChild(h("span", "ai-msg-model", model.model));
|
|
762
|
-
const metaEl = h("div", "ai-msg-meta");
|
|
1887
|
+
if (model.model) body.appendChild(h("span", "icen-ai-msg-model", model.model));
|
|
1888
|
+
const metaEl = h("div", "icen-ai-msg-meta");
|
|
763
1889
|
if (model.meta != null) metaEl.textContent = model.meta;
|
|
764
1890
|
row.appendChild(metaEl);
|
|
765
|
-
const actions = h("div", "ai-msg-actions");
|
|
1891
|
+
const actions = h("div", "icen-ai-msg-actions");
|
|
766
1892
|
const copyBtn = h("button", "ai-msg-action");
|
|
767
1893
|
copyBtn.type = "button";
|
|
768
|
-
copyBtn.setAttribute("data-ai-msg-action", "copy");
|
|
769
|
-
copyBtn.setAttribute("aria-label", "
|
|
1894
|
+
copyBtn.setAttribute("data-icen-ai-msg-action", "copy");
|
|
1895
|
+
copyBtn.setAttribute("aria-label", t("common.copy"));
|
|
770
1896
|
const copyIcon = svgIcon(ICON_COPY);
|
|
771
1897
|
if (copyIcon) copyBtn.appendChild(copyIcon);
|
|
772
1898
|
const retryBtn = h("button", "ai-msg-action");
|
|
773
1899
|
retryBtn.type = "button";
|
|
774
|
-
retryBtn.setAttribute("data-ai-msg-action", "retry");
|
|
775
|
-
retryBtn.setAttribute("aria-label", "
|
|
1900
|
+
retryBtn.setAttribute("data-icen-ai-msg-action", "retry");
|
|
1901
|
+
retryBtn.setAttribute("aria-label", t("common.retry"));
|
|
776
1902
|
const retryIcon = svgIcon(ICON_RETRY);
|
|
777
1903
|
if (retryIcon) retryBtn.appendChild(retryIcon);
|
|
778
1904
|
actions.append(copyBtn, retryBtn);
|
|
@@ -784,10 +1910,11 @@ function renderAiMessage(scrollEl, model) {
|
|
|
784
1910
|
metaEl.textContent = meta;
|
|
785
1911
|
},
|
|
786
1912
|
setError(message) {
|
|
787
|
-
row.classList.add("ai-msg--error");
|
|
788
|
-
let errEl = row.querySelector(".ai-msg-error-text");
|
|
1913
|
+
row.classList.add("icen-ai-msg--error");
|
|
1914
|
+
let errEl = row.querySelector(".icen-ai-msg-error-text");
|
|
789
1915
|
if (!errEl) {
|
|
790
|
-
errEl = h("div", "ai-msg-error-text");
|
|
1916
|
+
errEl = h("div", "icen-ai-msg-error-text");
|
|
1917
|
+
errEl.setAttribute("role", "status");
|
|
791
1918
|
body.appendChild(errEl);
|
|
792
1919
|
}
|
|
793
1920
|
errEl.textContent = message;
|
|
@@ -804,34 +1931,102 @@ function renderAiMessage(scrollEl, model) {
|
|
|
804
1931
|
return handle;
|
|
805
1932
|
}
|
|
806
1933
|
|
|
1934
|
+
// src/behaviors/input.ts
|
|
1935
|
+
var searchFields = /* @__PURE__ */ new WeakMap();
|
|
1936
|
+
function enhanceSearchField(input) {
|
|
1937
|
+
if (typeof document === "undefined" || !input.parentElement) return { refresh() {
|
|
1938
|
+
}, destroy() {
|
|
1939
|
+
} };
|
|
1940
|
+
const previous = searchFields.get(input);
|
|
1941
|
+
if (previous) return previous;
|
|
1942
|
+
const host = input.parentElement;
|
|
1943
|
+
const wasFocused = document.activeElement === input;
|
|
1944
|
+
const hadHostClass = host.classList.contains("icen-search-field");
|
|
1945
|
+
const hadInputClass = input.classList.contains("icen-search-input");
|
|
1946
|
+
const hadStandardClass = input.classList.contains("icen-input");
|
|
1947
|
+
const ownedWrap = !host.classList.contains("icen-input-wrap");
|
|
1948
|
+
const next = input.nextSibling;
|
|
1949
|
+
const wrap = ownedWrap ? document.createElement("div") : host;
|
|
1950
|
+
if (ownedWrap) {
|
|
1951
|
+
wrap.className = "icen-input-wrap icen-input-wrap--sm icen-input-wrap--search icen-control";
|
|
1952
|
+
host.insertBefore(wrap, input);
|
|
1953
|
+
wrap.append(input);
|
|
1954
|
+
}
|
|
1955
|
+
const leading = wrap.querySelector(".icen-input-leading") ? null : document.createElement("span");
|
|
1956
|
+
if (leading) {
|
|
1957
|
+
leading.className = "icen-input-leading";
|
|
1958
|
+
leading.append(createIcon("search"));
|
|
1959
|
+
wrap.prepend(leading);
|
|
1960
|
+
}
|
|
1961
|
+
host.classList.add("icen-search-field");
|
|
1962
|
+
input.classList.add("icen-search-input", "icen-input");
|
|
1963
|
+
const clear = document.createElement("button");
|
|
1964
|
+
clear.type = "button";
|
|
1965
|
+
clear.className = "icen-input-clear icen-search-clear";
|
|
1966
|
+
clear.append(createIcon("close"));
|
|
1967
|
+
wrap.append(clear);
|
|
1968
|
+
const ac = new AbortController();
|
|
1969
|
+
let disposed = false;
|
|
1970
|
+
const refresh = () => {
|
|
1971
|
+
if (disposed) return;
|
|
1972
|
+
clear.hidden = !input.value || input.disabled || input.readOnly;
|
|
1973
|
+
clear.setAttribute("aria-label", t("input.clearSearch"));
|
|
1974
|
+
};
|
|
1975
|
+
clear.addEventListener("pointerdown", (event) => event.preventDefault(), { signal: ac.signal });
|
|
1976
|
+
clear.addEventListener("click", () => {
|
|
1977
|
+
if (input.disabled || input.readOnly) return;
|
|
1978
|
+
input.value = "";
|
|
1979
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1980
|
+
input.focus({ preventScroll: true });
|
|
1981
|
+
refresh();
|
|
1982
|
+
}, { signal: ac.signal });
|
|
1983
|
+
for (const event of ["input", "change", "focus"]) input.addEventListener(event, refresh, { signal: ac.signal });
|
|
1984
|
+
document.addEventListener("icen:locale-change", refresh, { signal: ac.signal });
|
|
1985
|
+
const observer = new MutationObserver(refresh);
|
|
1986
|
+
observer.observe(input, { attributes: true, attributeFilter: ["disabled", "readonly"] });
|
|
1987
|
+
refresh();
|
|
1988
|
+
if (wasFocused) input.focus({ preventScroll: true });
|
|
1989
|
+
const handle = { refresh, destroy() {
|
|
1990
|
+
if (disposed) return;
|
|
1991
|
+
disposed = true;
|
|
1992
|
+
observer.disconnect();
|
|
1993
|
+
ac.abort();
|
|
1994
|
+
clear.remove();
|
|
1995
|
+
leading?.remove();
|
|
1996
|
+
searchFields.delete(input);
|
|
1997
|
+
const focused = document.activeElement === input;
|
|
1998
|
+
if (ownedWrap) {
|
|
1999
|
+
host.insertBefore(input, next?.parentNode === host ? next : null);
|
|
2000
|
+
wrap.remove();
|
|
2001
|
+
}
|
|
2002
|
+
if (focused) input.focus({ preventScroll: true });
|
|
2003
|
+
if (!hadHostClass) host.classList.remove("icen-search-field");
|
|
2004
|
+
if (!hadInputClass) input.classList.remove("icen-search-input");
|
|
2005
|
+
if (!hadStandardClass) input.classList.remove("icen-input");
|
|
2006
|
+
} };
|
|
2007
|
+
searchFields.set(input, handle);
|
|
2008
|
+
return handle;
|
|
2009
|
+
}
|
|
2010
|
+
|
|
807
2011
|
// src/behaviors/ai-composer.ts
|
|
808
2012
|
var MAX_ROWS_DEFAULT = 8;
|
|
809
2013
|
var HISTORY_LIMIT = 50;
|
|
810
2014
|
var CACHE_WARN_RATIO = 0.4;
|
|
811
|
-
var SEND_ICON =
|
|
812
|
-
var STOP_ICON =
|
|
813
|
-
var ATTACH_ICON =
|
|
814
|
-
var
|
|
815
|
-
var
|
|
816
|
-
var
|
|
817
|
-
var
|
|
818
|
-
var
|
|
819
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>'
|
|
820
|
-
);
|
|
821
|
-
var ICON_FOLDER = svgWrap2(
|
|
822
|
-
'<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>'
|
|
823
|
-
);
|
|
824
|
-
var ICON_DOC = svgWrap2(
|
|
825
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
826
|
-
);
|
|
827
|
-
var ICON_BOT2 = svgWrap2(
|
|
828
|
-
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
829
|
-
);
|
|
2015
|
+
var SEND_ICON = iconHTML("arrow-up");
|
|
2016
|
+
var STOP_ICON = iconHTML("stop");
|
|
2017
|
+
var ATTACH_ICON = iconHTML("paperclip");
|
|
2018
|
+
var ICON_INFO = iconHTML("circle-info");
|
|
2019
|
+
var ICON_FILE3 = iconHTML("file");
|
|
2020
|
+
var ICON_FOLDER = iconHTML("folder");
|
|
2021
|
+
var ICON_DOC = iconHTML("document");
|
|
2022
|
+
var ICON_BOT2 = iconHTML("agent");
|
|
830
2023
|
var REF_KIND_BUILTIN = {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
2024
|
+
skill: { label: t("aiComposer.skills"), icon: iconHTML("sparkle"), order: -2 },
|
|
2025
|
+
tool: { label: t("aiComposer.tools"), icon: iconHTML("box"), order: -1 },
|
|
2026
|
+
file: { label: t("aiComposer.attachFile"), icon: ICON_FILE3, order: 0 },
|
|
2027
|
+
folder: { label: t("aiComposer.attachFolder"), icon: ICON_FOLDER, order: 1 },
|
|
2028
|
+
doc: { label: t("aiComposer.attachDoc"), icon: ICON_DOC, order: 2 },
|
|
2029
|
+
agent: { label: t("aiComposer.attachAgent"), icon: ICON_BOT2, order: 3 }
|
|
835
2030
|
};
|
|
836
2031
|
var REF_KIND_ORDER_LAST = Number.MAX_SAFE_INTEGER;
|
|
837
2032
|
var REF_KIND_REGISTRY = /* @__PURE__ */ new Map();
|
|
@@ -858,6 +2053,7 @@ function knownRefKinds(sources) {
|
|
|
858
2053
|
}
|
|
859
2054
|
var RUNNING = /* @__PURE__ */ new WeakMap();
|
|
860
2055
|
var QUEUES = /* @__PURE__ */ new WeakMap();
|
|
2056
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
861
2057
|
var MODELS = /* @__PURE__ */ new WeakMap();
|
|
862
2058
|
var MODEL_CTX = /* @__PURE__ */ new WeakMap();
|
|
863
2059
|
var COMMANDS = /* @__PURE__ */ new WeakMap();
|
|
@@ -872,18 +2068,18 @@ var POPUP_SIZING = /* @__PURE__ */ new WeakMap();
|
|
|
872
2068
|
function isBrowser() {
|
|
873
2069
|
return typeof document !== "undefined" && typeof window !== "undefined";
|
|
874
2070
|
}
|
|
875
|
-
function
|
|
2071
|
+
function emit2(target, name, detail) {
|
|
876
2072
|
emitIcen(target, name, detail);
|
|
877
2073
|
}
|
|
878
2074
|
function resolveComposer(el) {
|
|
879
|
-
return el.closest("[data-ai-composer]");
|
|
2075
|
+
return el.closest("[data-icen-ai-composer]");
|
|
880
2076
|
}
|
|
881
2077
|
function getTextarea(composer) {
|
|
882
|
-
return composer.querySelector(".ai-composer-input");
|
|
2078
|
+
return composer.querySelector(".icen-ai-composer-input");
|
|
883
2079
|
}
|
|
884
2080
|
function autosizeTa(ta) {
|
|
885
|
-
const composer = ta.closest("[data-ai-composer]");
|
|
886
|
-
const maxRows = Number(composer?.getAttribute("data-max-rows")) || MAX_ROWS_DEFAULT;
|
|
2081
|
+
const composer = ta.closest("[data-icen-ai-composer]");
|
|
2082
|
+
const maxRows = Number(composer?.getAttribute("data-icen-max-rows")) || MAX_ROWS_DEFAULT;
|
|
887
2083
|
const cs = window.getComputedStyle(ta);
|
|
888
2084
|
const lineHeight = parseFloat(cs.lineHeight) || 20;
|
|
889
2085
|
const padY = (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0);
|
|
@@ -894,51 +2090,58 @@ function autosizeTa(ta) {
|
|
|
894
2090
|
ta.style.height = `${Math.max(minH, Math.min(ta.scrollHeight, maxH))}px`;
|
|
895
2091
|
}
|
|
896
2092
|
function ensureIcons(composer) {
|
|
897
|
-
const sendBtn = composer.querySelector("[data-ai-send]");
|
|
2093
|
+
const sendBtn = composer.querySelector("[data-icen-ai-send]");
|
|
898
2094
|
if (sendBtn && !sendBtn.hasChildNodes()) {
|
|
899
2095
|
const sendWrap = document.createElement("span");
|
|
900
|
-
sendWrap.className = "ai-composer-send-icon";
|
|
901
|
-
sendWrap.dataset.
|
|
2096
|
+
sendWrap.className = "icen-ai-composer-send-icon";
|
|
2097
|
+
sendWrap.dataset.icenAiSendIcon = "send";
|
|
902
2098
|
const stopWrap = document.createElement("span");
|
|
903
|
-
stopWrap.className = "ai-composer-send-icon";
|
|
904
|
-
stopWrap.dataset.
|
|
2099
|
+
stopWrap.className = "icen-ai-composer-send-icon";
|
|
2100
|
+
stopWrap.dataset.icenAiSendIcon = "stop";
|
|
905
2101
|
const sendSvg = svgIcon(SEND_ICON);
|
|
906
2102
|
const stopSvg = svgIcon(STOP_ICON);
|
|
907
2103
|
if (sendSvg) sendWrap.appendChild(sendSvg);
|
|
908
2104
|
if (stopSvg) stopWrap.appendChild(stopSvg);
|
|
909
2105
|
sendBtn.append(sendWrap, stopWrap);
|
|
910
2106
|
}
|
|
911
|
-
const attachBtn = composer.querySelector("[data-ai-attach]");
|
|
2107
|
+
const attachBtn = composer.querySelector("[data-icen-ai-attach]");
|
|
912
2108
|
if (attachBtn && !attachBtn.hasChildNodes()) {
|
|
913
2109
|
const icon = svgIcon(ATTACH_ICON);
|
|
914
2110
|
if (icon) attachBtn.appendChild(icon);
|
|
915
2111
|
}
|
|
916
|
-
const sendIcon = sendBtn?.querySelector('[data-ai-send-icon="send"]') ?? null;
|
|
917
|
-
const stopIcon = sendBtn?.querySelector('[data-ai-send-icon="stop"]') ?? null;
|
|
2112
|
+
const sendIcon = sendBtn?.querySelector('[data-icen-ai-send-icon="send"]') ?? null;
|
|
2113
|
+
const stopIcon = sendBtn?.querySelector('[data-icen-ai-send-icon="stop"]') ?? null;
|
|
918
2114
|
return { sendBtn, sendIcon, stopIcon };
|
|
919
2115
|
}
|
|
920
|
-
function makeChip(text, removable, ariaLabel) {
|
|
2116
|
+
function makeChip(text, removable, ariaLabel, icon) {
|
|
921
2117
|
const chip = document.createElement("span");
|
|
922
|
-
chip.className = "ai-composer-chip";
|
|
2118
|
+
chip.className = "icen-ai-composer-chip";
|
|
2119
|
+
if (icon) {
|
|
2120
|
+
const mark = document.createElement("span");
|
|
2121
|
+
mark.className = "icen-ai-composer-chip-icon";
|
|
2122
|
+
const svg = createIcon(icon);
|
|
2123
|
+
if (svg) mark.append(svg);
|
|
2124
|
+
chip.append(mark);
|
|
2125
|
+
}
|
|
923
2126
|
const label = document.createElement("span");
|
|
924
|
-
label.className = "ai-composer-chip-text";
|
|
2127
|
+
label.className = "icen-ai-composer-chip-text";
|
|
925
2128
|
label.textContent = text;
|
|
926
2129
|
chip.appendChild(label);
|
|
927
2130
|
if (removable) {
|
|
928
2131
|
const remove = document.createElement("button");
|
|
929
2132
|
remove.type = "button";
|
|
930
|
-
remove.className = "ai-composer-chip-remove";
|
|
2133
|
+
remove.className = "icen-ai-composer-chip-remove";
|
|
931
2134
|
remove.setAttribute("aria-label", ariaLabel);
|
|
932
|
-
remove.
|
|
2135
|
+
remove.replaceChildren(createIcon("close"));
|
|
933
2136
|
chip.appendChild(remove);
|
|
934
2137
|
}
|
|
935
2138
|
return chip;
|
|
936
2139
|
}
|
|
937
2140
|
function renderQueueChips(composer) {
|
|
938
|
-
const queueEl = composer.querySelector(".ai-composer-queue");
|
|
2141
|
+
const queueEl = composer.querySelector(".icen-ai-composer-queue");
|
|
939
2142
|
if (!queueEl) return;
|
|
940
2143
|
const queue = QUEUES.get(composer) ?? [];
|
|
941
|
-
queueEl.replaceChildren(...queue.map((
|
|
2144
|
+
queueEl.replaceChildren(...queue.map((draft, i) => makeChip(draft.text || [...draft.files?.map((f) => f.name) ?? [], ...draft.refs?.map((r) => r.label) ?? []].join(" \xB7 "), true, t("aiComposer.removeQueued", { p0: i + 1 }), "layers")));
|
|
942
2145
|
queueEl.hidden = queue.length === 0;
|
|
943
2146
|
}
|
|
944
2147
|
function setComposerRunning(el, running) {
|
|
@@ -951,24 +2154,24 @@ function setComposerRunning(el, running) {
|
|
|
951
2154
|
} else {
|
|
952
2155
|
composer.removeAttribute("aria-busy");
|
|
953
2156
|
}
|
|
954
|
-
const sendBtn = composer.querySelector("[data-ai-send]");
|
|
2157
|
+
const sendBtn = composer.querySelector("[data-icen-ai-send]");
|
|
955
2158
|
if (!sendBtn) return;
|
|
956
2159
|
sendBtn.classList.toggle("is-stop", running);
|
|
957
|
-
sendBtn.setAttribute("aria-label", running ? "
|
|
958
|
-
const sendIcon = sendBtn.querySelector('[data-ai-send-icon="send"]');
|
|
959
|
-
const stopIcon = sendBtn.querySelector('[data-ai-send-icon="stop"]');
|
|
2160
|
+
sendBtn.setAttribute("aria-label", running ? t("aiComposer.stop") : t("aiComposer.send"));
|
|
2161
|
+
const sendIcon = sendBtn.querySelector('[data-icen-ai-send-icon="send"]');
|
|
2162
|
+
const stopIcon = sendBtn.querySelector('[data-icen-ai-send-icon="stop"]');
|
|
960
2163
|
if (sendIcon) sendIcon.hidden = running;
|
|
961
2164
|
if (stopIcon) stopIcon.hidden = !running;
|
|
962
2165
|
}
|
|
963
2166
|
function providerMark(provider, badgeClass) {
|
|
964
2167
|
const slot = document.createElement("span");
|
|
965
2168
|
slot.className = badgeClass;
|
|
966
|
-
const
|
|
967
|
-
if (
|
|
968
|
-
slot.appendChild(
|
|
2169
|
+
const svg = provider.icon ? svgIcon(provider.icon) : null;
|
|
2170
|
+
if (svg) {
|
|
2171
|
+
slot.appendChild(svg);
|
|
969
2172
|
} else {
|
|
970
2173
|
const badge = document.createElement("span");
|
|
971
|
-
badge.className = "ai-composer-model-badge";
|
|
2174
|
+
badge.className = "icen-ai-composer-model-badge";
|
|
972
2175
|
badge.textContent = (provider.label.trim()[0] ?? "?").toUpperCase();
|
|
973
2176
|
slot.appendChild(badge);
|
|
974
2177
|
}
|
|
@@ -977,8 +2180,8 @@ function providerMark(provider, badgeClass) {
|
|
|
977
2180
|
function buildModelButton(composer) {
|
|
978
2181
|
const btn = document.createElement("button");
|
|
979
2182
|
btn.type = "button";
|
|
980
|
-
btn.className = "ai-composer-model";
|
|
981
|
-
btn.setAttribute("data-ai-model-open", "");
|
|
2183
|
+
btn.className = "icen-ai-composer-model";
|
|
2184
|
+
btn.setAttribute("data-icen-ai-model-open", "");
|
|
982
2185
|
btn.setAttribute("aria-haspopup", "listbox");
|
|
983
2186
|
btn.setAttribute("aria-expanded", "false");
|
|
984
2187
|
btn.addEventListener("click", () => {
|
|
@@ -989,66 +2192,59 @@ function buildModelButton(composer) {
|
|
|
989
2192
|
}
|
|
990
2193
|
function updateModelButton(composer) {
|
|
991
2194
|
const cfg = MODELS.get(composer);
|
|
992
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
2195
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
993
2196
|
if (!cfg || !btn) return;
|
|
994
2197
|
const provider = cfg.providers.find((p) => p.id === cfg.current.provider) ?? cfg.providers[0];
|
|
995
2198
|
if (!provider) return;
|
|
996
2199
|
const model = provider.models.find((m) => m.id === cfg.current.model) ?? provider.models[0];
|
|
997
2200
|
if (!model) return;
|
|
998
|
-
const iconSlot = btn.querySelector(".ai-composer-model-icon") ?? (() => {
|
|
2201
|
+
const iconSlot = btn.querySelector(".icen-ai-composer-model-icon") ?? (() => {
|
|
999
2202
|
const slot = document.createElement("span");
|
|
1000
|
-
slot.className = "ai-composer-model-icon";
|
|
2203
|
+
slot.className = "icen-ai-composer-model-icon";
|
|
1001
2204
|
btn.prepend(slot);
|
|
1002
2205
|
return slot;
|
|
1003
2206
|
})();
|
|
1004
|
-
iconSlot.replaceChildren(providerMark(provider, "ai-composer-model-provider-icon"));
|
|
1005
|
-
let name = btn.querySelector(".ai-composer-model-name");
|
|
2207
|
+
iconSlot.replaceChildren(providerMark(provider, "icen-ai-composer-model-provider-icon"));
|
|
2208
|
+
let name = btn.querySelector(".icen-ai-composer-model-name");
|
|
1006
2209
|
if (!name) {
|
|
1007
2210
|
name = document.createElement("span");
|
|
1008
|
-
name.className = "ai-composer-model-name";
|
|
1009
|
-
btn.insertBefore(name, btn.querySelector(".ai-composer-model-chevron"));
|
|
2211
|
+
name.className = "icen-ai-composer-model-name";
|
|
2212
|
+
btn.insertBefore(name, btn.querySelector(".icen-ai-composer-model-chevron"));
|
|
1010
2213
|
}
|
|
1011
2214
|
name.textContent = model.label;
|
|
1012
|
-
btn.setAttribute("aria-label",
|
|
1013
|
-
|
|
1014
|
-
const chev = svgIcon(ICON_CHEVRON);
|
|
1015
|
-
if (chev) {
|
|
1016
|
-
const wrap = document.createElement("span");
|
|
1017
|
-
wrap.className = "ai-composer-model-chevron";
|
|
1018
|
-
wrap.appendChild(chev);
|
|
1019
|
-
btn.appendChild(wrap);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
2215
|
+
btn.setAttribute("aria-label", t("aiComposer.modelAria", { p0: model.label, p1: provider.label }));
|
|
2216
|
+
btn.querySelector(".icen-ai-composer-model-chevron")?.remove();
|
|
1022
2217
|
}
|
|
1023
2218
|
function syncToolbar(composer) {
|
|
1024
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
2219
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
1025
2220
|
if (!box || !getTextarea(composer)) return;
|
|
1026
2221
|
const modelsCfg = MODELS.get(composer);
|
|
1027
2222
|
const usageCfg = USAGE.get(composer);
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
let
|
|
2223
|
+
const hasLibrary = !!(COMMANDS.get(composer)?.length || REF_SOURCES.get(composer)?.length);
|
|
2224
|
+
if (!modelsCfg && !usageCfg && !hasLibrary && !composer.querySelector(".icen-ai-composer-toolbar")) return;
|
|
2225
|
+
let bar = composer.querySelector(".icen-ai-composer-toolbar");
|
|
2226
|
+
let modelBtn = composer.querySelector("[data-icen-ai-model-open]");
|
|
1031
2227
|
if (modelsCfg && !modelBtn) {
|
|
1032
2228
|
modelBtn = buildModelButton(composer);
|
|
1033
|
-
modelBtn.dataset.
|
|
2229
|
+
modelBtn.dataset.icenAiModelOpen = "auto";
|
|
1034
2230
|
updateModelButton(composer);
|
|
1035
2231
|
}
|
|
1036
|
-
if (!modelsCfg && modelBtn?.dataset.
|
|
2232
|
+
if (!modelsCfg && modelBtn?.dataset.icenAiModelOpen === "auto") {
|
|
1037
2233
|
modelBtn.remove();
|
|
1038
2234
|
modelBtn = null;
|
|
1039
2235
|
}
|
|
1040
|
-
let usageMount = composer.querySelector(".ai-composer-usage");
|
|
2236
|
+
let usageMount = composer.querySelector(".icen-ai-composer-usage");
|
|
1041
2237
|
if (usageCfg && !usageMount) {
|
|
1042
2238
|
usageMount = document.createElement("span");
|
|
1043
|
-
usageMount.className = "ai-composer-usage";
|
|
1044
|
-
usageMount.dataset.
|
|
2239
|
+
usageMount.className = "icen-ai-composer-usage";
|
|
2240
|
+
usageMount.dataset.icenAiUsage = "auto";
|
|
1045
2241
|
}
|
|
1046
|
-
if (!usageCfg && usageMount?.dataset.
|
|
2242
|
+
if (!usageCfg && usageMount?.dataset.icenAiUsage === "auto") {
|
|
1047
2243
|
usageMount.remove();
|
|
1048
2244
|
usageMount = null;
|
|
1049
2245
|
}
|
|
1050
|
-
const attach = composer.querySelector("[data-ai-attach]");
|
|
1051
|
-
const send = composer.querySelector("[data-ai-send]");
|
|
2246
|
+
const attach = composer.querySelector("[data-icen-ai-attach]");
|
|
2247
|
+
const send = composer.querySelector("[data-icen-ai-send]");
|
|
1052
2248
|
if (bar) {
|
|
1053
2249
|
if (modelBtn && modelBtn.parentElement !== bar) bar.insertBefore(modelBtn, bar.firstChild);
|
|
1054
2250
|
if (usageMount && usageMount.parentElement !== bar) {
|
|
@@ -1056,24 +2252,36 @@ function syncToolbar(composer) {
|
|
|
1056
2252
|
}
|
|
1057
2253
|
} else {
|
|
1058
2254
|
bar = document.createElement("div");
|
|
1059
|
-
bar.className = "ai-composer-toolbar";
|
|
2255
|
+
bar.className = "icen-ai-composer-toolbar";
|
|
1060
2256
|
bar.appendChild(modelBtn ?? document.createComment("model"));
|
|
1061
2257
|
const spacer = document.createElement("span");
|
|
1062
|
-
spacer.className = "ai-composer-spacer";
|
|
2258
|
+
spacer.className = "icen-ai-composer-spacer";
|
|
1063
2259
|
bar.appendChild(spacer);
|
|
1064
2260
|
if (usageMount) bar.appendChild(usageMount);
|
|
1065
2261
|
if (attach) bar.appendChild(attach);
|
|
1066
2262
|
if (send) bar.appendChild(send);
|
|
1067
2263
|
box.appendChild(bar);
|
|
1068
2264
|
}
|
|
1069
|
-
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1072
|
-
|
|
2265
|
+
let library = composer.querySelector("[data-icen-ai-library]");
|
|
2266
|
+
if (hasLibrary && !library) {
|
|
2267
|
+
library = document.createElement("button");
|
|
2268
|
+
library.type = "button";
|
|
2269
|
+
library.className = "icen-ai-composer-btn icen-ai-composer-library";
|
|
2270
|
+
library.dataset.icenAiLibrary = "auto";
|
|
2271
|
+
library.setAttribute("aria-label", t("aiComposer.library"));
|
|
2272
|
+
library.setAttribute("aria-haspopup", "dialog");
|
|
2273
|
+
library.setAttribute("aria-expanded", "false");
|
|
2274
|
+
library.append(createIcon("plus"));
|
|
2275
|
+
library.addEventListener("click", () => {
|
|
2276
|
+
if (POPUP.get(composer)?.mode === "library") closePopup(composer);
|
|
2277
|
+
else openComposerLibrary(composer);
|
|
2278
|
+
});
|
|
2279
|
+
bar.prepend(library);
|
|
2280
|
+
} else if (!hasLibrary && library?.dataset.icenAiLibrary === "auto") library.remove();
|
|
1073
2281
|
}
|
|
1074
2282
|
function refreshUsageRing(composer) {
|
|
1075
2283
|
const cfg = USAGE.get(composer);
|
|
1076
|
-
const mount = composer.querySelector(".ai-composer-usage");
|
|
2284
|
+
const mount = composer.querySelector(".icen-ai-composer-usage");
|
|
1077
2285
|
if (!cfg || !mount) return;
|
|
1078
2286
|
const explicit = typeof cfg.opts.total === "number" && cfg.opts.total > 0;
|
|
1079
2287
|
renderAiUsageRing(mount, cfg.usage, {
|
|
@@ -1081,18 +2289,21 @@ function refreshUsageRing(composer) {
|
|
|
1081
2289
|
total: explicit ? cfg.opts.total : MODEL_CTX.get(composer)
|
|
1082
2290
|
});
|
|
1083
2291
|
}
|
|
1084
|
-
var visibleOptions = (s) => s.options.filter((o) => !o.hidden);
|
|
2292
|
+
var visibleOptions = (s) => s.options.filter((o) => !o.hidden && o.getAttribute("aria-disabled") !== "true");
|
|
2293
|
+
var popupId = 0;
|
|
1085
2294
|
function setPopupFocus(s, idx) {
|
|
1086
2295
|
const vis = visibleOptions(s);
|
|
1087
2296
|
s.options.forEach((o) => o.classList.remove("is-focused"));
|
|
1088
2297
|
if (vis.length === 0) {
|
|
1089
2298
|
s.focused = -1;
|
|
2299
|
+
s.control?.removeAttribute("aria-activedescendant");
|
|
1090
2300
|
return;
|
|
1091
2301
|
}
|
|
1092
2302
|
s.focused = Math.max(0, Math.min(idx, vis.length - 1));
|
|
1093
2303
|
const cur = vis[s.focused];
|
|
1094
2304
|
cur.classList.add("is-focused");
|
|
1095
|
-
|
|
2305
|
+
s.control?.setAttribute("aria-activedescendant", cur.id);
|
|
2306
|
+
revealPopoverItem(cur, s.panel.querySelector(".icen-ai-composer-popup-list") ?? s.panel);
|
|
1096
2307
|
}
|
|
1097
2308
|
function movePopupFocus(s, delta) {
|
|
1098
2309
|
const vis = visibleOptions(s);
|
|
@@ -1101,15 +2312,25 @@ function movePopupFocus(s, delta) {
|
|
|
1101
2312
|
}
|
|
1102
2313
|
function settlePopup(s) {
|
|
1103
2314
|
for (const g of s.groups) {
|
|
1104
|
-
g.hidden = !Array.from(g.querySelectorAll(".ai-composer-popup-option")).some((o) => !o.hidden);
|
|
2315
|
+
g.hidden = !Array.from(g.querySelectorAll(".icen-ai-composer-popup-option")).some((o) => !o.hidden);
|
|
1105
2316
|
}
|
|
1106
|
-
s.emptyEl.hidden =
|
|
2317
|
+
s.emptyEl.hidden = s.options.some((o) => !o.hidden);
|
|
1107
2318
|
setPopupFocus(s, 0);
|
|
1108
2319
|
}
|
|
1109
2320
|
function filterPopupOptions(s, q) {
|
|
1110
2321
|
const needle = q.trim().toLowerCase();
|
|
1111
2322
|
for (const opt of s.options) {
|
|
1112
|
-
opt.hidden = needle !== "" && !(opt.dataset.hay ?? "").includes(needle);
|
|
2323
|
+
opt.hidden = !!s.category && s.category !== "all" && opt.dataset.category !== s.category || needle !== "" && !(opt.dataset.hay ?? "").includes(needle);
|
|
2324
|
+
for (const label of opt.querySelectorAll("[data-icen-search-text]")) {
|
|
2325
|
+
const text = label.dataset.icenSearchText ?? "";
|
|
2326
|
+
const at = needle ? text.toLowerCase().indexOf(needle) : -1;
|
|
2327
|
+
if (at < 0) label.textContent = text;
|
|
2328
|
+
else {
|
|
2329
|
+
const mark = document.createElement("mark");
|
|
2330
|
+
mark.textContent = text.slice(at, at + needle.length);
|
|
2331
|
+
label.replaceChildren(document.createTextNode(text.slice(0, at)), mark, document.createTextNode(text.slice(at + needle.length)));
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
1113
2334
|
}
|
|
1114
2335
|
settlePopup(s);
|
|
1115
2336
|
}
|
|
@@ -1126,6 +2347,9 @@ function popupKeydown(composer, s, e) {
|
|
|
1126
2347
|
return;
|
|
1127
2348
|
case "Enter":
|
|
1128
2349
|
case "Tab": {
|
|
2350
|
+
if (e.key === "Tab" && (s.mode === "library" || s.mode === "model")) {
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
1129
2353
|
e.preventDefault();
|
|
1130
2354
|
const vis = visibleOptions(s);
|
|
1131
2355
|
const opt = vis[s.focused] ?? vis[0];
|
|
@@ -1133,10 +2357,18 @@ function popupKeydown(composer, s, e) {
|
|
|
1133
2357
|
s.pick(opt);
|
|
1134
2358
|
return;
|
|
1135
2359
|
}
|
|
2360
|
+
if (s.mode === "library" || s.mode === "model") return;
|
|
1136
2361
|
closePopup(composer, false);
|
|
1137
2362
|
if (e.key === "Enter") SUBMITS.get(composer)?.();
|
|
1138
2363
|
return;
|
|
1139
2364
|
}
|
|
2365
|
+
case "Home":
|
|
2366
|
+
case "End":
|
|
2367
|
+
if (e.altKey || e.ctrlKey || e.metaKey) {
|
|
2368
|
+
e.preventDefault();
|
|
2369
|
+
setPopupFocus(s, e.key === "Home" ? 0 : visibleOptions(s).length - 1);
|
|
2370
|
+
}
|
|
2371
|
+
return;
|
|
1140
2372
|
case "Escape":
|
|
1141
2373
|
e.preventDefault();
|
|
1142
2374
|
closePopup(composer);
|
|
@@ -1146,14 +2378,19 @@ function popupKeydown(composer, s, e) {
|
|
|
1146
2378
|
function closePopup(composer, restoreFocus = true) {
|
|
1147
2379
|
const s = POPUP.get(composer);
|
|
1148
2380
|
if (!s) return;
|
|
2381
|
+
s.restoreFocus = restoreFocus;
|
|
1149
2382
|
POPUP.delete(composer);
|
|
1150
2383
|
if (s.searchInput && s.keydownHandler) {
|
|
1151
2384
|
s.searchInput.removeEventListener("keydown", s.keydownHandler);
|
|
1152
2385
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
2386
|
+
s.control?.removeAttribute("aria-activedescendant");
|
|
2387
|
+
s.control?.removeAttribute("aria-controls");
|
|
2388
|
+
if (s.mode === "library") {
|
|
2389
|
+
composer.querySelector("[data-icen-ai-library]")?.setAttribute("aria-expanded", "false");
|
|
2390
|
+
} else if (s.mode === "model") {
|
|
2391
|
+
composer.querySelector("[data-icen-ai-model-open]")?.setAttribute("aria-expanded", "false");
|
|
1155
2392
|
} else {
|
|
1156
|
-
getTextarea(composer)?.
|
|
2393
|
+
getTextarea(composer)?.removeAttribute("aria-expanded");
|
|
1157
2394
|
}
|
|
1158
2395
|
closePopover(s.panel);
|
|
1159
2396
|
if (restoreFocus && s.returnFocus && s.returnFocus.isConnected) s.returnFocus.focus();
|
|
@@ -1165,7 +2402,9 @@ function resolvePopupSizing(composer, defaults) {
|
|
|
1165
2402
|
function mountPopup(composer, init) {
|
|
1166
2403
|
closePopup(composer, false);
|
|
1167
2404
|
const panel = document.createElement("div");
|
|
1168
|
-
panel.className = "ai-composer-popup";
|
|
2405
|
+
panel.className = "icen-ai-composer-popup";
|
|
2406
|
+
panel.dataset.icenMaterial = "floating";
|
|
2407
|
+
panel.dataset.icenMode = init.mode;
|
|
1169
2408
|
panel.hidden = true;
|
|
1170
2409
|
const session = {
|
|
1171
2410
|
mode: init.mode,
|
|
@@ -1181,49 +2420,245 @@ function mountPopup(composer, init) {
|
|
|
1181
2420
|
pick: init.pick
|
|
1182
2421
|
};
|
|
1183
2422
|
init.build(session);
|
|
2423
|
+
if (session.searchInput) session.searchField = enhanceSearchField(session.searchInput);
|
|
2424
|
+
const list = panel.querySelector('[role="listbox"]');
|
|
2425
|
+
if (list) {
|
|
2426
|
+
list.id = `icen-composer-list-${++popupId}`;
|
|
2427
|
+
session.options.forEach((o, i) => {
|
|
2428
|
+
o.id = `${list.id}-${i}`;
|
|
2429
|
+
o.tabIndex = -1;
|
|
2430
|
+
});
|
|
2431
|
+
session.control = session.searchInput ?? getTextarea(composer);
|
|
2432
|
+
session.control?.setAttribute("aria-controls", list.id);
|
|
2433
|
+
session.control?.setAttribute("aria-haspopup", "listbox");
|
|
2434
|
+
}
|
|
1184
2435
|
openPopover(panel, {
|
|
1185
2436
|
anchor: init.anchor,
|
|
1186
2437
|
side: "top",
|
|
1187
2438
|
align: "start",
|
|
1188
2439
|
offset: 8,
|
|
1189
2440
|
sizing: resolvePopupSizing(composer, init.sizing),
|
|
2441
|
+
restoreFocus: false,
|
|
1190
2442
|
onClose: () => {
|
|
1191
2443
|
if (POPUP.get(composer) === session) POPUP.delete(composer);
|
|
2444
|
+
session.control?.removeAttribute("aria-activedescendant");
|
|
2445
|
+
session.control?.removeAttribute("aria-controls");
|
|
2446
|
+
composer.querySelector("[data-icen-ai-library]")?.setAttribute("aria-expanded", "false");
|
|
2447
|
+
composer.querySelector("[data-icen-ai-model-open]")?.setAttribute("aria-expanded", "false");
|
|
2448
|
+
getTextarea(composer)?.removeAttribute("aria-expanded");
|
|
2449
|
+
if (session.restoreFocus !== false && panel.contains(document.activeElement) && session.returnFocus?.isConnected) {
|
|
2450
|
+
session.returnFocus.focus({ preventScroll: true });
|
|
2451
|
+
}
|
|
2452
|
+
session.searchField?.destroy();
|
|
1192
2453
|
panel.remove();
|
|
1193
2454
|
}
|
|
1194
2455
|
});
|
|
1195
2456
|
POPUP.set(composer, session);
|
|
1196
2457
|
panel.addEventListener("click", (e) => {
|
|
1197
|
-
const
|
|
1198
|
-
if (!(
|
|
1199
|
-
const opt =
|
|
1200
|
-
if (opt && panel.contains(opt) && !opt.hidden) session.pick(opt);
|
|
2458
|
+
const t2 = e.target;
|
|
2459
|
+
if (!(t2 instanceof Element)) return;
|
|
2460
|
+
const opt = t2.closest(".icen-ai-composer-popup-option");
|
|
2461
|
+
if (opt && panel.contains(opt) && !opt.hidden && opt.getAttribute("aria-disabled") !== "true") session.pick(opt);
|
|
1201
2462
|
});
|
|
1202
2463
|
panel.addEventListener("mouseover", (e) => {
|
|
1203
|
-
const
|
|
1204
|
-
if (!(
|
|
1205
|
-
const opt =
|
|
1206
|
-
if (!opt || opt.hidden) return;
|
|
2464
|
+
const t2 = e.target;
|
|
2465
|
+
if (!(t2 instanceof Element)) return;
|
|
2466
|
+
const opt = t2.closest(".icen-ai-composer-popup-option");
|
|
2467
|
+
if (!opt || opt.hidden || opt.getAttribute("aria-disabled") === "true") return;
|
|
1207
2468
|
const idx = visibleOptions(session).indexOf(opt);
|
|
1208
2469
|
if (idx >= 0) setPopupFocus(session, idx);
|
|
1209
2470
|
});
|
|
2471
|
+
panel.addEventListener("focusout", (e) => {
|
|
2472
|
+
const next = e.relatedTarget;
|
|
2473
|
+
if (next instanceof Node && !panel.contains(next) && next !== session.returnFocus) closePopup(composer, false);
|
|
2474
|
+
});
|
|
2475
|
+
panel.addEventListener("keydown", (e) => {
|
|
2476
|
+
if (e.key === "Escape" && !e.isComposing) {
|
|
2477
|
+
e.preventDefault();
|
|
2478
|
+
closePopup(composer);
|
|
2479
|
+
} else if (e.target instanceof Element && e.target.closest(".icen-ai-composer-popup-option") && ["ArrowUp", "ArrowDown"].includes(e.key)) {
|
|
2480
|
+
popupKeydown(composer, session, e);
|
|
2481
|
+
session.searchInput?.focus({ preventScroll: true });
|
|
2482
|
+
}
|
|
2483
|
+
});
|
|
1210
2484
|
return session;
|
|
1211
2485
|
}
|
|
1212
2486
|
function appendPopupEmpty(s, text) {
|
|
1213
|
-
s.emptyEl.className = "ai-composer-popup-empty";
|
|
2487
|
+
s.emptyEl.className = "icen-ai-composer-popup-empty";
|
|
1214
2488
|
s.emptyEl.textContent = text;
|
|
1215
2489
|
s.emptyEl.hidden = true;
|
|
1216
2490
|
s.panel.appendChild(s.emptyEl);
|
|
1217
2491
|
}
|
|
1218
2492
|
function popupSizingFor(box) {
|
|
1219
2493
|
const w = box.getBoundingClientRect().width;
|
|
1220
|
-
return {
|
|
2494
|
+
return { width: Math.min(Math.max(w, 280), 440), maxWidth: 440, maxHeight: 400 };
|
|
2495
|
+
}
|
|
2496
|
+
function searchLeaf(text, className) {
|
|
2497
|
+
const el = document.createElement("span");
|
|
2498
|
+
el.className = className;
|
|
2499
|
+
el.textContent = text;
|
|
2500
|
+
el.dataset.icenSearchText = text;
|
|
2501
|
+
return el;
|
|
2502
|
+
}
|
|
2503
|
+
function resourceIcon(source) {
|
|
2504
|
+
const mark = document.createElement("span");
|
|
2505
|
+
mark.className = "icen-ai-composer-popup-option-icon";
|
|
2506
|
+
const svg = (source.icon ? createIcon(source.icon) : null) ?? svgIcon(getRefKindDef(source.kind).icon);
|
|
2507
|
+
if (svg) mark.append(svg);
|
|
2508
|
+
return mark;
|
|
2509
|
+
}
|
|
2510
|
+
function resourceOption(source) {
|
|
2511
|
+
const opt = document.createElement("button");
|
|
2512
|
+
opt.type = "button";
|
|
2513
|
+
opt.className = "icen-ai-composer-popup-option";
|
|
2514
|
+
opt.setAttribute("role", "option");
|
|
2515
|
+
opt.dataset.refId = source.id;
|
|
2516
|
+
opt.dataset.refKind = source.kind;
|
|
2517
|
+
opt.dataset.category = source.kind;
|
|
2518
|
+
opt.dataset.hay = [source.label, source.description, source.sub, getRefKindDef(source.kind).label, ...source.keywords ?? []].join(" ").toLowerCase();
|
|
2519
|
+
opt.setAttribute("aria-selected", "false");
|
|
2520
|
+
if (source.disabled) opt.setAttribute("aria-disabled", "true");
|
|
2521
|
+
const body = document.createElement("span");
|
|
2522
|
+
body.className = "icen-ai-composer-popup-option-copy";
|
|
2523
|
+
body.append(searchLeaf(source.label, "icen-ai-composer-popup-option-label"));
|
|
2524
|
+
if (source.description || source.sub) body.append(searchLeaf(source.description ?? source.sub ?? "", "icen-ai-composer-popup-option-sub"));
|
|
2525
|
+
opt.append(resourceIcon(source), body);
|
|
2526
|
+
return opt;
|
|
2527
|
+
}
|
|
2528
|
+
function commandOption(c) {
|
|
2529
|
+
const opt = document.createElement("button");
|
|
2530
|
+
opt.type = "button";
|
|
2531
|
+
opt.className = "icen-ai-composer-popup-option icen-ai-composer-popup-cmd";
|
|
2532
|
+
opt.setAttribute("role", "option");
|
|
2533
|
+
opt.setAttribute("aria-selected", "false");
|
|
2534
|
+
if (c.disabled) opt.setAttribute("aria-disabled", "true");
|
|
2535
|
+
opt.dataset.name = c.name;
|
|
2536
|
+
opt.dataset.category = "command";
|
|
2537
|
+
opt.dataset.hay = [c.name, c.label, c.description, c.group, ...c.keywords ?? []].join(" ").toLowerCase();
|
|
2538
|
+
const mark = document.createElement("span");
|
|
2539
|
+
mark.className = "icen-ai-composer-popup-option-icon";
|
|
2540
|
+
mark.append(createIcon(c.icon ?? "terminal") ?? createIcon("terminal"));
|
|
2541
|
+
const body = document.createElement("span");
|
|
2542
|
+
body.className = "icen-ai-composer-popup-option-copy";
|
|
2543
|
+
const line = document.createElement("span");
|
|
2544
|
+
line.className = "icen-ai-composer-popup-cmd-line";
|
|
2545
|
+
line.append(searchLeaf(c.label ?? `/${c.name}`, "icen-ai-composer-popup-option-label"));
|
|
2546
|
+
if (c.label) line.append(searchLeaf(`/${c.name}`, "icen-ai-composer-popup-cmd-name"));
|
|
2547
|
+
if (c.argsHint) line.append(searchLeaf(c.argsHint, "icen-ai-composer-popup-cmd-args"));
|
|
2548
|
+
body.append(line);
|
|
2549
|
+
if (c.description) body.append(searchLeaf(c.description, "icen-ai-composer-popup-option-sub"));
|
|
2550
|
+
opt.append(mark, body);
|
|
2551
|
+
return opt;
|
|
2552
|
+
}
|
|
2553
|
+
function popupFoot(s, text) {
|
|
2554
|
+
const foot = document.createElement("div");
|
|
2555
|
+
foot.className = "icen-ai-composer-popup-foot";
|
|
2556
|
+
foot.textContent = text;
|
|
2557
|
+
s.panel.append(foot);
|
|
2558
|
+
}
|
|
2559
|
+
function openComposerLibrary(el, category = "all") {
|
|
2560
|
+
if (!isBrowser()) return;
|
|
2561
|
+
const composer = resolveComposer(el);
|
|
2562
|
+
if (!composer) return;
|
|
2563
|
+
const ta = getTextarea(composer);
|
|
2564
|
+
if (!ta || ta.disabled || ta.readOnly) return;
|
|
2565
|
+
const anchor = composer.querySelector("[data-icen-ai-library]") ?? ta;
|
|
2566
|
+
const sources = REF_SOURCES.get(composer) ?? [], commands = COMMANDS.get(composer) ?? [];
|
|
2567
|
+
if (!sources.length && !commands.length) return;
|
|
2568
|
+
const session = mountPopup(composer, {
|
|
2569
|
+
mode: "library",
|
|
2570
|
+
anchor: composer,
|
|
2571
|
+
sizing: popupSizingFor(composer),
|
|
2572
|
+
returnFocus: anchor,
|
|
2573
|
+
pick: (opt) => {
|
|
2574
|
+
if (opt.dataset.name) {
|
|
2575
|
+
const draft = ta.value.replace(/^\/\S*\s?/, "");
|
|
2576
|
+
ta.value = `/${opt.dataset.name} ${draft}`;
|
|
2577
|
+
autosizeTa(ta);
|
|
2578
|
+
closePopup(composer, false);
|
|
2579
|
+
ta.focus();
|
|
2580
|
+
ta.setSelectionRange(ta.value.length, ta.value.length);
|
|
2581
|
+
return;
|
|
2582
|
+
}
|
|
2583
|
+
const source = sources.find((r) => r.id === opt.dataset.refId && r.kind === opt.dataset.refKind);
|
|
2584
|
+
if (!source) return;
|
|
2585
|
+
const active = (ACTIVE_REFS.get(composer) ?? []).some((r) => r.id === source.id && r.kind === source.kind);
|
|
2586
|
+
if (active) removeActiveRef(composer, source);
|
|
2587
|
+
else addActiveRef(composer, source);
|
|
2588
|
+
opt.setAttribute("aria-selected", String(!active));
|
|
2589
|
+
},
|
|
2590
|
+
build: (s) => {
|
|
2591
|
+
s.panel.setAttribute("role", "dialog");
|
|
2592
|
+
s.panel.setAttribute("aria-label", t("aiComposer.library"));
|
|
2593
|
+
const search = document.createElement("div");
|
|
2594
|
+
search.className = "icen-ai-composer-popup-search";
|
|
2595
|
+
const input = document.createElement("input");
|
|
2596
|
+
input.type = "search";
|
|
2597
|
+
input.className = "icen-ai-composer-popup-search-input";
|
|
2598
|
+
input.placeholder = t("aiComposer.searchLibrary");
|
|
2599
|
+
input.setAttribute("aria-label", t("aiComposer.searchLibrary"));
|
|
2600
|
+
search.append(input);
|
|
2601
|
+
s.searchInput = input;
|
|
2602
|
+
s.panel.append(search);
|
|
2603
|
+
const categories = [{ id: "all", label: t("aiComposer.all") }, ...knownRefKinds(sources).filter((k) => sources.some((r) => r.kind === k)).map((k) => ({ id: k, label: getRefKindDef(k).label })), ...commands.length ? [{ id: "command", label: t("aiComposer.commands") }] : []];
|
|
2604
|
+
s.category = categories.some((c) => c.id === category) ? category : "all";
|
|
2605
|
+
const filters = document.createElement("div");
|
|
2606
|
+
filters.className = "icen-ai-composer-popup-filters";
|
|
2607
|
+
filters.setAttribute("role", "group");
|
|
2608
|
+
filters.setAttribute("aria-label", t("aiComposer.refs"));
|
|
2609
|
+
for (const c of categories) {
|
|
2610
|
+
const b = document.createElement("button");
|
|
2611
|
+
b.type = "button";
|
|
2612
|
+
b.textContent = c.label;
|
|
2613
|
+
b.setAttribute("aria-pressed", String(c.id === s.category));
|
|
2614
|
+
b.addEventListener("click", () => {
|
|
2615
|
+
s.category = c.id;
|
|
2616
|
+
for (const node of filters.querySelectorAll("button")) node.setAttribute("aria-pressed", String(node === b));
|
|
2617
|
+
filterPopupOptions(s, input.value);
|
|
2618
|
+
});
|
|
2619
|
+
filters.append(b);
|
|
2620
|
+
}
|
|
2621
|
+
s.panel.append(filters);
|
|
2622
|
+
const list = document.createElement("div");
|
|
2623
|
+
list.className = "icen-ai-composer-popup-list";
|
|
2624
|
+
list.setAttribute("role", "listbox");
|
|
2625
|
+
list.setAttribute("aria-label", t("aiComposer.library"));
|
|
2626
|
+
list.setAttribute("aria-multiselectable", "true");
|
|
2627
|
+
const addGroup = (title, options) => {
|
|
2628
|
+
const g = document.createElement("div");
|
|
2629
|
+
g.className = "icen-ai-composer-popup-group";
|
|
2630
|
+
g.setAttribute("role", "group");
|
|
2631
|
+
g.setAttribute("aria-label", title);
|
|
2632
|
+
g.append(searchLeaf(title, "icen-ai-composer-popup-group-label"), ...options);
|
|
2633
|
+
list.append(g);
|
|
2634
|
+
s.groups.push(g);
|
|
2635
|
+
s.options.push(...options);
|
|
2636
|
+
};
|
|
2637
|
+
for (const kind of knownRefKinds(sources)) {
|
|
2638
|
+
const options = sources.filter((r) => r.kind === kind).map((r) => {
|
|
2639
|
+
const opt = resourceOption(r);
|
|
2640
|
+
opt.setAttribute("aria-selected", String((ACTIVE_REFS.get(composer) ?? []).some((a) => a.id === r.id && a.kind === r.kind)));
|
|
2641
|
+
return opt;
|
|
2642
|
+
});
|
|
2643
|
+
if (options.length) addGroup(getRefKindDef(kind).label, options);
|
|
2644
|
+
}
|
|
2645
|
+
for (const group of new Set(commands.map((c) => c.group ?? t("aiComposer.commands")))) addGroup(group, commands.filter((c) => (c.group ?? t("aiComposer.commands")) === group).map(commandOption));
|
|
2646
|
+
s.panel.append(list);
|
|
2647
|
+
appendPopupEmpty(s, t("aiComposer.noLibraryMatch"));
|
|
2648
|
+
popupFoot(s, t("aiComposer.libraryHint"));
|
|
2649
|
+
input.addEventListener("input", () => filterPopupOptions(s, input.value));
|
|
2650
|
+
input.addEventListener("keydown", (e) => popupKeydown(composer, s, e));
|
|
2651
|
+
}
|
|
2652
|
+
});
|
|
2653
|
+
anchor.setAttribute("aria-expanded", "true");
|
|
2654
|
+
filterPopupOptions(session, "");
|
|
2655
|
+
session.searchInput?.focus({ preventScroll: true });
|
|
1221
2656
|
}
|
|
1222
2657
|
function openModelPopup(composer) {
|
|
1223
2658
|
const cfg = MODELS.get(composer);
|
|
1224
2659
|
if (!cfg) return;
|
|
1225
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
1226
|
-
const anchor = btn ?? composer.querySelector(".ai-composer-box") ?? composer;
|
|
2660
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
2661
|
+
const anchor = btn ?? composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1227
2662
|
const ta = getTextarea(composer);
|
|
1228
2663
|
const session = mountPopup(composer, {
|
|
1229
2664
|
mode: "model",
|
|
@@ -1233,7 +2668,7 @@ function openModelPopup(composer) {
|
|
|
1233
2668
|
pick: (opt) => {
|
|
1234
2669
|
const provider = opt.dataset.provider ?? "";
|
|
1235
2670
|
const model = opt.dataset.model ?? "";
|
|
1236
|
-
const label = opt.dataset.
|
|
2671
|
+
const label = opt.dataset.icenLabel ?? model;
|
|
1237
2672
|
const context = typeof opt.dataset.context === "string" ? Number(opt.dataset.context) : void 0;
|
|
1238
2673
|
MODELS.set(composer, { providers: cfg.providers, current: { provider, model } });
|
|
1239
2674
|
if (typeof context === "number" && Number.isFinite(context) && context > 0) {
|
|
@@ -1242,31 +2677,31 @@ function openModelPopup(composer) {
|
|
|
1242
2677
|
MODEL_CTX.delete(composer);
|
|
1243
2678
|
}
|
|
1244
2679
|
updateModelButton(composer);
|
|
1245
|
-
|
|
2680
|
+
emit2(composer, "icen:ai-model-change", { provider, model, label, context });
|
|
1246
2681
|
refreshUsageRing(composer);
|
|
1247
2682
|
closePopup(composer);
|
|
1248
2683
|
},
|
|
1249
2684
|
build: (s) => {
|
|
1250
2685
|
const search = document.createElement("div");
|
|
1251
|
-
search.className = "ai-composer-popup-search";
|
|
2686
|
+
search.className = "icen-ai-composer-popup-search";
|
|
1252
2687
|
const input = document.createElement("input");
|
|
1253
2688
|
input.type = "search";
|
|
1254
|
-
input.className = "ai-composer-popup-search-input";
|
|
1255
|
-
input.placeholder = "
|
|
1256
|
-
input.setAttribute("aria-label", "
|
|
2689
|
+
input.className = "icen-ai-composer-popup-search-input";
|
|
2690
|
+
input.placeholder = t("aiComposer.searchModels");
|
|
2691
|
+
input.setAttribute("aria-label", t("aiComposer.searchModels"));
|
|
1257
2692
|
search.appendChild(input);
|
|
1258
2693
|
s.panel.appendChild(search);
|
|
1259
2694
|
s.searchInput = input;
|
|
1260
2695
|
const list = document.createElement("div");
|
|
1261
|
-
list.className = "ai-composer-popup-list";
|
|
2696
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1262
2697
|
list.setAttribute("role", "listbox");
|
|
1263
|
-
list.setAttribute("aria-label", "
|
|
2698
|
+
list.setAttribute("aria-label", t("aiComposer.selectModel"));
|
|
1264
2699
|
for (const p of cfg.providers) {
|
|
1265
2700
|
const group = document.createElement("div");
|
|
1266
|
-
group.className = "ai-composer-popup-group";
|
|
2701
|
+
group.className = "icen-ai-composer-popup-group";
|
|
1267
2702
|
const glabel = document.createElement("div");
|
|
1268
|
-
glabel.className = "ai-composer-popup-group-label";
|
|
1269
|
-
glabel.appendChild(providerMark(p, "ai-composer-popup-group-icon"));
|
|
2703
|
+
glabel.className = "icen-ai-composer-popup-group-label";
|
|
2704
|
+
glabel.appendChild(providerMark(p, "icen-ai-composer-popup-group-icon"));
|
|
1270
2705
|
const gtext = document.createElement("span");
|
|
1271
2706
|
gtext.textContent = p.label;
|
|
1272
2707
|
glabel.appendChild(gtext);
|
|
@@ -1274,30 +2709,26 @@ function openModelPopup(composer) {
|
|
|
1274
2709
|
for (const m of p.models) {
|
|
1275
2710
|
const opt = document.createElement("button");
|
|
1276
2711
|
opt.type = "button";
|
|
1277
|
-
opt.className = "ai-composer-popup-option";
|
|
2712
|
+
opt.className = "icen-ai-composer-popup-option";
|
|
1278
2713
|
opt.setAttribute("role", "option");
|
|
1279
2714
|
opt.dataset.provider = p.id;
|
|
1280
2715
|
opt.dataset.providerLabel = p.label;
|
|
1281
2716
|
opt.dataset.model = m.id;
|
|
1282
|
-
opt.dataset.
|
|
2717
|
+
opt.dataset.icenLabel = m.label;
|
|
1283
2718
|
opt.dataset.hay = `${m.label} ${p.label}`.toLowerCase();
|
|
1284
2719
|
if (typeof m.context === "number") opt.dataset.context = String(m.context);
|
|
1285
2720
|
const selected = cfg.current.provider === p.id && cfg.current.model === m.id;
|
|
1286
2721
|
opt.setAttribute("aria-selected", String(selected));
|
|
1287
2722
|
const icon = document.createElement("span");
|
|
1288
|
-
icon.className = "ai-composer-popup-option-icon";
|
|
2723
|
+
icon.className = "icen-ai-composer-popup-option-icon";
|
|
1289
2724
|
icon.appendChild(providerMark(p, "ai-composer-popup-option-provider-icon"));
|
|
1290
2725
|
const label = document.createElement("span");
|
|
1291
|
-
label.className = "ai-composer-popup-option-label";
|
|
2726
|
+
label.className = "icen-ai-composer-popup-option-label";
|
|
1292
2727
|
label.textContent = m.label;
|
|
1293
2728
|
const meta = document.createElement("span");
|
|
1294
|
-
meta.className = "ai-composer-popup-option-meta";
|
|
2729
|
+
meta.className = "icen-ai-composer-popup-option-meta";
|
|
1295
2730
|
meta.textContent = typeof m.context === "number" ? formatTokens(m.context) : "";
|
|
1296
|
-
|
|
1297
|
-
check.className = "ai-composer-popup-option-check";
|
|
1298
|
-
const checkSvg = svgIcon(ICON_CHECK);
|
|
1299
|
-
if (checkSvg) check.appendChild(checkSvg);
|
|
1300
|
-
opt.append(icon, label, meta, check);
|
|
2731
|
+
opt.append(icon, label, meta);
|
|
1301
2732
|
group.appendChild(opt);
|
|
1302
2733
|
s.options.push(opt);
|
|
1303
2734
|
}
|
|
@@ -1305,9 +2736,9 @@ function openModelPopup(composer) {
|
|
|
1305
2736
|
s.groups.push(group);
|
|
1306
2737
|
}
|
|
1307
2738
|
s.panel.appendChild(list);
|
|
1308
|
-
appendPopupEmpty(s, "
|
|
2739
|
+
appendPopupEmpty(s, t("aiComposer.noModelMatch"));
|
|
1309
2740
|
const foot = document.createElement("div");
|
|
1310
|
-
foot.className = "ai-composer-popup-foot";
|
|
2741
|
+
foot.className = "icen-ai-composer-popup-foot";
|
|
1311
2742
|
const usageCfg = USAGE.get(composer);
|
|
1312
2743
|
if (usageCfg) {
|
|
1313
2744
|
const u = usageCfg.usage;
|
|
@@ -1319,7 +2750,7 @@ function openModelPopup(composer) {
|
|
|
1319
2750
|
const info = svgIcon(ICON_INFO);
|
|
1320
2751
|
if (info) foot.appendChild(info);
|
|
1321
2752
|
const footText = document.createElement("span");
|
|
1322
|
-
footText.textContent = "
|
|
2753
|
+
footText.textContent = t("aiComposer.cacheInvalidHint");
|
|
1323
2754
|
foot.appendChild(footText);
|
|
1324
2755
|
s.panel.appendChild(foot);
|
|
1325
2756
|
s.keydownHandler = (e) => popupKeydown(composer, s, e);
|
|
@@ -1332,10 +2763,21 @@ function openModelPopup(composer) {
|
|
|
1332
2763
|
btn?.setAttribute("aria-expanded", "true");
|
|
1333
2764
|
session.searchInput?.focus();
|
|
1334
2765
|
}
|
|
2766
|
+
function runComposerCommand(composer, name) {
|
|
2767
|
+
const command = COMMANDS.get(composer)?.find((c) => c.name === name && !c.disabled);
|
|
2768
|
+
const ta = getTextarea(composer);
|
|
2769
|
+
if (!command || !ta || ta.disabled || ta.readOnly) return false;
|
|
2770
|
+
const args = /^\/\S*\s+([\s\S]*)$/.exec(ta.value)?.[1] ?? "";
|
|
2771
|
+
ta.value = "";
|
|
2772
|
+
autosizeTa(ta);
|
|
2773
|
+
emit2(composer, "icen:ai-command", { name: command.name, args });
|
|
2774
|
+
closePopup(composer);
|
|
2775
|
+
return true;
|
|
2776
|
+
}
|
|
1335
2777
|
function openCommandPopup(composer, token) {
|
|
1336
2778
|
const commands = COMMANDS.get(composer);
|
|
1337
2779
|
if (!commands || commands.length === 0) return;
|
|
1338
|
-
const box = composer.querySelector(".ai-composer-box") ?? composer;
|
|
2780
|
+
const box = composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1339
2781
|
const ta = getTextarea(composer);
|
|
1340
2782
|
const session = mountPopup(composer, {
|
|
1341
2783
|
mode: "command",
|
|
@@ -1343,59 +2785,27 @@ function openCommandPopup(composer, token) {
|
|
|
1343
2785
|
sizing: popupSizingFor(box),
|
|
1344
2786
|
returnFocus: ta,
|
|
1345
2787
|
pick: (opt) => {
|
|
1346
|
-
|
|
1347
|
-
const m = /^\/\S*\s+([\s\S]*)$/.exec(ta?.value ?? "");
|
|
1348
|
-
const args = m ? m[1] : "";
|
|
1349
|
-
if (ta) {
|
|
1350
|
-
ta.value = "";
|
|
1351
|
-
autosizeTa(ta);
|
|
1352
|
-
}
|
|
1353
|
-
emit(composer, "icen:ai-command", { name, args });
|
|
1354
|
-
closePopup(composer);
|
|
2788
|
+
runComposerCommand(composer, opt.dataset.name ?? "");
|
|
1355
2789
|
},
|
|
1356
2790
|
build: (s) => {
|
|
1357
2791
|
const list = document.createElement("div");
|
|
1358
|
-
list.className = "ai-composer-popup-list";
|
|
2792
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1359
2793
|
list.setAttribute("role", "listbox");
|
|
1360
|
-
list.setAttribute("aria-label", "
|
|
2794
|
+
list.setAttribute("aria-label", t("aiComposer.commands"));
|
|
1361
2795
|
const group = document.createElement("div");
|
|
1362
|
-
group.className = "ai-composer-popup-group";
|
|
2796
|
+
group.className = "icen-ai-composer-popup-group";
|
|
1363
2797
|
for (const c of commands) {
|
|
1364
|
-
const opt =
|
|
1365
|
-
opt.type = "button";
|
|
1366
|
-
opt.className = "ai-composer-popup-option ai-composer-popup-cmd";
|
|
1367
|
-
opt.setAttribute("role", "option");
|
|
1368
|
-
opt.dataset.name = c.name;
|
|
1369
|
-
opt.dataset.hay = `${c.name} ${c.description ?? ""}`.toLowerCase();
|
|
1370
|
-
const line = document.createElement("span");
|
|
1371
|
-
line.className = "ai-composer-popup-cmd-line";
|
|
1372
|
-
const nameEl = document.createElement("span");
|
|
1373
|
-
nameEl.className = "ai-composer-popup-cmd-name";
|
|
1374
|
-
nameEl.textContent = `/${c.name}`;
|
|
1375
|
-
line.appendChild(nameEl);
|
|
1376
|
-
if (c.argsHint) {
|
|
1377
|
-
const argsEl = document.createElement("span");
|
|
1378
|
-
argsEl.className = "ai-composer-popup-cmd-args";
|
|
1379
|
-
argsEl.textContent = c.argsHint;
|
|
1380
|
-
line.appendChild(argsEl);
|
|
1381
|
-
}
|
|
1382
|
-
opt.appendChild(line);
|
|
1383
|
-
if (c.description) {
|
|
1384
|
-
opt.appendChild(Object.assign(document.createElement("span"), {
|
|
1385
|
-
className: "ai-composer-popup-cmd-desc",
|
|
1386
|
-
textContent: c.description
|
|
1387
|
-
}));
|
|
1388
|
-
}
|
|
2798
|
+
const opt = commandOption(c);
|
|
1389
2799
|
group.appendChild(opt);
|
|
1390
2800
|
s.options.push(opt);
|
|
1391
2801
|
}
|
|
1392
2802
|
list.appendChild(group);
|
|
1393
2803
|
s.groups.push(group);
|
|
1394
2804
|
s.panel.appendChild(list);
|
|
1395
|
-
appendPopupEmpty(s, "
|
|
2805
|
+
appendPopupEmpty(s, t("aiComposer.noCommandMatch"));
|
|
2806
|
+
popupFoot(s, t("aiComposer.commandHint"));
|
|
1396
2807
|
}
|
|
1397
2808
|
});
|
|
1398
|
-
ta?.setAttribute("aria-expanded", "true");
|
|
1399
2809
|
filterPopupOptions(session, token);
|
|
1400
2810
|
}
|
|
1401
2811
|
function commandToken(value) {
|
|
@@ -1414,7 +2824,7 @@ function updateCommandPopup(composer, s) {
|
|
|
1414
2824
|
function openRefPopup(composer, range, filter) {
|
|
1415
2825
|
const sources = REF_SOURCES.get(composer);
|
|
1416
2826
|
if (!sources || sources.length === 0) return;
|
|
1417
|
-
const box = composer.querySelector(".ai-composer-box") ?? composer;
|
|
2827
|
+
const box = composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1418
2828
|
const ta = getTextarea(composer);
|
|
1419
2829
|
const session = mountPopup(composer, {
|
|
1420
2830
|
mode: "ref",
|
|
@@ -1423,7 +2833,7 @@ function openRefPopup(composer, range, filter) {
|
|
|
1423
2833
|
returnFocus: ta,
|
|
1424
2834
|
refRange: range,
|
|
1425
2835
|
pick: (opt) => {
|
|
1426
|
-
const source = (REF_SOURCES.get(composer) ?? []).find((r2) => r2.id === opt.dataset.refId);
|
|
2836
|
+
const source = (REF_SOURCES.get(composer) ?? []).find((r2) => r2.id === opt.dataset.refId && r2.kind === opt.dataset.refKind);
|
|
1427
2837
|
const cur = POPUP.get(composer);
|
|
1428
2838
|
const r = cur?.refRange ?? (ta ? findRefToken(ta) : null);
|
|
1429
2839
|
if (source && ta && r) {
|
|
@@ -1439,41 +2849,23 @@ function openRefPopup(composer, range, filter) {
|
|
|
1439
2849
|
},
|
|
1440
2850
|
build: (s) => {
|
|
1441
2851
|
const list = document.createElement("div");
|
|
1442
|
-
list.className = "ai-composer-popup-list";
|
|
2852
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1443
2853
|
list.setAttribute("role", "listbox");
|
|
1444
|
-
list.setAttribute("aria-label", "
|
|
2854
|
+
list.setAttribute("aria-label", t("aiComposer.refs"));
|
|
1445
2855
|
for (const kind of knownRefKinds(sources)) {
|
|
1446
2856
|
const def = getRefKindDef(kind);
|
|
1447
2857
|
const items = sources.filter((r) => r.kind === kind);
|
|
1448
2858
|
if (items.length === 0) continue;
|
|
1449
2859
|
const group = document.createElement("div");
|
|
1450
|
-
group.className = "ai-composer-popup-group";
|
|
1451
|
-
group.dataset.
|
|
2860
|
+
group.className = "icen-ai-composer-popup-group";
|
|
2861
|
+
group.dataset.icenKind = kind;
|
|
1452
2862
|
group.appendChild(Object.assign(document.createElement("div"), {
|
|
1453
|
-
className: "ai-composer-popup-group-label",
|
|
2863
|
+
className: "icen-ai-composer-popup-group-label",
|
|
1454
2864
|
textContent: def.label
|
|
1455
2865
|
}));
|
|
1456
2866
|
for (const r of items) {
|
|
1457
|
-
const opt =
|
|
1458
|
-
opt.
|
|
1459
|
-
opt.className = "ai-composer-popup-option";
|
|
1460
|
-
opt.setAttribute("role", "option");
|
|
1461
|
-
opt.dataset.refId = r.id;
|
|
1462
|
-
opt.dataset.hay = `${r.label} ${r.sub ?? ""}`.toLowerCase();
|
|
1463
|
-
const icon = document.createElement("span");
|
|
1464
|
-
icon.className = "ai-composer-popup-option-icon";
|
|
1465
|
-
const svg2 = svgIcon(def.icon);
|
|
1466
|
-
if (svg2) icon.appendChild(svg2);
|
|
1467
|
-
const label = document.createElement("span");
|
|
1468
|
-
label.className = "ai-composer-popup-option-label";
|
|
1469
|
-
label.textContent = r.label;
|
|
1470
|
-
if (r.sub) {
|
|
1471
|
-
const sub = document.createElement("span");
|
|
1472
|
-
sub.className = "ai-composer-popup-option-sub";
|
|
1473
|
-
sub.textContent = r.sub;
|
|
1474
|
-
label.appendChild(sub);
|
|
1475
|
-
}
|
|
1476
|
-
opt.append(icon, label);
|
|
2867
|
+
const opt = resourceOption(r);
|
|
2868
|
+
opt.setAttribute("aria-selected", String((ACTIVE_REFS.get(composer) ?? []).some((a) => a.id === r.id && a.kind === r.kind)));
|
|
1477
2869
|
group.appendChild(opt);
|
|
1478
2870
|
s.options.push(opt);
|
|
1479
2871
|
}
|
|
@@ -1481,22 +2873,22 @@ function openRefPopup(composer, range, filter) {
|
|
|
1481
2873
|
s.groups.push(group);
|
|
1482
2874
|
}
|
|
1483
2875
|
s.panel.appendChild(list);
|
|
1484
|
-
appendPopupEmpty(s, "
|
|
2876
|
+
appendPopupEmpty(s, t("aiComposer.noRefMatch"));
|
|
2877
|
+
popupFoot(s, t("aiComposer.refHint"));
|
|
1485
2878
|
}
|
|
1486
2879
|
});
|
|
1487
|
-
ta?.setAttribute("aria-expanded", "true");
|
|
1488
2880
|
filterPopupOptions(session, filter);
|
|
1489
2881
|
}
|
|
1490
2882
|
function updateRefPopup(composer, s) {
|
|
1491
2883
|
const ta = getTextarea(composer);
|
|
1492
|
-
const
|
|
1493
|
-
if (!
|
|
2884
|
+
const t2 = ta ? findRefToken(ta) : null;
|
|
2885
|
+
if (!t2) {
|
|
1494
2886
|
closePopup(composer, false);
|
|
1495
2887
|
maybeOpenTriggerPopups(composer);
|
|
1496
2888
|
return;
|
|
1497
2889
|
}
|
|
1498
|
-
s.refRange = { start:
|
|
1499
|
-
filterPopupOptions(s,
|
|
2890
|
+
s.refRange = { start: t2.start, end: t2.end };
|
|
2891
|
+
filterPopupOptions(s, t2.filter);
|
|
1500
2892
|
}
|
|
1501
2893
|
function findRefToken(ta) {
|
|
1502
2894
|
const value = ta.value;
|
|
@@ -1518,30 +2910,34 @@ function maybeOpenTriggerPopups(composer) {
|
|
|
1518
2910
|
}
|
|
1519
2911
|
const sources = REF_SOURCES.get(composer);
|
|
1520
2912
|
if (sources && sources.length > 0) {
|
|
1521
|
-
const
|
|
1522
|
-
if (
|
|
2913
|
+
const t2 = findRefToken(ta);
|
|
2914
|
+
if (t2) openRefPopup(composer, { start: t2.start, end: t2.end }, t2.filter);
|
|
1523
2915
|
}
|
|
1524
2916
|
}
|
|
1525
2917
|
function ensureRefsRow(composer) {
|
|
1526
|
-
const existing = composer.querySelector(".ai-composer-refs");
|
|
2918
|
+
const existing = composer.querySelector(".icen-ai-composer-refs");
|
|
1527
2919
|
if (existing) return existing;
|
|
1528
2920
|
const row = document.createElement("div");
|
|
1529
|
-
row.className = "ai-composer-refs";
|
|
2921
|
+
row.className = "icen-ai-composer-refs";
|
|
1530
2922
|
row.dataset.aiRefs = "auto";
|
|
1531
2923
|
row.hidden = true;
|
|
1532
|
-
const attach = composer.querySelector(".ai-composer-attach");
|
|
1533
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
2924
|
+
const attach = composer.querySelector(".icen-ai-composer-attach");
|
|
2925
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
1534
2926
|
composer.insertBefore(row, attach ?? box ?? null);
|
|
1535
2927
|
return row;
|
|
1536
2928
|
}
|
|
1537
2929
|
function renderRefs(composer) {
|
|
1538
|
-
const row = composer.querySelector(".ai-composer-refs");
|
|
2930
|
+
const row = composer.querySelector(".icen-ai-composer-refs");
|
|
1539
2931
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1540
2932
|
if (!row) return;
|
|
1541
2933
|
row.replaceChildren(
|
|
1542
2934
|
...actives.map((src) => {
|
|
1543
|
-
const chip = makeChip(src.label, true,
|
|
2935
|
+
const chip = makeChip(src.label, true, t("aiComposer.removeRef", { p0: src.label }));
|
|
2936
|
+
chip.prepend(resourceIcon(src));
|
|
2937
|
+
chip.dataset.icenKind = src.kind;
|
|
1544
2938
|
chip.dataset.refId = src.id;
|
|
2939
|
+
chip.dataset.refKind = src.kind;
|
|
2940
|
+
chip.title = [src.label, src.description ?? src.sub].filter(Boolean).join(" \xB7 ");
|
|
1545
2941
|
return chip;
|
|
1546
2942
|
})
|
|
1547
2943
|
);
|
|
@@ -1549,31 +2945,69 @@ function renderRefs(composer) {
|
|
|
1549
2945
|
}
|
|
1550
2946
|
function addActiveRef(composer, source) {
|
|
1551
2947
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1552
|
-
if (actives.some((r) => r.id === source.id)) return;
|
|
2948
|
+
if (actives.some((r) => r.id === source.id && r.kind === source.kind)) return;
|
|
1553
2949
|
actives.push(source);
|
|
1554
2950
|
ACTIVE_REFS.set(composer, actives);
|
|
1555
2951
|
renderRefs(composer);
|
|
1556
|
-
|
|
2952
|
+
emit2(composer, "icen:ai-ref", { action: "add", ref: source });
|
|
1557
2953
|
}
|
|
1558
2954
|
function removeActiveRef(composer, source) {
|
|
1559
2955
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1560
|
-
const idx = actives.findIndex((r) => r.id === source.id);
|
|
2956
|
+
const idx = actives.findIndex((r) => r.id === source.id && r.kind === source.kind);
|
|
1561
2957
|
if (idx === -1) return;
|
|
1562
2958
|
actives.splice(idx, 1);
|
|
1563
2959
|
ACTIVE_REFS.set(composer, actives);
|
|
2960
|
+
const activeButton = document.activeElement;
|
|
2961
|
+
const restore = activeButton instanceof Element && !!activeButton.closest(".icen-ai-composer-refs");
|
|
1564
2962
|
renderRefs(composer);
|
|
2963
|
+
if (restore) {
|
|
2964
|
+
const buttons = composer.querySelectorAll(".icen-ai-composer-refs .icen-ai-composer-chip-remove");
|
|
2965
|
+
(buttons[Math.min(idx, buttons.length - 1)] ?? getTextarea(composer))?.focus({ preventScroll: true });
|
|
2966
|
+
}
|
|
1565
2967
|
const ta = getTextarea(composer);
|
|
1566
|
-
if (ta) {
|
|
2968
|
+
if (ta && !actives.some((r) => r.label === source.label)) {
|
|
1567
2969
|
const needle = `@${source.label}`;
|
|
1568
|
-
|
|
2970
|
+
let at = ta.value.indexOf(needle);
|
|
2971
|
+
while (at !== -1 && (at > 0 && !/\s/.test(ta.value[at - 1]) || ta.value[at + needle.length] !== void 0 && !/\s/.test(ta.value[at + needle.length]))) at = ta.value.indexOf(needle, at + needle.length);
|
|
1569
2972
|
if (at !== -1) {
|
|
2973
|
+
const start = ta.selectionStart, end = ta.selectionEnd, direction = ta.selectionDirection;
|
|
1570
2974
|
let endIdx = at + needle.length;
|
|
1571
2975
|
if (ta.value[endIdx] === " ") endIdx += 1;
|
|
1572
2976
|
ta.value = ta.value.slice(0, at) + ta.value.slice(endIdx);
|
|
2977
|
+
const shifted = (pos) => pos <= at ? pos : pos < endIdx ? at : pos - (endIdx - at);
|
|
2978
|
+
ta.setSelectionRange(shifted(start), shifted(end), direction);
|
|
1573
2979
|
autosizeTa(ta);
|
|
1574
2980
|
}
|
|
1575
2981
|
}
|
|
1576
|
-
|
|
2982
|
+
emit2(composer, "icen:ai-ref", { action: "remove", ref: source });
|
|
2983
|
+
}
|
|
2984
|
+
function renderFiles(composer) {
|
|
2985
|
+
let row = composer.querySelector(".icen-ai-composer-attach");
|
|
2986
|
+
const files = FILES.get(composer) ?? [];
|
|
2987
|
+
if (!row && files.length) {
|
|
2988
|
+
row = document.createElement("div");
|
|
2989
|
+
row.className = "icen-ai-composer-attach";
|
|
2990
|
+
composer.insertBefore(row, composer.querySelector(".icen-ai-composer-box"));
|
|
2991
|
+
}
|
|
2992
|
+
if (!row) return;
|
|
2993
|
+
row.replaceChildren(...files.map((file, index) => {
|
|
2994
|
+
const chip = makeChip(file.name, true, t("aiComposer.removeAttachment", { p0: file.name }), "file");
|
|
2995
|
+
chip.dataset.icenFile = String(index);
|
|
2996
|
+
const size = document.createElement("span");
|
|
2997
|
+
size.className = "icen-ai-composer-chip-meta";
|
|
2998
|
+
size.textContent = file.size < 1024 ? `${file.size} B` : `${Math.ceil(file.size / 1024)} KB`;
|
|
2999
|
+
chip.insertBefore(size, chip.lastElementChild);
|
|
3000
|
+
chip.title = file.name;
|
|
3001
|
+
return chip;
|
|
3002
|
+
}));
|
|
3003
|
+
row.hidden = !files.length;
|
|
3004
|
+
}
|
|
3005
|
+
function getComposerDraft(el) {
|
|
3006
|
+
if (!isBrowser()) return { text: "" };
|
|
3007
|
+
const c = resolveComposer(el);
|
|
3008
|
+
if (!c) return { text: "" };
|
|
3009
|
+
const refs = ACTIVE_REFS.get(c) ?? [], files = FILES.get(c) ?? [];
|
|
3010
|
+
return { text: getTextarea(c)?.value ?? "", ...refs.length ? { refs: refs.map((r) => ({ ...r })) } : {}, ...files.length ? { files: [...files] } : {} };
|
|
1577
3011
|
}
|
|
1578
3012
|
function pushHistory(composer, text) {
|
|
1579
3013
|
const h2 = HISTORIES.get(composer) ?? { items: [], index: -1 };
|
|
@@ -1593,31 +3027,35 @@ function setupComposer(composer) {
|
|
|
1593
3027
|
el.__icenAiComposerInit = false;
|
|
1594
3028
|
return void 0;
|
|
1595
3029
|
}
|
|
1596
|
-
const queueEl = composer.querySelector(".ai-composer-queue");
|
|
1597
|
-
const attachEl = composer.querySelector(".ai-composer-attach");
|
|
3030
|
+
const queueEl = composer.querySelector(".icen-ai-composer-queue");
|
|
1598
3031
|
const { sendBtn, sendIcon, stopIcon } = ensureIcons(composer);
|
|
1599
3032
|
if (!ta.hasAttribute("placeholder")) {
|
|
1600
|
-
ta.setAttribute("placeholder", "
|
|
3033
|
+
ta.setAttribute("placeholder", t("aiComposer.placeholder"));
|
|
1601
3034
|
}
|
|
1602
3035
|
const renderQueue = () => renderQueueChips(composer);
|
|
1603
|
-
const enqueue = (
|
|
3036
|
+
const enqueue = (draft) => {
|
|
1604
3037
|
const queue = QUEUES.get(composer) ?? [];
|
|
1605
|
-
queue.push(
|
|
3038
|
+
queue.push({ ...draft, ...draft.refs ? { refs: draft.refs.map((r) => ({ ...r })) } : {}, ...draft.files ? { files: [...draft.files] } : {} });
|
|
1606
3039
|
QUEUES.set(composer, queue);
|
|
1607
3040
|
renderQueue();
|
|
1608
3041
|
};
|
|
1609
3042
|
const isRunning = () => RUNNING.get(composer) ?? false;
|
|
1610
3043
|
const submit = () => {
|
|
1611
|
-
|
|
1612
|
-
|
|
3044
|
+
if (ta.disabled || ta.readOnly || composing) return;
|
|
3045
|
+
const draft = getComposerDraft(composer);
|
|
3046
|
+
if (!draft.text.trim() && !draft.files?.length && !draft.refs?.length) return;
|
|
1613
3047
|
ta.value = "";
|
|
1614
3048
|
autosizeTa(ta);
|
|
3049
|
+
ACTIVE_REFS.set(composer, []);
|
|
3050
|
+
FILES.set(composer, []);
|
|
3051
|
+
renderRefs(composer);
|
|
3052
|
+
renderFiles(composer);
|
|
1615
3053
|
if (isRunning()) {
|
|
1616
|
-
enqueue(
|
|
1617
|
-
|
|
3054
|
+
enqueue(draft);
|
|
3055
|
+
emit2(composer, "icen:ai-queue", draft);
|
|
1618
3056
|
} else {
|
|
1619
|
-
pushHistory(composer, text);
|
|
1620
|
-
|
|
3057
|
+
pushHistory(composer, draft.text);
|
|
3058
|
+
emit2(composer, "icen:ai-send", draft);
|
|
1621
3059
|
}
|
|
1622
3060
|
};
|
|
1623
3061
|
SUBMITS.set(composer, submit);
|
|
@@ -1625,12 +3063,16 @@ function setupComposer(composer) {
|
|
|
1625
3063
|
const queue = QUEUES.get(composer) ?? [];
|
|
1626
3064
|
if (queue.length === 0) return;
|
|
1627
3065
|
const index = queue.length - 1;
|
|
1628
|
-
const
|
|
3066
|
+
const draft = queue.pop();
|
|
1629
3067
|
QUEUES.set(composer, queue);
|
|
1630
3068
|
renderQueue();
|
|
1631
|
-
ta.value = text;
|
|
3069
|
+
ta.value = draft.text;
|
|
3070
|
+
for (const ref of draft.refs ?? []) addActiveRef(composer, ref);
|
|
3071
|
+
const files = FILES.get(composer) ?? [];
|
|
3072
|
+
FILES.set(composer, Array.from(/* @__PURE__ */ new Set([...files, ...draft.files ?? []])));
|
|
3073
|
+
renderFiles(composer);
|
|
1632
3074
|
autosizeTa(ta);
|
|
1633
|
-
|
|
3075
|
+
emit2(composer, "icen:ai-dequeue", { index });
|
|
1634
3076
|
};
|
|
1635
3077
|
const browseHistory = (delta) => {
|
|
1636
3078
|
const h2 = HISTORIES.get(composer);
|
|
@@ -1650,7 +3092,7 @@ function setupComposer(composer) {
|
|
|
1650
3092
|
autosizeTa(ta);
|
|
1651
3093
|
};
|
|
1652
3094
|
const onKeydown = (e) => {
|
|
1653
|
-
if (composing || e.isComposing) return;
|
|
3095
|
+
if (composing || e.isComposing || ta.disabled || ta.readOnly) return;
|
|
1654
3096
|
const session = POPUP.get(composer);
|
|
1655
3097
|
if (session) {
|
|
1656
3098
|
popupKeydown(composer, session, e);
|
|
@@ -1658,6 +3100,7 @@ function setupComposer(composer) {
|
|
|
1658
3100
|
}
|
|
1659
3101
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
1660
3102
|
e.preventDefault();
|
|
3103
|
+
if (ta.value.startsWith("/") && runComposerCommand(composer, commandToken(ta.value))) return;
|
|
1661
3104
|
submit();
|
|
1662
3105
|
return;
|
|
1663
3106
|
}
|
|
@@ -1665,7 +3108,7 @@ function setupComposer(composer) {
|
|
|
1665
3108
|
const h2 = HISTORIES.get(composer);
|
|
1666
3109
|
const browsing = (h2?.index ?? -1) >= 0;
|
|
1667
3110
|
if (ta.value === "") {
|
|
1668
|
-
if (
|
|
3111
|
+
if ((QUEUES.get(composer) ?? []).length > 0) {
|
|
1669
3112
|
e.preventDefault();
|
|
1670
3113
|
takeBackLastQueued();
|
|
1671
3114
|
return;
|
|
@@ -1690,6 +3133,7 @@ function setupComposer(composer) {
|
|
|
1690
3133
|
};
|
|
1691
3134
|
const onInput = () => {
|
|
1692
3135
|
autosizeTa(ta);
|
|
3136
|
+
if (composing) return;
|
|
1693
3137
|
const h2 = HISTORIES.get(composer);
|
|
1694
3138
|
if (h2 && h2.index >= 0 && ta.value !== h2.items[h2.index]) h2.index = -1;
|
|
1695
3139
|
const session = POPUP.get(composer);
|
|
@@ -1703,34 +3147,39 @@ function setupComposer(composer) {
|
|
|
1703
3147
|
let composing = false;
|
|
1704
3148
|
const onCompositionStart = () => {
|
|
1705
3149
|
composing = true;
|
|
3150
|
+
closePopup(composer, false);
|
|
1706
3151
|
};
|
|
1707
3152
|
const onCompositionEnd = () => {
|
|
1708
3153
|
composing = false;
|
|
3154
|
+
onInput();
|
|
1709
3155
|
};
|
|
1710
3156
|
const onSendClick = () => {
|
|
1711
3157
|
if (isRunning()) {
|
|
1712
|
-
|
|
3158
|
+
emit2(composer, "icen:ai-stop", {});
|
|
1713
3159
|
} else {
|
|
1714
3160
|
submit();
|
|
1715
3161
|
}
|
|
1716
3162
|
};
|
|
1717
3163
|
const onQueueClick = (e) => {
|
|
1718
|
-
const btn = e.target instanceof Element ? e.target.closest(".ai-composer-chip-remove") : null;
|
|
3164
|
+
const btn = e.target instanceof Element ? e.target.closest(".icen-ai-composer-chip-remove") : null;
|
|
1719
3165
|
if (!btn) return;
|
|
1720
|
-
const index = Array.from(queueEl?.querySelectorAll(".ai-composer-chip-remove") ?? []).indexOf(btn);
|
|
3166
|
+
const index = Array.from(queueEl?.querySelectorAll(".icen-ai-composer-chip-remove") ?? []).indexOf(btn);
|
|
1721
3167
|
const queue = QUEUES.get(composer) ?? [];
|
|
1722
3168
|
if (index >= 0 && index < queue.length) {
|
|
1723
3169
|
queue.splice(index, 1);
|
|
1724
3170
|
QUEUES.set(composer, queue);
|
|
1725
3171
|
renderQueue();
|
|
1726
|
-
|
|
3172
|
+
const buttons = queueEl?.querySelectorAll(".icen-ai-composer-chip-remove");
|
|
3173
|
+
(buttons?.[Math.min(index, buttons.length - 1)] ?? ta).focus({ preventScroll: true });
|
|
3174
|
+
emit2(composer, "icen:ai-dequeue", { index });
|
|
1727
3175
|
}
|
|
1728
3176
|
};
|
|
1729
3177
|
const onRefsClick = (e) => {
|
|
1730
|
-
const btn = e.target instanceof Element ? e.target.closest(".ai-composer-chip-remove") : null;
|
|
1731
|
-
if (!btn || !btn.closest(".ai-composer-refs")) return;
|
|
1732
|
-
const id = btn.closest(".ai-composer-chip")?.dataset.refId;
|
|
1733
|
-
const
|
|
3178
|
+
const btn = e.target instanceof Element ? e.target.closest(".icen-ai-composer-chip-remove") : null;
|
|
3179
|
+
if (!btn || !btn.closest(".icen-ai-composer-refs")) return;
|
|
3180
|
+
const id = btn.closest(".icen-ai-composer-chip")?.dataset.refId;
|
|
3181
|
+
const kind = btn.closest(".icen-ai-composer-chip")?.dataset.refKind;
|
|
3182
|
+
const source = (ACTIVE_REFS.get(composer) ?? []).find((r) => r.id === id && r.kind === kind);
|
|
1734
3183
|
if (source) removeActiveRef(composer, source);
|
|
1735
3184
|
};
|
|
1736
3185
|
const fileInput = document.createElement("input");
|
|
@@ -1739,20 +3188,32 @@ function setupComposer(composer) {
|
|
|
1739
3188
|
fileInput.multiple = true;
|
|
1740
3189
|
composer.appendChild(fileInput);
|
|
1741
3190
|
const onAttachClick = () => {
|
|
1742
|
-
fileInput.click();
|
|
3191
|
+
if (!ta.disabled && !ta.readOnly) fileInput.click();
|
|
1743
3192
|
};
|
|
1744
3193
|
const addFiles = (files) => {
|
|
1745
|
-
if (files.length
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
remove?.addEventListener("click", () => chip.remove(), { once: true });
|
|
1751
|
-
attachEl.appendChild(chip);
|
|
1752
|
-
}
|
|
1753
|
-
attachEl.hidden = false;
|
|
3194
|
+
if (!files.length || ta.disabled || ta.readOnly) return;
|
|
3195
|
+
const current2 = FILES.get(composer) ?? [];
|
|
3196
|
+
const accepted = [];
|
|
3197
|
+
for (const file of files) {
|
|
3198
|
+
if (![...current2, ...accepted].some((c) => c.name === file.name && c.size === file.size && c.lastModified === file.lastModified && c.type === file.type)) accepted.push(file);
|
|
1754
3199
|
}
|
|
1755
|
-
|
|
3200
|
+
if (!accepted.length) return;
|
|
3201
|
+
FILES.set(composer, [...current2, ...accepted]);
|
|
3202
|
+
renderFiles(composer);
|
|
3203
|
+
emit2(composer, "icen:ai-attach", { files: accepted });
|
|
3204
|
+
};
|
|
3205
|
+
const onRemoveFile = (e) => {
|
|
3206
|
+
const button = e.target instanceof Element ? e.target.closest(".icen-ai-composer-attach .icen-ai-composer-chip-remove") : null;
|
|
3207
|
+
if (!button) return;
|
|
3208
|
+
const index = Number(button.closest("[data-icen-file]")?.dataset.icenFile);
|
|
3209
|
+
const files = FILES.get(composer) ?? [];
|
|
3210
|
+
if (!Number.isInteger(index) || index < 0 || index >= files.length) return;
|
|
3211
|
+
const [file] = files.splice(index, 1);
|
|
3212
|
+
FILES.set(composer, files);
|
|
3213
|
+
renderFiles(composer);
|
|
3214
|
+
const buttons = composer.querySelectorAll(".icen-ai-composer-attach .icen-ai-composer-chip-remove");
|
|
3215
|
+
(buttons[Math.min(index, buttons.length - 1)] ?? ta).focus({ preventScroll: true });
|
|
3216
|
+
emit2(composer, "icen:ai-attachment-remove", { file, files: [...files] });
|
|
1756
3217
|
};
|
|
1757
3218
|
const onFileChange = () => {
|
|
1758
3219
|
const files = Array.from(fileInput.files ?? []);
|
|
@@ -1765,7 +3226,7 @@ function setupComposer(composer) {
|
|
|
1765
3226
|
e.preventDefault();
|
|
1766
3227
|
addFiles(files);
|
|
1767
3228
|
};
|
|
1768
|
-
const boxEl = composer.querySelector(".ai-composer-box");
|
|
3229
|
+
const boxEl = composer.querySelector(".icen-ai-composer-box");
|
|
1769
3230
|
const onDragOver = (e) => {
|
|
1770
3231
|
if (!e.dataTransfer?.types.includes("Files")) return;
|
|
1771
3232
|
e.preventDefault();
|
|
@@ -1792,7 +3253,8 @@ function setupComposer(composer) {
|
|
|
1792
3253
|
sendBtn?.addEventListener("click", onSendClick);
|
|
1793
3254
|
queueEl?.addEventListener("click", onQueueClick);
|
|
1794
3255
|
composer.addEventListener("click", onRefsClick);
|
|
1795
|
-
composer.
|
|
3256
|
+
composer.addEventListener("click", onRemoveFile);
|
|
3257
|
+
composer.querySelector("[data-icen-ai-attach]")?.addEventListener("click", onAttachClick);
|
|
1796
3258
|
fileInput.addEventListener("change", onFileChange);
|
|
1797
3259
|
const initialRunning = RUNNING.get(composer) ?? composer.classList.contains("is-running");
|
|
1798
3260
|
if (initialRunning) setComposerRunning(composer, true);
|
|
@@ -1803,6 +3265,7 @@ function setupComposer(composer) {
|
|
|
1803
3265
|
autosizeTa(ta);
|
|
1804
3266
|
renderQueue();
|
|
1805
3267
|
renderRefs(composer);
|
|
3268
|
+
renderFiles(composer);
|
|
1806
3269
|
return () => {
|
|
1807
3270
|
closePopup(composer, false);
|
|
1808
3271
|
ta.removeEventListener("keydown", onKeydown);
|
|
@@ -1816,7 +3279,8 @@ function setupComposer(composer) {
|
|
|
1816
3279
|
sendBtn?.removeEventListener("click", onSendClick);
|
|
1817
3280
|
queueEl?.removeEventListener("click", onQueueClick);
|
|
1818
3281
|
composer.removeEventListener("click", onRefsClick);
|
|
1819
|
-
composer.
|
|
3282
|
+
composer.removeEventListener("click", onRemoveFile);
|
|
3283
|
+
composer.querySelector("[data-icen-ai-attach]")?.removeEventListener("click", onAttachClick);
|
|
1820
3284
|
fileInput.removeEventListener("change", onFileChange);
|
|
1821
3285
|
fileInput.remove();
|
|
1822
3286
|
el.__icenAiComposerInit = false;
|
|
@@ -1827,10 +3291,10 @@ function initAiComposer(root) {
|
|
|
1827
3291
|
if (isBrowser()) {
|
|
1828
3292
|
const scope = root ?? document;
|
|
1829
3293
|
const candidates = [];
|
|
1830
|
-
if (scope instanceof Element && scope.matches("[data-ai-composer]")) {
|
|
3294
|
+
if (scope instanceof Element && scope.matches("[data-icen-ai-composer]")) {
|
|
1831
3295
|
candidates.push(scope);
|
|
1832
3296
|
}
|
|
1833
|
-
candidates.push(...Array.from(scope.querySelectorAll("[data-ai-composer]")));
|
|
3297
|
+
candidates.push(...Array.from(scope.querySelectorAll("[data-icen-ai-composer]")));
|
|
1834
3298
|
for (const composer of candidates) {
|
|
1835
3299
|
const cleanup = setupComposer(composer);
|
|
1836
3300
|
if (cleanup) cleanups.push(cleanup);
|
|
@@ -1841,7 +3305,7 @@ function initAiComposer(root) {
|
|
|
1841
3305
|
cleanups.length = 0;
|
|
1842
3306
|
};
|
|
1843
3307
|
}
|
|
1844
|
-
function setComposerModels(el, providers,
|
|
3308
|
+
function setComposerModels(el, providers, current2) {
|
|
1845
3309
|
if (!isBrowser()) return;
|
|
1846
3310
|
const composer = resolveComposer(el);
|
|
1847
3311
|
if (!composer) return;
|
|
@@ -1851,13 +3315,13 @@ function setComposerModels(el, providers, current) {
|
|
|
1851
3315
|
if (list.length === 0) {
|
|
1852
3316
|
MODELS.delete(composer);
|
|
1853
3317
|
MODEL_CTX.delete(composer);
|
|
1854
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
1855
|
-
if (btn?.dataset.
|
|
3318
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
3319
|
+
if (btn?.dataset.icenAiModelOpen === "auto") btn.remove();
|
|
1856
3320
|
syncToolbar(composer);
|
|
1857
3321
|
refreshUsageRing(composer);
|
|
1858
3322
|
return;
|
|
1859
3323
|
}
|
|
1860
|
-
const cur =
|
|
3324
|
+
const cur = current2 ?? { provider: list[0].id, model: list[0].models[0].id };
|
|
1861
3325
|
MODELS.set(composer, { providers: list, current: cur });
|
|
1862
3326
|
const provider = list.find((p) => p.id === cur.provider) ?? list[0];
|
|
1863
3327
|
const model = provider.models.find((m) => m.id === cur.model) ?? provider.models[0];
|
|
@@ -1878,10 +3342,13 @@ function setComposerCommands(el, commands) {
|
|
|
1878
3342
|
if (list.length === 0) {
|
|
1879
3343
|
COMMANDS.delete(composer);
|
|
1880
3344
|
const session = POPUP.get(composer);
|
|
1881
|
-
if (session?.mode === "command") closePopup(composer);
|
|
3345
|
+
if (session?.mode === "command" || session?.mode === "library") closePopup(composer);
|
|
3346
|
+
syncToolbar(composer);
|
|
1882
3347
|
return;
|
|
1883
3348
|
}
|
|
1884
3349
|
COMMANDS.set(composer, list);
|
|
3350
|
+
syncToolbar(composer);
|
|
3351
|
+
if (POPUP.get(composer)) closePopup(composer);
|
|
1885
3352
|
}
|
|
1886
3353
|
function setComposerRefs(el, sources) {
|
|
1887
3354
|
if (!isBrowser()) return;
|
|
@@ -1889,6 +3356,8 @@ function setComposerRefs(el, sources) {
|
|
|
1889
3356
|
if (!composer) return;
|
|
1890
3357
|
const list = (Array.isArray(sources) ? sources : []).filter((s) => s && typeof s.label === "string" && s.label);
|
|
1891
3358
|
REF_SOURCES.set(composer, list);
|
|
3359
|
+
syncToolbar(composer);
|
|
3360
|
+
if (POPUP.get(composer)) closePopup(composer);
|
|
1892
3361
|
if (list.length === 0) {
|
|
1893
3362
|
const session = POPUP.get(composer);
|
|
1894
3363
|
if (session?.mode === "ref") closePopup(composer);
|
|
@@ -1902,8 +3371,8 @@ function setComposerUsage(el, usage, opts = {}) {
|
|
|
1902
3371
|
if (!composer) return;
|
|
1903
3372
|
if (!usage) {
|
|
1904
3373
|
USAGE.delete(composer);
|
|
1905
|
-
const mount = composer.querySelector(".ai-composer-usage");
|
|
1906
|
-
if (mount?.dataset.
|
|
3374
|
+
const mount = composer.querySelector(".icen-ai-composer-usage");
|
|
3375
|
+
if (mount?.dataset.icenAiUsage === "auto") mount.remove();
|
|
1907
3376
|
syncToolbar(composer);
|
|
1908
3377
|
return;
|
|
1909
3378
|
}
|
|
@@ -1915,7 +3384,7 @@ function setComposerTodo(el, items) {
|
|
|
1915
3384
|
if (!isBrowser()) return;
|
|
1916
3385
|
const composer = resolveComposer(el);
|
|
1917
3386
|
if (!composer) return;
|
|
1918
|
-
let chip = composer.querySelector(".ai-composer-todo");
|
|
3387
|
+
let chip = composer.querySelector(".icen-ai-composer-todo");
|
|
1919
3388
|
if (!items || items.length === 0) {
|
|
1920
3389
|
TODO_STATES.delete(composer);
|
|
1921
3390
|
chip?.remove();
|
|
@@ -1925,17 +3394,17 @@ function setComposerTodo(el, items) {
|
|
|
1925
3394
|
if (!chip) {
|
|
1926
3395
|
const btn = document.createElement("button");
|
|
1927
3396
|
btn.type = "button";
|
|
1928
|
-
btn.className = "ai-composer-todo";
|
|
3397
|
+
btn.className = "icen-ai-composer-todo";
|
|
1929
3398
|
btn.setAttribute("aria-haspopup", "true");
|
|
1930
3399
|
btn.addEventListener("click", () => {
|
|
1931
3400
|
const cur = TODO_STATES.get(composer);
|
|
1932
3401
|
if (!cur) return;
|
|
1933
3402
|
const p = document.createElement("div");
|
|
1934
|
-
p.className = "popover ai-composer-todo-pop";
|
|
3403
|
+
p.className = "icen-popover icen-ai-composer-todo-pop";
|
|
1935
3404
|
p.hidden = true;
|
|
1936
3405
|
const title = document.createElement("div");
|
|
1937
|
-
title.className = "ai-usage-popover-title";
|
|
1938
|
-
title.textContent = "
|
|
3406
|
+
title.className = "icen-ai-usage-popover-title";
|
|
3407
|
+
title.textContent = t("aiComposer.currentTodos");
|
|
1939
3408
|
const body = document.createElement("div");
|
|
1940
3409
|
body.className = "ai-usage-popover-body";
|
|
1941
3410
|
renderAiTodo(body, cur);
|
|
@@ -1953,39 +3422,42 @@ function setComposerTodo(el, items) {
|
|
|
1953
3422
|
);
|
|
1954
3423
|
if (icon) chip.appendChild(icon);
|
|
1955
3424
|
chip.appendChild(document.createElement("span")).className = "ai-composer-todo-label";
|
|
1956
|
-
const toolbar = composer.querySelector(".ai-composer-toolbar");
|
|
1957
|
-
const usage = composer.querySelector(".ai-composer-usage");
|
|
3425
|
+
const toolbar = composer.querySelector(".icen-ai-composer-toolbar");
|
|
3426
|
+
const usage = composer.querySelector(".icen-ai-composer-usage");
|
|
1958
3427
|
if (toolbar) toolbar.insertBefore(chip, usage ?? null);
|
|
1959
3428
|
else {
|
|
1960
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
3429
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
1961
3430
|
box?.before(chip);
|
|
1962
3431
|
}
|
|
1963
3432
|
}
|
|
1964
|
-
const done = items.filter((
|
|
1965
|
-
const failed = items.some((
|
|
3433
|
+
const done = items.filter((t2) => t2.status === "done").length;
|
|
3434
|
+
const failed = items.some((t2) => t2.status === "error" || t2.status === "cancelled");
|
|
1966
3435
|
chip.classList.toggle("is-done", done === items.length && !failed);
|
|
1967
3436
|
chip.classList.toggle("is-error", failed);
|
|
1968
|
-
chip.setAttribute("aria-label",
|
|
3437
|
+
chip.setAttribute("aria-label", t("aiComposer.todoChip", { p0: done, p1: items.length, p2: failed ? t("aiComposer.todoHasError") : "" }));
|
|
1969
3438
|
const label = chip.querySelector(".ai-composer-todo-label");
|
|
1970
3439
|
if (label) label.textContent = `${done}/${items.length}`;
|
|
1971
3440
|
}
|
|
1972
3441
|
var BOUND = /* @__PURE__ */ new WeakSet();
|
|
1973
3442
|
function bindComposer(el, opts = {}) {
|
|
1974
3443
|
const noop = () => void 0;
|
|
1975
|
-
if (!isBrowser()) return { unbind: noop };
|
|
3444
|
+
if (!isBrowser()) return { unbind: noop, retry: () => false };
|
|
1976
3445
|
const composer = resolveComposer(el);
|
|
1977
|
-
if (!composer) return { unbind: noop };
|
|
1978
|
-
if (BOUND.has(composer)) return { unbind: noop };
|
|
3446
|
+
if (!composer) return { unbind: noop, retry: () => false };
|
|
3447
|
+
if (BOUND.has(composer)) return { unbind: noop, retry: () => false };
|
|
1979
3448
|
BOUND.add(composer);
|
|
1980
3449
|
if (opts.popoverSizing) POPUP_SIZING.set(composer, opts.popoverSizing);
|
|
1981
3450
|
const disposers = [];
|
|
1982
3451
|
const usageCfg = opts.usage;
|
|
1983
3452
|
const manageRunning = opts.running ?? true;
|
|
3453
|
+
let bound = true;
|
|
3454
|
+
let retry = () => false;
|
|
3455
|
+
let updateUsage = (_detail) => {
|
|
3456
|
+
};
|
|
1984
3457
|
if (usageCfg) {
|
|
1985
3458
|
let cost = 0;
|
|
1986
3459
|
let billing = {};
|
|
1987
|
-
|
|
1988
|
-
const detail = e.detail;
|
|
3460
|
+
updateUsage = (detail) => {
|
|
1989
3461
|
if (!detail?.usage) return;
|
|
1990
3462
|
if (typeof detail.cost === "number") cost += detail.cost;
|
|
1991
3463
|
let usage;
|
|
@@ -2010,8 +3482,12 @@ function bindComposer(el, opts = {}) {
|
|
|
2010
3482
|
cost: cost > 0 ? Math.round(cost * 1e6) / 1e6 : void 0
|
|
2011
3483
|
});
|
|
2012
3484
|
};
|
|
2013
|
-
|
|
2014
|
-
|
|
3485
|
+
if (!opts.client || !opts.messages) {
|
|
3486
|
+
const onDone = (e) => updateUsage(e.detail);
|
|
3487
|
+
const target = opts.eventTarget ?? document;
|
|
3488
|
+
target.addEventListener("icen:ai-done", onDone);
|
|
3489
|
+
disposers.push(() => target.removeEventListener("icen:ai-done", onDone));
|
|
3490
|
+
}
|
|
2015
3491
|
}
|
|
2016
3492
|
if (opts.client && !opts.messages) {
|
|
2017
3493
|
console.warn("[ai-composer] client \u6A21\u5F0F\u9700\u8981 opts.messages\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u7EAF\u72B6\u6001\u7ED1\u5B9A");
|
|
@@ -2020,81 +3496,164 @@ function bindComposer(el, opts = {}) {
|
|
|
2020
3496
|
const client = opts.client;
|
|
2021
3497
|
const messages = opts.messages;
|
|
2022
3498
|
const history = [];
|
|
2023
|
-
let
|
|
3499
|
+
let active = null;
|
|
3500
|
+
let retryable = null;
|
|
2024
3501
|
const metaOf = (r) => {
|
|
2025
3502
|
const tok = r.usage.total ?? 0;
|
|
2026
|
-
const parts = [tok > 0 ? `${formatTokens(tok)} tok` : "
|
|
3503
|
+
const parts = [tok > 0 ? `${formatTokens(tok)} tok` : t("aiComposer.done")];
|
|
2027
3504
|
if (typeof r.cost === "number") parts.push(`$${r.cost.toFixed(4)}`);
|
|
2028
|
-
return
|
|
3505
|
+
return t("aiComposer.justNow", { p0: parts.join(" \xB7 ") });
|
|
2029
3506
|
};
|
|
2030
|
-
const startTurn = () => {
|
|
2031
|
-
const assistant = renderAiMessage(messages, {
|
|
3507
|
+
const startTurn = (previous, draft) => {
|
|
3508
|
+
const assistant = previous?.assistant ?? renderAiMessage(messages, {
|
|
2032
3509
|
role: "assistant",
|
|
2033
3510
|
content: "",
|
|
2034
3511
|
streaming: true,
|
|
2035
3512
|
model: client.config.model
|
|
2036
3513
|
});
|
|
3514
|
+
if (previous) {
|
|
3515
|
+
const restoreRetryFocus = assistant.body.contains(document.activeElement);
|
|
3516
|
+
previous.textNode?.remove();
|
|
3517
|
+
assistant.body.querySelectorAll(".icen-ai-msg-continue,.icen-ai-msg-error-text").forEach((node) => node.remove());
|
|
3518
|
+
assistant.el.classList.remove("icen-ai-msg--error");
|
|
3519
|
+
assistant.setMeta("");
|
|
3520
|
+
if (restoreRetryFocus) assistant.el.querySelector('[data-icen-ai-msg-action="retry"]')?.focus({ preventScroll: true });
|
|
3521
|
+
}
|
|
2037
3522
|
const streamH = assistant.stream();
|
|
3523
|
+
assistant.el.classList.add("is-streaming");
|
|
3524
|
+
const turn = { assistant, stream: streamH, textNode: assistant.body.lastElementChild, request: [...history], session: null, text: "", draft: previous?.draft ?? draft, preparation: new AbortController() };
|
|
3525
|
+
active = turn;
|
|
3526
|
+
retryable = null;
|
|
2038
3527
|
setComposerRunning(composer, true);
|
|
2039
|
-
const s = client.stream({ messages: [...history] });
|
|
2040
|
-
session = s;
|
|
2041
3528
|
let failed = false;
|
|
2042
3529
|
void (async () => {
|
|
2043
|
-
|
|
2044
|
-
if (
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
3530
|
+
try {
|
|
3531
|
+
if (turn.draft && opts.prepareMessage) {
|
|
3532
|
+
const content = await opts.prepareMessage(turn.draft, { signal: turn.preparation.signal });
|
|
3533
|
+
if (!bound || active !== turn) return;
|
|
3534
|
+
turn.request[turn.request.length - 1] = { role: "user", content };
|
|
3535
|
+
history.splice(0, history.length, ...turn.request);
|
|
3536
|
+
} else if (turn.draft?.files?.length) throw new Error(t("aiComposer.filesNeedAdapter"));
|
|
3537
|
+
const s = client.stream({ messages: turn.request });
|
|
3538
|
+
turn.session = s;
|
|
3539
|
+
void s.done.catch(() => {
|
|
3540
|
+
});
|
|
3541
|
+
for await (const chunk of s) {
|
|
3542
|
+
if (!bound || active !== turn) return;
|
|
3543
|
+
if (chunk.type === "text") {
|
|
3544
|
+
turn.text += chunk.delta;
|
|
3545
|
+
streamH.append(chunk.delta);
|
|
3546
|
+
} else if (chunk.type === "error") {
|
|
3547
|
+
failed = true;
|
|
3548
|
+
streamH.fail();
|
|
3549
|
+
assistant.setError(chunk.message);
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
const result = await s.done;
|
|
3553
|
+
if (!bound || active !== turn) return;
|
|
3554
|
+
if (!failed) {
|
|
3555
|
+
streamH.done();
|
|
3556
|
+
assistant.setMeta(metaOf(result));
|
|
3557
|
+
updateUsage(result);
|
|
3558
|
+
}
|
|
3559
|
+
if (result.text) history.push({ role: "assistant", content: result.text });
|
|
3560
|
+
} catch (error) {
|
|
3561
|
+
if (!bound || active !== turn) return;
|
|
3562
|
+
failed = true;
|
|
3563
|
+
streamH.fail();
|
|
3564
|
+
assistant.setError(error instanceof Error ? error.message : String(error));
|
|
3565
|
+
} finally {
|
|
3566
|
+
if (!bound || active !== turn) return;
|
|
3567
|
+
active = null;
|
|
3568
|
+
assistant.el.classList.remove("is-streaming");
|
|
3569
|
+
setComposerRunning(composer, false);
|
|
3570
|
+
if (failed) {
|
|
3571
|
+
retryable = turn;
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
const queue = QUEUES.get(composer) ?? [];
|
|
3575
|
+
if (queue.length > 0) {
|
|
3576
|
+
const next = queue.shift();
|
|
3577
|
+
QUEUES.set(composer, queue);
|
|
3578
|
+
renderQueueChips(composer);
|
|
3579
|
+
emit2(composer, "icen:ai-dequeue", { index: 0 });
|
|
3580
|
+
if (bound) send(next);
|
|
2049
3581
|
}
|
|
2050
|
-
}
|
|
2051
|
-
const result = await s.done;
|
|
2052
|
-
session = null;
|
|
2053
|
-
if (!failed) streamH.done();
|
|
2054
|
-
assistant.setMeta(metaOf(result));
|
|
2055
|
-
if (result.text) history.push({ role: "assistant", content: result.text });
|
|
2056
|
-
setComposerRunning(composer, false);
|
|
2057
|
-
const queue = QUEUES.get(composer) ?? [];
|
|
2058
|
-
if (queue.length > 0) {
|
|
2059
|
-
const next = queue.shift() ?? "";
|
|
2060
|
-
QUEUES.set(composer, queue);
|
|
2061
|
-
renderQueueChips(composer);
|
|
2062
|
-
emit(composer, "icen:ai-dequeue", { index: 0 });
|
|
2063
|
-
send(next);
|
|
2064
3582
|
}
|
|
2065
3583
|
})();
|
|
2066
3584
|
};
|
|
2067
|
-
const send = (
|
|
2068
|
-
|
|
3585
|
+
const send = (draft) => {
|
|
3586
|
+
if (!bound || active) return;
|
|
3587
|
+
const missingRefs = (draft.refs ?? []).filter((r) => !draft.text.includes(`@${r.label}`));
|
|
3588
|
+
const text = [draft.text, ...missingRefs.map((r) => `@${r.label}`)].filter(Boolean).join("\n");
|
|
3589
|
+
const message = renderAiMessage(messages, { role: "user", content: draft.text });
|
|
3590
|
+
if (draft.refs?.length || draft.files?.length) {
|
|
3591
|
+
const context = document.createElement("div");
|
|
3592
|
+
context.className = "icen-ai-msg-context";
|
|
3593
|
+
for (const ref of draft.refs ?? []) {
|
|
3594
|
+
const chip = makeChip(ref.label, false, "");
|
|
3595
|
+
chip.prepend(resourceIcon(ref));
|
|
3596
|
+
context.append(chip);
|
|
3597
|
+
}
|
|
3598
|
+
for (const file of draft.files ?? []) context.append(makeChip(file.name, false, "", "file"));
|
|
3599
|
+
message.body.append(context);
|
|
3600
|
+
}
|
|
2069
3601
|
history.push({ role: "user", content: text });
|
|
2070
|
-
startTurn();
|
|
3602
|
+
startTurn(void 0, draft);
|
|
2071
3603
|
};
|
|
2072
3604
|
const onSend = (e) => {
|
|
2073
|
-
const
|
|
2074
|
-
if (typeof text === "string" && text) send(
|
|
3605
|
+
const draft = e.detail;
|
|
3606
|
+
if (typeof draft?.text === "string" && (draft.text || draft.files?.length || draft.refs?.length)) send(draft);
|
|
2075
3607
|
};
|
|
2076
3608
|
const onStop = () => {
|
|
2077
|
-
|
|
3609
|
+
const turn = active;
|
|
3610
|
+
if (!turn) return;
|
|
3611
|
+
active = null;
|
|
3612
|
+
turn.preparation.abort();
|
|
3613
|
+
retryable = turn;
|
|
3614
|
+
turn.stream.cancel();
|
|
3615
|
+
turn.assistant.el.classList.remove("is-streaming");
|
|
3616
|
+
turn.assistant.setMeta(t("aiComposer.stopped"));
|
|
3617
|
+
if (turn.text) history.push({ role: "assistant", content: turn.text });
|
|
3618
|
+
setComposerRunning(composer, false);
|
|
3619
|
+
turn.session?.cancel();
|
|
3620
|
+
};
|
|
3621
|
+
retry = () => {
|
|
3622
|
+
if (!bound || active || !retryable) return false;
|
|
3623
|
+
const turn = retryable;
|
|
3624
|
+
history.splice(0, history.length, ...turn.request);
|
|
3625
|
+
startTurn(turn);
|
|
3626
|
+
return true;
|
|
3627
|
+
};
|
|
3628
|
+
const onRetry = (event) => {
|
|
3629
|
+
if (event.detail?.el === retryable?.assistant.el) retry();
|
|
2078
3630
|
};
|
|
2079
3631
|
composer.addEventListener("icen:ai-send", onSend);
|
|
2080
3632
|
composer.addEventListener("icen:ai-stop", onStop);
|
|
3633
|
+
messages.addEventListener("icen:ai-retry", onRetry);
|
|
2081
3634
|
disposers.push(() => {
|
|
2082
3635
|
composer.removeEventListener("icen:ai-send", onSend);
|
|
2083
3636
|
composer.removeEventListener("icen:ai-stop", onStop);
|
|
2084
|
-
|
|
3637
|
+
messages.removeEventListener("icen:ai-retry", onRetry);
|
|
3638
|
+
onStop();
|
|
3639
|
+
retryable = null;
|
|
2085
3640
|
});
|
|
2086
3641
|
} else if (manageRunning) {
|
|
2087
3642
|
const onSend = () => setComposerRunning(composer, true);
|
|
2088
3643
|
const onDone = () => setComposerRunning(composer, false);
|
|
2089
3644
|
composer.addEventListener("icen:ai-send", onSend);
|
|
2090
|
-
|
|
3645
|
+
const target = opts.eventTarget ?? document;
|
|
3646
|
+
target.addEventListener("icen:ai-done", onDone);
|
|
2091
3647
|
disposers.push(() => {
|
|
2092
3648
|
composer.removeEventListener("icen:ai-send", onSend);
|
|
2093
|
-
|
|
3649
|
+
target.removeEventListener("icen:ai-done", onDone);
|
|
2094
3650
|
});
|
|
2095
3651
|
}
|
|
2096
3652
|
return {
|
|
3653
|
+
retry: () => retry(),
|
|
2097
3654
|
unbind() {
|
|
3655
|
+
if (!bound) return;
|
|
3656
|
+
bound = false;
|
|
2098
3657
|
for (const dispose of disposers) dispose();
|
|
2099
3658
|
disposers.length = 0;
|
|
2100
3659
|
BOUND.delete(composer);
|
|
@@ -2103,7 +3662,9 @@ function bindComposer(el, opts = {}) {
|
|
|
2103
3662
|
}
|
|
2104
3663
|
export {
|
|
2105
3664
|
bindComposer,
|
|
3665
|
+
getComposerDraft,
|
|
2106
3666
|
initAiComposer,
|
|
3667
|
+
openComposerLibrary,
|
|
2107
3668
|
registerRefKind,
|
|
2108
3669
|
setComposerCommands,
|
|
2109
3670
|
setComposerModels,
|