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