@ahggg/dsh-side-chat 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/README.zh-CN.md +2 -1
- package/lib/client/apply.d.ts.map +1 -1
- package/lib/client/apply.js +1 -1
- package/lib/client/apply.js.map +1 -1
- package/lib/client/contracts.d.ts +3 -1
- package/lib/client/contracts.d.ts.map +1 -1
- package/lib/client/index.d.ts +2 -2
- package/lib/client/index.d.ts.map +1 -1
- package/lib/client/index.js +1 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/model-preference.d.ts +14 -0
- package/lib/client/model-preference.d.ts.map +1 -0
- package/lib/client/model-preference.js +60 -0
- package/lib/client/model-preference.js.map +1 -0
- package/lib/client/panel/SelectionQuote.d.ts.map +1 -1
- package/lib/client/panel/SelectionQuote.js +26 -1
- package/lib/client/panel/SelectionQuote.js.map +1 -1
- package/lib/client/panel/SideChatModelSelect.d.ts +17 -0
- package/lib/client/panel/SideChatModelSelect.d.ts.map +1 -0
- package/lib/client/panel/SideChatModelSelect.js +247 -0
- package/lib/client/panel/SideChatModelSelect.js.map +1 -0
- package/lib/client/panel/SideChatPanel.d.ts +2 -1
- package/lib/client/panel/SideChatPanel.d.ts.map +1 -1
- package/lib/client/panel/SideChatPanel.js +3 -3
- package/lib/client/panel/SideChatPanel.js.map +1 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts.map +1 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.js +4 -2
- package/lib/client/parent-composer/ParentConversationAnnotations.js.map +1 -1
- package/lib/client/parent-composer/add-to-conversation.d.ts +16 -0
- package/lib/client/parent-composer/add-to-conversation.d.ts.map +1 -1
- package/lib/client/parent-composer/add-to-conversation.js +143 -17
- package/lib/client/parent-composer/add-to-conversation.js.map +1 -1
- package/lib/client/parent-composer/annotation-persistence.d.ts +19 -0
- package/lib/client/parent-composer/annotation-persistence.d.ts.map +1 -0
- package/lib/client/parent-composer/annotation-persistence.js +97 -0
- package/lib/client/parent-composer/annotation-persistence.js.map +1 -0
- package/lib/client/rc6/ArchivedConversation.d.ts +3 -1
- package/lib/client/rc6/ArchivedConversation.d.ts.map +1 -1
- package/lib/client/rc6/ArchivedConversation.js +61 -11
- package/lib/client/rc6/ArchivedConversation.js.map +1 -1
- package/lib/client/rc6/Rc6SideChatOverlay.d.ts.map +1 -1
- package/lib/client/rc6/Rc6SideChatOverlay.js +65 -5
- package/lib/client/rc6/Rc6SideChatOverlay.js.map +1 -1
- package/lib/client/rc6/context.d.ts +3 -1
- package/lib/client/rc6/context.d.ts.map +1 -1
- package/lib/client/rc6/remote-adapter.d.ts.map +1 -1
- package/lib/client/rc6/remote-adapter.js +4 -0
- package/lib/client/rc6/remote-adapter.js.map +1 -1
- package/lib/client/rc6/sessions-adapter.d.ts +16 -1
- package/lib/client/rc6/sessions-adapter.d.ts.map +1 -1
- package/lib/client/rc6/sessions-adapter.js +80 -16
- package/lib/client/rc6/sessions-adapter.js.map +1 -1
- package/lib/client/selection/ConversationAnnotationMarkers.d.ts +9 -0
- package/lib/client/selection/ConversationAnnotationMarkers.d.ts.map +1 -0
- package/lib/client/selection/ConversationAnnotationMarkers.js +241 -0
- package/lib/client/selection/ConversationAnnotationMarkers.js.map +1 -0
- package/lib/client/selection/SelectionActions.d.ts +6 -1
- package/lib/client/selection/SelectionActions.d.ts.map +1 -1
- package/lib/client/selection/SelectionActions.js +9 -8
- package/lib/client/selection/SelectionActions.js.map +1 -1
- package/lib/client/selection/selection-controller.d.ts +11 -0
- package/lib/client/selection/selection-controller.d.ts.map +1 -1
- package/lib/client/selection/selection-controller.js +54 -0
- package/lib/client/selection/selection-controller.js.map +1 -1
- package/lib/client/side-chat-controller.d.ts +3 -1
- package/lib/client/side-chat-controller.d.ts.map +1 -1
- package/lib/client/side-chat-controller.js +45 -1
- package/lib/client/side-chat-controller.js.map +1 -1
- package/lib/client.js +1392 -144
- package/lib/client.js.map +1 -1
- package/lib/host/archived-fork-service.d.ts +3 -1
- package/lib/host/archived-fork-service.d.ts.map +1 -1
- package/lib/host/archived-fork-service.js +80 -2
- package/lib/host/archived-fork-service.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/remote.d.ts +5 -2
- package/lib/remote.d.ts.map +1 -1
- package/lib/remote.js.map +1 -1
- package/lib/shared/archived-wire.d.ts +56 -0
- package/lib/shared/archived-wire.d.ts.map +1 -1
- package/lib/shared/archived-wire.js +17 -0
- package/lib/shared/archived-wire.js.map +1 -1
- package/lib/shared/contracts.d.ts +16 -0
- package/lib/shared/contracts.d.ts.map +1 -1
- package/lib/shared/error-codes.d.ts +1 -1
- package/lib/shared/error-codes.d.ts.map +1 -1
- package/lib/shared/error-codes.js +1 -0
- package/lib/shared/error-codes.js.map +1 -1
- package/lib/typert.d.ts +2 -2
- package/lib/typert.d.ts.map +1 -1
- package/lib/typert.js +14 -3
- package/lib/typert.js.map +1 -1
- package/package.json +6 -1
package/lib/client.js
CHANGED
|
@@ -8,7 +8,7 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
10
|
//#region \0dsh-side-chat-css:L2hvbWUvcnVubmVyL3dvcmsvZHNoLXNpZGUtY2hhdC9kc2gtc2lkZS1jaGF0L3NyYy9jbGllbnQvcGFuZWwvc2lkZS1jaGF0LmNzcw
|
|
11
|
-
var _dsh_side_chat_css_L2hvbWUvcnVubmVyL3dvcmsvZHNoLXNpZGUtY2hhdC9kc2gtc2lkZS1jaGF0L3NyYy9jbGllbnQvcGFuZWwvc2lkZS1jaGF0LmNzcw_default = ".dsh-side-chat-overlay {\n pointer-events: none;\n}\n\n.dsh-side-chat-overlay > * {\n pointer-events: auto;\n}\n\n.dsh-side-chat-panel {\n --side-chat-border: var(--dsw-border, #d8d8de);\n --side-chat-bg: var(--dsw-surface, #ffffff);\n --side-chat-muted: var(--dsw-text-muted, #62636a);\n position: fixed;\n z-index: 70;\n right: clamp(12px, 2vw, 20px);\n bottom: clamp(12px, 2vw, 20px);\n display: flex;\n width: min(840px, calc(100vw - 32px));\n height: clamp(460px, 62dvh, 980px);\n max-height: calc(100dvh - 32px);\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--side-chat-border);\n border-radius: 28px;\n background: var(--side-chat-bg);\n color: var(--dsw-text, #19191d);\n box-shadow: 0 12px 36px rgb(0 0 0 / 11%), 0 2px 8px rgb(0 0 0 / 6%);\n}\n\n.dsh-side-chat-conversation {\n display: flex;\n height: 100%;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n}\n\n.dsh-side-chat-transcript {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 12px;\n overflow-x: hidden;\n overflow-y: auto;\n padding: 18px 20px 24px;\n scrollbar-color: color-mix(in srgb, var(--side-chat-muted) 34%, transparent) transparent;\n scrollbar-width: thin;\n}\n\n.dsh-side-chat-message {\n max-width: 92%;\n padding: 10px 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 12px;\n background: var(--dsw-surface-subtle, #f7f7f9);\n}\n\n.dsh-side-chat-message[data-role=\"user\"] {\n align-self: end;\n background: var(--dsw-accent-soft, #eef4ff);\n}\n\n.dsh-side-chat-message[data-role=\"assistant\"] {\n align-self: start;\n min-width: 0;\n max-width: 100%;\n border-color: transparent;\n background: transparent;\n overflow-wrap: anywhere;\n}\n.dsh-side-chat-message-role,\n.dsh-side-chat-message-note { display: block; margin-bottom: 5px; color: var(--side-chat-muted); font-size: 12px; }\n.dsh-side-chat-message-text { white-space: pre-wrap; overflow-wrap: anywhere; }\n.dsh-side-chat-message pre,\n.dsh-side-chat-turn-notice pre { overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; }\n.dsh-side-chat-message[data-role=\"assistant\"] :where(table) {\n display: block;\n max-width: 100%;\n overflow-x: auto;\n}\n.dsh-side-chat-tool-branch {\n min-width: 0;\n max-width: 100%;\n flex: 0 0 auto;\n}\n.dsh-side-chat-tool {\n display: flex;\n min-width: 0;\n max-width: 100%;\n flex: 0 0 auto;\n flex-direction: column;\n border-radius: 6px;\n}\n.dsh-side-chat-tool-row {\n position: relative;\n overflow: hidden;\n}\n.dsh-side-chat-tool[data-state=\"running\"] .dsh-side-chat-tool-row::after,\n.dsh-side-chat-tool[data-state=\"pending\"] .dsh-side-chat-tool-row::after {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 300px;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 60%, transparent) 55%,\n transparent 100%\n );\n content: '';\n pointer-events: none;\n animation: dsh-side-chat-tool-sweep 2.6s ease-out infinite;\n}\n@keyframes dsh-side-chat-tool-sweep {\n 0% { left: -300px; }\n 90%, 100% { left: 100%; }\n}\n.dsh-side-chat-tool-row:focus-visible {\n border-radius: 4px;\n outline: 2px solid color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 42%, transparent);\n outline-offset: 1px;\n}\n.dsh-side-chat-tool-leading { flex-shrink: 0; }\n.dsh-side-chat-tool-chevron { color: var(--dsw-alias-label-secondary, var(--side-chat-muted)); }\n.dsh-side-chat-tool-title { font-weight: 400; }\n.dsh-side-chat-tool-separator {\n width: 2px;\n height: 2px;\n flex: none;\n margin: 0 8px;\n border-radius: 1px;\n background: var(--dsw-alias-label-caption, #a1a1aa);\n}\n.dsh-side-chat-tool-summary {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 14px;\n line-height: 24px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-tool-error-summary { color: var(--dsw-alias-state-error-primary, var(--dsw-danger, #b42318)); }\n.dsh-side-chat-tool-body-wrap {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n.dsh-side-chat-tool-code,\n.dsh-side-chat-tool-diff,\n.dsh-side-chat-tool-read,\n.dsh-side-chat-tool-search,\n.dsh-side-chat-tool-terminal,\n.dsh-side-chat-tool-web {\n margin: 4px 0 4px 4px;\n}\n.dsh-side-chat-tool-code { --dsl-code-block-content-font: var(--dsw-font-markdown-code-block-small); }\n.dsh-side-chat-tool-terminal {\n --dsl-terminal-font: var(--dsw-font-markdown-code-block-small);\n --dsl-terminal-line-height: 18px;\n --dsl-terminal-output-max-height: 224px;\n border: 1px solid var(--dsw-alias-border-l1, var(--side-chat-border));\n}\n.dsh-side-chat-tool-io-card {\n display: flex;\n flex-direction: column;\n margin: 4px 0 4px 4px;\n border: 1px solid var(--dsw-alias-border-l1, var(--side-chat-border));\n border-radius: 12px;\n background: var(--dsw-alias-markdown-code-block, #f6f6f7);\n font: var(--dsw-font-markdown-code-block-small, 12px/18px ui-monospace, SFMono-Regular, Consolas, monospace);\n}\n.dsh-side-chat-tool-io-section {\n display: grid;\n max-height: 150px;\n grid-template-columns: max-content minmax(0, 1fr);\n column-gap: 14px;\n align-items: baseline;\n overflow-y: auto;\n padding: 12px 16px;\n}\n.dsh-side-chat-tool-io-divider {\n height: 1px;\n flex: none;\n background: var(--dsw-alias-border-l2, var(--side-chat-border));\n}\n.dsh-side-chat-tool-io-label {\n position: sticky;\n top: 0;\n align-self: start;\n color: var(--dsw-alias-label-caption, #8d8d95);\n}\n.dsh-side-chat-tool-io-text {\n min-width: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--dsw-alias-label-secondary, #4b4b52);\n}\n.dsh-side-chat-tool-io-text[data-error] { color: var(--dsw-alias-state-error-primary, var(--dsw-danger, #b42318)); }\n.dsh-side-chat-tool-subcalls {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 4px 0 2px 22px;\n padding-left: 8px;\n border-left: 1px solid var(--dsw-alias-border-l2, var(--side-chat-border));\n}\n.dsh-side-chat-tool-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n.dsh-side-chat-turn-notice,\n.dsh-side-chat-interaction,\n.dsh-side-chat-queue { padding: 10px; border: 1px solid var(--side-chat-border); border-radius: 10px; }\n.dsh-side-chat-interaction fieldset { margin: 8px 0; border: 1px solid var(--side-chat-border); border-radius: 8px; }\n.dsh-side-chat-question-option { display: flex; gap: 8px; margin: 8px 0; }\n.dsh-side-chat-interaction textarea { width: 100%; box-sizing: border-box; resize: vertical; }\n.dsh-side-chat-interaction-actions,\n.dsh-side-chat-composer > div,\n.dsh-side-chat-queue > div { display: flex; justify-content: end; gap: 8px; }\n.dsh-side-chat-interaction button,\n.dsh-side-chat-composer button,\n.dsh-side-chat-queue button { min-height: 32px; border: 1px solid var(--side-chat-border); border-radius: 7px; background: var(--dsw-control, #f7f7f9); color: inherit; cursor: pointer; }\n.dsh-side-chat-composer {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 8px;\n align-items: end;\n margin: 0 12px 12px;\n padding: 8px 8px 8px 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 24px;\n background: var(--side-chat-bg);\n box-shadow: 0 2px 8px rgb(0 0 0 / 5%);\n}\n.dsh-side-chat-composer textarea {\n width: 100%;\n height: auto;\n min-height: 24px;\n max-height: 160px;\n box-sizing: border-box;\n resize: none;\n overflow-y: hidden;\n padding: 6px;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.5;\n}\n.dsh-side-chat-composer button { align-self: end; }\n.dsh-side-chat-loading { display: grid; height: 100%; place-items: center; color: var(--side-chat-muted); }\n\n.dsh-side-chat-header {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 8px 12px;\n align-items: center;\n flex: 0 0 auto;\n min-height: 46px;\n box-sizing: border-box;\n padding: 5px 10px 5px 16px;\n border-bottom: 1px solid var(--side-chat-border);\n background: var(--side-chat-bg);\n}\n\n.dsh-side-chat-heading { display: flex; min-width: 0; flex-direction: column; }\n.dsh-side-chat-heading strong { font-size: 14px; font-weight: 600; }\n.dsh-side-chat-footer { color: var(--side-chat-muted); font-size: 12px; }\n.dsh-side-chat-header button,\n.dsh-side-chat-inline-actions button,\n.dsh-side-chat-draft button,\n.dsh-side-chat-error button,\n.dsh-side-chat-selection-actions button {\n min-height: 32px;\n border: 1px solid var(--side-chat-border);\n border-radius: 7px;\n background: var(--dsw-control, #f7f7f9);\n color: inherit;\n cursor: pointer;\n}\n.dsh-side-chat-header button:disabled { cursor: not-allowed; opacity: .55; }\n.dsh-side-chat-header .dsh-side-chat-heading {\n align-items: flex-start;\n min-height: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n text-align: left;\n}\n.dsh-side-chat-header > button:last-child {\n width: 32px;\n min-height: 32px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n background: transparent;\n font-size: 20px;\n line-height: 1;\n}\n.dsh-side-chat-header > button:last-child:hover { background: var(--dsw-surface-subtle, #f3f3f5); }\n\n.dsh-side-chat-quote { position: relative; max-width: 100%; align-self: flex-start; }\n.dsh-side-chat-quote-chip {\n display: inline-flex;\n min-height: 36px;\n align-items: center;\n overflow: hidden;\n padding: 0;\n border: 1px solid var(--side-chat-border);\n border-radius: 999px;\n background: var(--side-chat-bg);\n transition: background-color 120ms ease;\n}\n.dsh-side-chat-quote:hover .dsh-side-chat-quote-chip,\n.dsh-side-chat-quote:focus-within .dsh-side-chat-quote-chip,\n.dsh-side-chat-quote[data-expanded] .dsh-side-chat-quote-chip { background: var(--dsw-surface-subtle, #f3f3f5); }\n.dsh-side-chat-quote-chip .dsh-side-chat-quote-trigger {\n display: inline-flex;\n min-height: 34px;\n align-items: center;\n gap: 8px;\n padding: 0 11px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n.dsh-side-chat-quote-trigger strong { font-size: 13px; font-weight: 500; line-height: 1; }\n.dsh-side-chat-quote-icon {\n width: 16px;\n height: 16px;\n flex: 0 0 auto;\n color: var(--side-chat-muted);\n fill: none;\n stroke: currentColor;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-width: 1.7;\n}\n.dsh-side-chat-quote-chip .dsh-side-chat-quote-remove {\n display: grid;\n width: 0;\n height: 34px;\n min-height: 34px;\n box-sizing: border-box;\n flex: 0 0 auto;\n place-items: center;\n overflow: hidden;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--side-chat-muted);\n cursor: pointer;\n font: inherit;\n font-size: 18px;\n line-height: 1;\n opacity: 0;\n pointer-events: none;\n transition: width 120ms ease, margin-left 120ms ease, opacity 100ms ease, background-color 100ms ease;\n}\n.dsh-side-chat-quote:hover .dsh-side-chat-quote-remove,\n.dsh-side-chat-quote:focus-within .dsh-side-chat-quote-remove {\n width: 30px;\n opacity: 1;\n pointer-events: auto;\n}\n.dsh-side-chat-quote-remove:hover { background: rgb(0 0 0 / 6%); color: inherit; }\n.dsh-side-chat-quote-details {\n position: absolute;\n z-index: 10;\n bottom: calc(100% + 8px);\n left: 0;\n width: min(520px, calc(100vw - 64px));\n max-width: calc(100vw - 48px);\n box-sizing: border-box;\n padding: 14px 16px;\n border: 1px solid var(--side-chat-border);\n border-radius: 16px;\n background: var(--side-chat-bg);\n box-shadow: 0 4px 14px rgb(0 0 0 / 8%);\n font-size: 14px;\n line-height: 1.45;\n opacity: 0;\n pointer-events: none;\n transform: translate(var(--dsh-side-chat-quote-offset-x, 0px), 4px);\n visibility: hidden;\n transition: opacity 100ms ease, transform 120ms ease, visibility 100ms ease;\n}\n.dsh-side-chat-quote-details::before {\n content: '';\n position: absolute;\n right: 0;\n bottom: -8px;\n left: 0;\n height: 8px;\n}\n.dsh-side-chat-quote:hover .dsh-side-chat-quote-details,\n.dsh-side-chat-quote[data-hovered] .dsh-side-chat-quote-details,\n.dsh-side-chat-quote:focus-within .dsh-side-chat-quote-details,\n.dsh-side-chat-quote[data-expanded] .dsh-side-chat-quote-details {\n opacity: 1;\n pointer-events: auto;\n transform: translate(var(--dsh-side-chat-quote-offset-x, 0px), 0);\n visibility: visible;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-quote-details {\n top: calc(100% + 8px);\n right: 0;\n bottom: auto;\n left: auto;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-quote-details::before {\n top: -8px;\n bottom: auto;\n}\n.dsh-side-chat-quote-details-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }\n.dsh-side-chat-quote-details-header strong { color: var(--side-chat-muted); font-size: 13px; font-weight: 500; }\n.dsh-side-chat-quote-detail + .dsh-side-chat-quote-detail {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--side-chat-border);\n}\n.dsh-side-chat-quote pre {\n max-height: 180px;\n margin: 4px 0 0;\n overflow: auto;\n white-space: pre-wrap;\n font: inherit;\n}\n.dsh-side-chat-quote-comment {\n margin-top: 9px;\n}\n.dsh-side-chat-quote-comment > strong { color: var(--side-chat-muted); font-size: 13px; font-weight: 500; }\n.dsh-side-chat-quote-comment > pre { margin-top: 4px; }\n.dsh-side-chat-error { margin: 10px 16px 0; padding: 10px 12px; border: 1px solid var(--side-chat-border); border-radius: 14px; background: var(--dsw-surface-subtle, #f7f7f9); }\n.dsh-side-chat-error { border-color: var(--dsw-danger, #b42318); }\n.dsh-side-chat-body { min-height: 0; flex: 1; overflow: hidden; }\n.dsh-side-chat-annotated-user-message {\n display: flex;\n max-width: 92%;\n align-self: end;\n align-items: flex-start;\n flex-direction: column;\n gap: 8px;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-message { max-width: 100%; align-self: stretch; }\n\n/* The DSH occurrence remains the durable serialization carrier, while this\n plugin-owned capsule supplies the visible and interactive projection. */\n[data-composer-seat] [data-decoration=\"chip\"][title=\"__dsh_side_chat_annotations__\"] {\n visibility: hidden;\n}\n.dsh-side-chat-parent-annotation-dock,\n.dsh-side-chat-parent-user-message {\n --side-chat-border: var(--dsw-border, #d8d8de);\n --side-chat-bg: var(--dsw-surface, #ffffff);\n --side-chat-muted: var(--dsw-text-muted, #62636a);\n color: var(--dsw-text, #19191d);\n}\n.dsh-side-chat-parent-annotation-dock {\n position: relative;\n z-index: 20;\n width: calc(100% - 32px);\n max-width: var(--dsh-composer-card-max-width, 780px);\n height: 0;\n margin: 0 auto;\n pointer-events: none;\n}\n.dsh-side-chat-parent-annotation-dock > .dsh-side-chat-quote {\n position: absolute;\n top: 16px;\n left: 16px;\n pointer-events: auto;\n}\n.dsh-side-chat-parent-user-message {\n display: flex;\n width: 100%;\n flex-direction: column;\n align-items: flex-end;\n gap: 8px;\n}\n.dsh-side-chat-parent-user-message > .dsh-side-chat-quote { align-self: flex-end; }\n.dsh-side-chat-parent-user-message > .dsh-side-chat-quote .dsh-side-chat-quote-details {\n right: 0;\n left: auto;\n}\n.dsh-side-chat-draft {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n min-height: 0;\n flex: 0 0 auto;\n gap: 8px;\n align-items: end;\n margin: auto 12px 12px;\n padding: 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 24px;\n background: var(--side-chat-bg);\n box-shadow: 0 2px 8px rgb(0 0 0 / 5%);\n}\n.dsh-side-chat-draft > .dsh-side-chat-quote { grid-column: 1 / -1; }\n.dsh-side-chat-draft label {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n}\n.dsh-side-chat-draft textarea {\n width: 100%;\n height: auto;\n min-height: 24px;\n max-height: 160px;\n box-sizing: border-box;\n resize: none;\n overflow-y: hidden;\n padding: 6px 2px;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.5;\n}\n.dsh-side-chat-draft > button { align-self: end; }\n.dsh-side-chat-panel .dsh-side-chat-send-button,\n.dsh-side-chat-panel .dsh-side-chat-stop-button {\n display: grid;\n width: 34px;\n height: 34px;\n min-height: 34px;\n flex: none;\n place-items: center;\n padding: 1px 6px;\n border: 0;\n border-radius: 999px;\n background: var(--dsw-alias-button-info-fill, #4176e6);\n color: #fff;\n cursor: pointer;\n line-height: 1;\n transform: translateY(-2px);\n transition: background-color 100ms ease;\n}\n.dsh-side-chat-panel .dsh-side-chat-send-button:hover:not(:disabled),\n.dsh-side-chat-panel .dsh-side-chat-stop-button:hover:not(:disabled) {\n background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n.dsh-side-chat-panel .dsh-side-chat-send-button:disabled,\n.dsh-side-chat-panel .dsh-side-chat-stop-button:disabled { cursor: default; opacity: .4; }\n.dsh-side-chat-footer { display: none; }\n.dsh-side-chat-announcer { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n\n.dsh-side-chat-selection-actions {\n position: fixed;\n z-index: 90;\n display: flex;\n max-width: calc(100vw - 16px);\n flex-wrap: wrap;\n gap: 0;\n padding: 0;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 999px;\n background: var(--dsw-surface, #fff);\n box-shadow: 0 4px 14px rgb(0 0 0 / 12%);\n overflow: hidden;\n}\n.dsh-side-chat-selection-actions button {\n min-height: 36px;\n padding: 0 14px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n transition: background-color 120ms ease;\n}\n.dsh-side-chat-selection-actions button:hover:not(:disabled),\n.dsh-side-chat-selection-actions button:focus-visible {\n background: var(--dsw-surface-subtle, #f3f3f5);\n}\n.dsh-side-chat-selection-actions button + button {\n border-left: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 0;\n}\n\n.dsh-side-chat-selection-marker {\n position: fixed;\n z-index: 91;\n display: grid;\n width: 28px;\n height: 28px;\n place-items: center;\n border: 2px solid var(--dsw-surface, #fff);\n border-radius: 999px;\n background: var(--dsw-alias-button-info, #1473e6);\n box-shadow: 0 2px 6px rgb(0 0 0 / 12%);\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n line-height: 1;\n pointer-events: none;\n}\n\n.dsh-side-chat-selection-comment {\n position: fixed;\n z-index: 92;\n display: grid;\n max-width: calc(100vw - 16px);\n box-sizing: border-box;\n gap: 10px;\n padding: 12px;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 20px;\n background: var(--dsw-surface, #fff);\n box-shadow: 0 5px 18px rgb(0 0 0 / 9%);\n color: var(--dsw-text, #19191d);\n}\n.dsh-side-chat-selection-comment textarea {\n width: 100%;\n min-height: 48px;\n max-height: 128px;\n box-sizing: border-box;\n resize: none;\n padding: 6px 8px;\n overflow-y: auto;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.45;\n}\n.dsh-side-chat-selection-comment-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.dsh-side-chat-selection-comment-actions button {\n min-height: 32px;\n padding: 0 14px;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 999px;\n background: var(--dsw-surface, #fff);\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n.dsh-side-chat-selection-comment-actions button:hover { background: var(--dsw-surface-subtle, #f3f3f5); }\n.dsh-side-chat-selection-comment-actions .dsh-side-chat-selection-comment-save {\n border-color: transparent;\n background: var(--dsw-alias-button-info, #1473e6);\n color: #fff;\n}\n.dsh-side-chat-selection-comment-actions .dsh-side-chat-selection-comment-save:hover {\n background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n\n@media (max-width: 900px) {\n .dsh-side-chat-panel {\n right: 12px;\n bottom: 12px;\n width: calc(100vw - 24px);\n max-height: calc(100dvh - 24px);\n border-radius: 24px;\n }\n}\n\n@media (max-width: 720px) {\n .dsh-side-chat-panel {\n right: 8px;\n bottom: 8px;\n width: calc(100vw - 16px);\n height: min(78dvh, 760px);\n max-height: calc(100dvh - 16px);\n border-radius: 22px;\n }\n .dsh-side-chat-transcript { padding: 14px 14px 20px; }\n .dsh-side-chat-header { padding-left: 14px; }\n .dsh-side-chat-error { margin-inline: 12px; }\n}\n\n@media (max-height: 620px) {\n .dsh-side-chat-panel {\n bottom: 8px;\n height: calc(100dvh - 16px);\n max-height: calc(100dvh - 16px);\n }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .dsh-side-chat-panel { animation: dsh-side-chat-enter 160ms ease-out; }\n @keyframes dsh-side-chat-enter { from { transform: translateY(18px) scale(.985); opacity: .7; } }\n}\n\n@media (forced-colors: active) {\n.dsh-side-chat-panel,\n.dsh-side-chat-selection-actions,\n.dsh-side-chat-selection-comment { border: 1px solid CanvasText; }\n}\n";
|
|
11
|
+
var _dsh_side_chat_css_L2hvbWUvcnVubmVyL3dvcmsvZHNoLXNpZGUtY2hhdC9kc2gtc2lkZS1jaGF0L3NyYy9jbGllbnQvcGFuZWwvc2lkZS1jaGF0LmNzcw_default = ".dsh-side-chat-overlay {\n pointer-events: none;\n}\n\n.dsh-side-chat-overlay > * {\n pointer-events: auto;\n}\n\n.dsh-side-chat-panel {\n --side-chat-border: var(--dsw-border, #d8d8de);\n --side-chat-bg: var(--dsw-surface, #ffffff);\n --side-chat-muted: var(--dsw-text-muted, #62636a);\n position: fixed;\n z-index: 70;\n right: clamp(12px, 2vw, 20px);\n bottom: clamp(12px, 2vw, 20px);\n display: flex;\n width: min(840px, calc(100vw - 32px));\n height: clamp(460px, 62dvh, 980px);\n max-height: calc(100dvh - 32px);\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--side-chat-border);\n border-radius: 28px;\n background: var(--side-chat-bg);\n color: var(--dsw-text, #19191d);\n box-shadow: 0 12px 36px rgb(0 0 0 / 11%), 0 2px 8px rgb(0 0 0 / 6%);\n}\n\n.dsh-side-chat-conversation {\n display: flex;\n height: 100%;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n}\n\n.dsh-side-chat-transcript {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 12px;\n overflow-x: hidden;\n overflow-y: auto;\n padding: 18px 20px 24px;\n scrollbar-color: color-mix(in srgb, var(--side-chat-muted) 34%, transparent) transparent;\n scrollbar-width: thin;\n}\n\n.dsh-side-chat-message {\n max-width: 92%;\n padding: 10px 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 12px;\n background: var(--dsw-surface-subtle, #f7f7f9);\n}\n\n.dsh-side-chat-message[data-role=\"user\"] {\n align-self: end;\n background: var(--dsw-accent-soft, #eef4ff);\n}\n\n.dsh-side-chat-message[data-role=\"assistant\"] {\n align-self: start;\n min-width: 0;\n max-width: 100%;\n border-color: transparent;\n background: transparent;\n overflow-wrap: anywhere;\n}\n.dsh-side-chat-message-role,\n.dsh-side-chat-message-note { display: block; margin-bottom: 5px; color: var(--side-chat-muted); font-size: 12px; }\n.dsh-side-chat-message-text { white-space: pre-wrap; overflow-wrap: anywhere; }\n.dsh-side-chat-message pre,\n.dsh-side-chat-turn-notice pre { overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; }\n.dsh-side-chat-message[data-role=\"assistant\"] :where(table) {\n display: block;\n max-width: 100%;\n overflow-x: auto;\n}\n.dsh-side-chat-reasoning {\n display: flex;\n flex-direction: column;\n}\n.dsh-side-chat-reasoning-row {\n position: relative;\n overflow: hidden;\n}\n.dsh-side-chat-reasoning[data-state=\"running\"] .dsh-side-chat-reasoning-row::after {\n position: absolute;\n inset-block: 0;\n left: 0;\n width: 300px;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 60%, transparent) 55%,\n transparent 100%\n );\n content: '';\n pointer-events: none;\n animation: dsh-side-chat-reasoning-sweep 2.6s ease-out infinite;\n}\n@keyframes dsh-side-chat-reasoning-sweep {\n 0% { left: -300px; }\n 90%, 100% { left: 100%; }\n}\n.dsh-side-chat-reasoning-leading { flex-shrink: 0; }\n.dsh-side-chat-reasoning-chevron { color: var(--dsw-alias-label-secondary, var(--side-chat-muted)); }\n.dsh-side-chat-reasoning-title { font-weight: 400; }\n.dsh-side-chat-reasoning-separator {\n width: 2px;\n height: 2px;\n flex: none;\n margin: 0 8px;\n border-radius: 1px;\n background: var(--dsw-alias-label-caption, #a1a1aa);\n}\n.dsh-side-chat-reasoning-summary {\n min-width: 0;\n flex: auto;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 14px;\n line-height: 24px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-reasoning-summary[data-follow-end] { text-overflow: clip; }\n.dsh-side-chat-reasoning-body {\n padding: 4px 0 4px 22px;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 14px;\n line-height: 24px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.dsh-side-chat-reasoning-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n.dsh-side-chat-tool-branch {\n min-width: 0;\n max-width: 100%;\n flex: 0 0 auto;\n}\n.dsh-side-chat-tool {\n display: flex;\n min-width: 0;\n max-width: 100%;\n flex: 0 0 auto;\n flex-direction: column;\n border-radius: 6px;\n}\n.dsh-side-chat-tool-row {\n position: relative;\n overflow: hidden;\n}\n.dsh-side-chat-tool[data-state=\"running\"] .dsh-side-chat-tool-row::after,\n.dsh-side-chat-tool[data-state=\"pending\"] .dsh-side-chat-tool-row::after {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 300px;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 60%, transparent) 55%,\n transparent 100%\n );\n content: '';\n pointer-events: none;\n animation: dsh-side-chat-tool-sweep 2.6s ease-out infinite;\n}\n@keyframes dsh-side-chat-tool-sweep {\n 0% { left: -300px; }\n 90%, 100% { left: 100%; }\n}\n.dsh-side-chat-tool-row:focus-visible {\n border-radius: 4px;\n outline: 2px solid color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 42%, transparent);\n outline-offset: 1px;\n}\n.dsh-side-chat-tool-leading { flex-shrink: 0; }\n.dsh-side-chat-tool-chevron { color: var(--dsw-alias-label-secondary, var(--side-chat-muted)); }\n.dsh-side-chat-tool-title { font-weight: 400; }\n.dsh-side-chat-tool-separator {\n width: 2px;\n height: 2px;\n flex: none;\n margin: 0 8px;\n border-radius: 1px;\n background: var(--dsw-alias-label-caption, #a1a1aa);\n}\n.dsh-side-chat-tool-summary {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 14px;\n line-height: 24px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-tool-error-summary { color: var(--dsw-alias-state-error-primary, var(--dsw-danger, #b42318)); }\n.dsh-side-chat-tool-body-wrap {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n.dsh-side-chat-tool-code,\n.dsh-side-chat-tool-diff,\n.dsh-side-chat-tool-read,\n.dsh-side-chat-tool-search,\n.dsh-side-chat-tool-terminal,\n.dsh-side-chat-tool-web {\n margin: 4px 0 4px 4px;\n}\n.dsh-side-chat-tool-code { --dsl-code-block-content-font: var(--dsw-font-markdown-code-block-small); }\n.dsh-side-chat-tool-terminal {\n --dsl-terminal-font: var(--dsw-font-markdown-code-block-small);\n --dsl-terminal-line-height: 18px;\n --dsl-terminal-output-max-height: 224px;\n border: 1px solid var(--dsw-alias-border-l1, var(--side-chat-border));\n}\n.dsh-side-chat-tool-io-card {\n display: flex;\n flex-direction: column;\n margin: 4px 0 4px 4px;\n border: 1px solid var(--dsw-alias-border-l1, var(--side-chat-border));\n border-radius: 12px;\n background: var(--dsw-alias-markdown-code-block, #f6f6f7);\n font: var(--dsw-font-markdown-code-block-small, 12px/18px ui-monospace, SFMono-Regular, Consolas, monospace);\n}\n.dsh-side-chat-tool-io-section {\n display: grid;\n max-height: 150px;\n grid-template-columns: max-content minmax(0, 1fr);\n column-gap: 14px;\n align-items: baseline;\n overflow-y: auto;\n padding: 12px 16px;\n}\n.dsh-side-chat-tool-io-divider {\n height: 1px;\n flex: none;\n background: var(--dsw-alias-border-l2, var(--side-chat-border));\n}\n.dsh-side-chat-tool-io-label {\n position: sticky;\n top: 0;\n align-self: start;\n color: var(--dsw-alias-label-caption, #8d8d95);\n}\n.dsh-side-chat-tool-io-text {\n min-width: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--dsw-alias-label-secondary, #4b4b52);\n}\n.dsh-side-chat-tool-io-text[data-error] { color: var(--dsw-alias-state-error-primary, var(--dsw-danger, #b42318)); }\n.dsh-side-chat-tool-subcalls {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 4px 0 2px 22px;\n padding-left: 8px;\n border-left: 1px solid var(--dsw-alias-border-l2, var(--side-chat-border));\n}\n.dsh-side-chat-tool-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n.dsh-side-chat-turn-notice,\n.dsh-side-chat-interaction,\n.dsh-side-chat-queue { padding: 10px; border: 1px solid var(--side-chat-border); border-radius: 10px; }\n.dsh-side-chat-interaction fieldset { margin: 8px 0; border: 1px solid var(--side-chat-border); border-radius: 8px; }\n.dsh-side-chat-question-option { display: flex; gap: 8px; margin: 8px 0; }\n.dsh-side-chat-interaction textarea { width: 100%; box-sizing: border-box; resize: vertical; }\n.dsh-side-chat-interaction-actions,\n.dsh-side-chat-queue > div { display: flex; justify-content: end; gap: 8px; }\n.dsh-side-chat-interaction button,\n.dsh-side-chat-queue button { min-height: 32px; border: 1px solid var(--side-chat-border); border-radius: 7px; background: var(--dsw-control, #f7f7f9); color: inherit; cursor: pointer; }\n.dsh-side-chat-composer {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: 6px;\n align-items: end;\n margin: 0 12px 12px;\n padding: 8px 8px 8px 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 24px;\n background: var(--side-chat-bg);\n box-shadow: 0 2px 8px rgb(0 0 0 / 5%);\n}\n.dsh-side-chat-composer textarea {\n grid-column: 1 / -1;\n width: 100%;\n height: auto;\n min-height: 24px;\n max-height: 160px;\n box-sizing: border-box;\n resize: none;\n overflow-y: hidden;\n padding: 6px;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.5;\n}\n.dsh-side-chat-composer-actions,\n.dsh-side-chat-draft-actions {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n}\n.dsh-side-chat-model-root {\n position: relative;\n min-width: 0;\n}\n.dsh-side-chat-model-trigger {\n display: flex;\n width: auto;\n height: 28px;\n min-height: 28px;\n max-width: 220px;\n align-items: center;\n gap: 4px;\n padding: 0 4px 0 8px;\n border: 0;\n border-radius: 24px;\n outline: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary, var(--side-chat-muted));\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n}\n.dsh-side-chat-model-trigger:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, var(--dsw-surface-subtle, #f3f3f5));\n}\n.dsh-side-chat-model-trigger:focus-visible {\n box-shadow: 0 0 0 2px var(--dsw-alias-border-l3, var(--side-chat-border));\n}\n.dsh-side-chat-model-trigger:disabled {\n color: var(--dsw-alias-label-dimmed, #a1a1aa);\n cursor: default;\n}\n.dsh-side-chat-model-trigger-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-model-trigger-effort {\n flex: none;\n color: var(--dsw-alias-label-caption, #8d8d95);\n}\n.dsh-side-chat-model-chevron {\n flex: none;\n color: var(--dsw-alias-label-caption, #8d8d95);\n transition: transform 120ms ease;\n}\n.dsh-side-chat-model-chevron-open { transform: rotate(180deg); }\n.dsh-side-chat-model-menu {\n position: absolute;\n z-index: 20;\n right: 0;\n bottom: calc(100% + 8px);\n display: flex;\n width: min(240px, calc(100vw - 32px));\n max-height: min(360px, calc(100dvh - 96px));\n flex-direction: column;\n overflow: hidden;\n padding: 4px;\n border: 1px solid var(--dsw-alias-border-inverted, var(--side-chat-border));\n border-radius: 12px;\n background: var(--dsw-specific-menu, var(--side-chat-bg));\n box-shadow: var(--dsw-shadow-lv3, 0 8px 24px rgb(0 0 0 / 16%));\n color: var(--dsw-alias-label-primary, inherit);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2, #a1a1aa);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2, #71717a);\n}\n.dsh-side-chat-model-status,\n.dsh-side-chat-model-empty {\n padding: 10px;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 13px;\n line-height: 20px;\n}\n.dsh-side-chat-model-error,\n.dsh-side-chat-model-warning {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 4px;\n padding: 7px 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover-danger, #fff1f0);\n color: var(--dsw-alias-state-error-primary, var(--dsw-danger, #b42318));\n font-size: 12px;\n line-height: 18px;\n}\n.dsh-side-chat-model-warning {\n background: var(--dsw-alias-bg-module-platform, #fff8e6);\n color: var(--dsw-alias-state-warn-label, #8a5a00);\n}\n.dsh-side-chat-model-retry {\n min-height: 0;\n flex: none;\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n font-weight: 600;\n}\n.dsh-side-chat-model-groups {\n min-height: 0;\n overflow-y: auto;\n}\n.dsh-side-chat-model-group + .dsh-side-chat-model-group { margin-top: 4px; }\n.dsh-side-chat-model-group-title {\n position: sticky;\n z-index: 1;\n top: 0;\n padding: 5px 8px 3px;\n background: var(--dsw-specific-menu, var(--side-chat-bg));\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n.dsh-side-chat-model-option {\n display: flex;\n width: 100%;\n min-height: 38px;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border: 0;\n border-radius: 10px;\n outline: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n text-align: left;\n}\n.dsh-side-chat-model-option:hover:not(:disabled),\n.dsh-side-chat-model-option:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover, var(--dsw-surface-subtle, #f3f3f5));\n}\n.dsh-side-chat-model-selected { background: transparent; }\n.dsh-side-chat-model-option:disabled {\n color: var(--dsw-alias-label-dimmed, #a1a1aa);\n cursor: default;\n}\n.dsh-side-chat-model-option-copy {\n display: flex;\n min-width: 0;\n flex: 1;\n flex-direction: column;\n}\n.dsh-side-chat-model-name {\n overflow: hidden;\n color: inherit;\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-model-description {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n font-size: 12px;\n line-height: 18px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-model-check {\n display: grid;\n flex: 0 0 18px;\n place-items: center;\n color: var(--dsw-alias-label-primary, inherit);\n}\n.dsh-side-chat-model-cell {\n display: flex;\n width: 100%;\n height: 40px;\n align-items: center;\n gap: 8px;\n padding: 0 10px;\n border: 0;\n border-radius: 10px;\n background: transparent;\n color: var(--dsw-alias-label-primary, inherit);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n text-align: left;\n}\n.dsh-side-chat-model-cell:hover {\n background: var(--dsw-alias-interactive-bg-hover, var(--dsw-surface-subtle, #f3f3f5));\n}\n.dsh-side-chat-model-cell-label {\n min-width: 0;\n flex: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-model-cell-value {\n min-width: 0;\n flex: 0 auto;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-side-chat-model-cell-chevron {\n flex: none;\n color: var(--dsw-alias-label-tertiary, var(--side-chat-muted));\n}\n.dsh-side-chat-loading { display: grid; height: 100%; place-items: center; color: var(--side-chat-muted); }\n\n.dsh-side-chat-header {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 8px 12px;\n align-items: center;\n flex: 0 0 auto;\n min-height: 46px;\n box-sizing: border-box;\n padding: 5px 10px 5px 16px;\n border-bottom: 1px solid var(--side-chat-border);\n background: var(--side-chat-bg);\n}\n\n.dsh-side-chat-heading { display: flex; min-width: 0; flex-direction: column; }\n.dsh-side-chat-heading strong { font-size: 14px; font-weight: 600; }\n.dsh-side-chat-footer { color: var(--side-chat-muted); font-size: 12px; }\n.dsh-side-chat-header button,\n.dsh-side-chat-inline-actions button,\n.dsh-side-chat-error button,\n.dsh-side-chat-selection-actions button {\n min-height: 32px;\n border: 1px solid var(--side-chat-border);\n border-radius: 7px;\n background: var(--dsw-control, #f7f7f9);\n color: inherit;\n cursor: pointer;\n}\n.dsh-side-chat-header button:disabled { cursor: not-allowed; opacity: .55; }\n.dsh-side-chat-header .dsh-side-chat-heading {\n align-items: flex-start;\n min-height: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n text-align: left;\n}\n.dsh-side-chat-header > button:last-child {\n width: 32px;\n min-height: 32px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n background: transparent;\n font-size: 20px;\n line-height: 1;\n}\n.dsh-side-chat-header > button:last-child:hover { background: var(--dsw-surface-subtle, #f3f3f5); }\n\n.dsh-side-chat-quote { position: relative; max-width: 100%; align-self: flex-start; }\n.dsh-side-chat-quote-chip {\n display: inline-flex;\n min-height: 36px;\n align-items: center;\n overflow: hidden;\n padding: 0;\n border: 1px solid var(--side-chat-border);\n border-radius: 999px;\n background: var(--side-chat-bg);\n transition: background-color 120ms ease;\n}\n.dsh-side-chat-quote:hover .dsh-side-chat-quote-chip,\n.dsh-side-chat-quote:focus-within .dsh-side-chat-quote-chip,\n.dsh-side-chat-quote[data-expanded] .dsh-side-chat-quote-chip { background: var(--dsw-surface-subtle, #f3f3f5); }\n.dsh-side-chat-quote-chip .dsh-side-chat-quote-trigger {\n display: inline-flex;\n min-height: 34px;\n align-items: center;\n gap: 8px;\n padding: 0 11px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n.dsh-side-chat-quote-trigger strong { font-size: 13px; font-weight: 500; line-height: 1; }\n.dsh-side-chat-quote-icon {\n width: 16px;\n height: 16px;\n flex: 0 0 auto;\n color: var(--side-chat-muted);\n fill: none;\n stroke: currentColor;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-width: 1.7;\n}\n.dsh-side-chat-quote-chip .dsh-side-chat-quote-remove {\n display: grid;\n width: 0;\n height: 34px;\n min-height: 34px;\n box-sizing: border-box;\n flex: 0 0 auto;\n place-items: center;\n overflow: hidden;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--side-chat-muted);\n cursor: pointer;\n font: inherit;\n font-size: 18px;\n line-height: 1;\n opacity: 0;\n pointer-events: none;\n transition: width 120ms ease, margin-left 120ms ease, opacity 100ms ease, background-color 100ms ease;\n}\n.dsh-side-chat-quote:hover .dsh-side-chat-quote-remove,\n.dsh-side-chat-quote:focus-within .dsh-side-chat-quote-remove {\n width: 30px;\n opacity: 1;\n pointer-events: auto;\n}\n.dsh-side-chat-quote-remove:hover { background: rgb(0 0 0 / 6%); color: inherit; }\n.dsh-side-chat-quote-details {\n position: absolute;\n z-index: 10;\n bottom: calc(100% + 8px);\n left: 0;\n width: min(520px, calc(100vw - 64px));\n max-width: calc(100vw - 48px);\n box-sizing: border-box;\n padding: 14px 16px;\n border: 1px solid var(--side-chat-border);\n border-radius: 16px;\n background: var(--side-chat-bg);\n box-shadow: 0 4px 14px rgb(0 0 0 / 8%);\n font-size: 14px;\n line-height: 1.45;\n opacity: 0;\n pointer-events: none;\n transform: translate(var(--dsh-side-chat-quote-offset-x, 0px), 4px);\n visibility: hidden;\n transition: opacity 100ms ease, transform 120ms ease, visibility 100ms ease;\n}\n.dsh-side-chat-quote-details::before {\n content: '';\n position: absolute;\n right: 0;\n bottom: -8px;\n left: 0;\n height: 8px;\n}\n.dsh-side-chat-quote[data-hovered] .dsh-side-chat-quote-details,\n.dsh-side-chat-quote[data-expanded] .dsh-side-chat-quote-details {\n opacity: 1;\n pointer-events: auto;\n transform: translate(var(--dsh-side-chat-quote-offset-x, 0px), 0);\n visibility: visible;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-quote-details {\n top: calc(100% + 8px);\n right: 0;\n bottom: auto;\n left: auto;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-quote-details::before {\n top: -8px;\n bottom: auto;\n}\n.dsh-side-chat-quote-details-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }\n.dsh-side-chat-quote-details-header strong { color: var(--side-chat-muted); font-size: 13px; font-weight: 500; }\n.dsh-side-chat-quote-detail + .dsh-side-chat-quote-detail {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--side-chat-border);\n}\n.dsh-side-chat-quote pre {\n max-height: 180px;\n margin: 4px 0 0;\n overflow: auto;\n white-space: pre-wrap;\n font: inherit;\n}\n.dsh-side-chat-quote-comment {\n margin-top: 9px;\n}\n.dsh-side-chat-quote-comment > strong { color: var(--side-chat-muted); font-size: 13px; font-weight: 500; }\n.dsh-side-chat-quote-comment > pre { margin-top: 4px; }\n.dsh-side-chat-error { margin: 10px 16px 0; padding: 10px 12px; border: 1px solid var(--side-chat-border); border-radius: 14px; background: var(--dsw-surface-subtle, #f7f7f9); }\n.dsh-side-chat-error { border-color: var(--dsw-danger, #b42318); }\n.dsh-side-chat-body { min-height: 0; flex: 1; overflow: hidden; }\n.dsh-side-chat-annotated-user-message {\n display: flex;\n max-width: 92%;\n align-self: end;\n align-items: flex-start;\n flex-direction: column;\n gap: 8px;\n}\n.dsh-side-chat-annotated-user-message .dsh-side-chat-message { max-width: 100%; align-self: stretch; }\n\n/* The DSH occurrence remains the durable serialization carrier, while this\n plugin-owned capsule supplies the visible and interactive projection. */\n[data-composer-seat] [data-decoration=\"chip\"][title=\"__dsh_side_chat_annotations__\"] {\n visibility: hidden;\n}\n.dsh-side-chat-parent-annotation-dock,\n.dsh-side-chat-parent-user-message {\n --side-chat-border: var(--dsw-border, #d8d8de);\n --side-chat-bg: var(--dsw-surface, #ffffff);\n --side-chat-muted: var(--dsw-text-muted, #62636a);\n color: var(--dsw-text, #19191d);\n}\n.dsh-side-chat-parent-annotation-dock {\n position: relative;\n z-index: 20;\n width: calc(100% - 32px);\n max-width: var(--dsh-composer-card-max-width, 780px);\n height: 0;\n /* The terminal zero-height dock would otherwise add a second gap between\n Todo/Goal/Queue and the input card. Its child still lands 10px inside the\n following card: -gap + top:16px against the card's own 6px gap. */\n margin: calc(0px - var(--dsh-composer-stack-gap, 6px)) auto 0;\n pointer-events: none;\n}\n.dsh-side-chat-parent-annotation-dock > .dsh-side-chat-quote {\n position: absolute;\n top: 16px;\n left: 16px;\n pointer-events: auto;\n}\n.dsh-side-chat-parent-user-message {\n display: flex;\n width: 100%;\n min-width: 0;\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n}\n.dsh-side-chat-parent-user-message > .dsh-side-chat-quote { align-self: flex-end; }\n/* rc.6 caps its inner user stack at 82%; give that percentage the full chat\n column as its containing width instead of the annotation chip's shrink width. */\n.dsh-side-chat-parent-user-message-body { width: 100%; min-width: 0; }\n.dsh-side-chat-parent-user-message > .dsh-side-chat-quote .dsh-side-chat-quote-details {\n right: 0;\n left: auto;\n}\n.dsh-side-chat-draft {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n min-height: 0;\n flex: 0 0 auto;\n gap: 6px;\n align-items: end;\n margin: auto 12px 12px;\n padding: 12px;\n border: 1px solid var(--side-chat-border);\n border-radius: 24px;\n background: var(--side-chat-bg);\n box-shadow: 0 2px 8px rgb(0 0 0 / 5%);\n}\n.dsh-side-chat-draft > .dsh-side-chat-quote { grid-column: 1 / -1; }\n.dsh-side-chat-draft label {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n}\n.dsh-side-chat-draft textarea {\n grid-column: 1 / -1;\n width: 100%;\n height: auto;\n min-height: 24px;\n max-height: 160px;\n box-sizing: border-box;\n resize: none;\n overflow-y: hidden;\n padding: 6px 2px;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.5;\n}\n.dsh-side-chat-panel .dsh-side-chat-send-button,\n.dsh-side-chat-panel .dsh-side-chat-stop-button {\n display: grid;\n width: 34px;\n height: 34px;\n min-height: 34px;\n flex: none;\n place-items: center;\n padding: 1px 6px;\n border: 0;\n border-radius: 999px;\n background: var(--dsw-alias-button-info-fill, #4176e6);\n color: #fff;\n cursor: pointer;\n line-height: 1;\n transform: translateY(-2px);\n transition: background-color 100ms ease;\n}\n.dsh-side-chat-panel .dsh-side-chat-send-button:hover:not(:disabled),\n.dsh-side-chat-panel .dsh-side-chat-stop-button:hover:not(:disabled) {\n background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n.dsh-side-chat-panel .dsh-side-chat-send-button:disabled,\n.dsh-side-chat-panel .dsh-side-chat-stop-button:disabled { cursor: default; opacity: .4; }\n.dsh-side-chat-footer { display: none; }\n.dsh-side-chat-announcer { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n\n.dsh-side-chat-selection-actions {\n position: fixed;\n z-index: 90;\n display: flex;\n max-width: calc(100vw - 16px);\n flex-wrap: wrap;\n gap: 0;\n padding: 0;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 999px;\n background: var(--dsw-surface, #fff);\n box-shadow: 0 4px 14px rgb(0 0 0 / 12%);\n overflow: hidden;\n}\n.dsh-side-chat-selection-actions button {\n min-height: 36px;\n padding: 0 14px;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n transition: background-color 120ms ease;\n}\n.dsh-side-chat-selection-actions button:hover:not(:disabled),\n.dsh-side-chat-selection-actions button:focus-visible {\n background: var(--dsw-surface-subtle, #f3f3f5);\n}\n.dsh-side-chat-selection-actions button + button {\n border-left: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 0;\n}\n\n::highlight(dsh-side-chat-annotations) {\n background: color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 18%, transparent);\n}\n::highlight(dsh-side-chat-active-annotation) {\n background: color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 32%, transparent);\n text-decoration: underline;\n text-decoration-color: color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 70%, transparent);\n text-decoration-thickness: 1px;\n}\n\n.dsh-side-chat-annotation-marker,\n.dsh-side-chat-selection-marker {\n position: fixed;\n z-index: 91;\n display: grid;\n width: 22px;\n height: 22px;\n min-height: 22px;\n box-sizing: border-box;\n place-items: center;\n padding: 0;\n border: 0;\n border-radius: 999px;\n background: var(--dsw-alias-button-info, #1473e6);\n box-shadow: 0 2px 6px rgb(0 0 0 / 14%);\n color: #fff;\n font: inherit;\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n}\n.dsh-side-chat-annotation-marker { cursor: pointer; }\n.dsh-side-chat-selection-marker { pointer-events: none; }\n.dsh-side-chat-annotation-marker[data-large],\n.dsh-side-chat-selection-marker[data-large] { font-size: 9px; }\n.dsh-side-chat-annotation-marker[data-active] {\n background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n.dsh-side-chat-annotation-marker:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--dsw-alias-button-info, #1473e6) 32%, transparent);\n outline-offset: 1px;\n}\n\n.dsh-side-chat-selection-comment {\n position: fixed;\n z-index: 92;\n display: grid;\n max-width: calc(100vw - 16px);\n box-sizing: border-box;\n gap: 10px;\n padding: 12px;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 20px;\n background: var(--dsw-surface, #fff);\n box-shadow: 0 5px 18px rgb(0 0 0 / 9%);\n color: var(--dsw-text, #19191d);\n}\n.dsh-side-chat-selection-comment textarea {\n width: 100%;\n min-height: 48px;\n max-height: 128px;\n box-sizing: border-box;\n resize: none;\n padding: 6px 8px;\n overflow-y: auto;\n border: 0;\n outline: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.45;\n}\n.dsh-side-chat-selection-comment-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.dsh-side-chat-selection-comment-actions button {\n min-height: 32px;\n padding: 0 14px;\n border: 1px solid var(--dsw-border, #d8d8de);\n border-radius: 999px;\n background: var(--dsw-surface, #fff);\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n.dsh-side-chat-selection-comment-actions button:hover { background: var(--dsw-surface-subtle, #f3f3f5); }\n.dsh-side-chat-selection-comment-actions .dsh-side-chat-selection-comment-save {\n border-color: transparent;\n background: var(--dsw-alias-button-info, #1473e6);\n color: #fff;\n}\n.dsh-side-chat-selection-comment-actions .dsh-side-chat-selection-comment-save:hover {\n background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n\n@media (max-width: 900px) {\n .dsh-side-chat-panel {\n right: 12px;\n bottom: 12px;\n width: calc(100vw - 24px);\n max-height: calc(100dvh - 24px);\n border-radius: 24px;\n }\n}\n\n@media (max-width: 720px) {\n .dsh-side-chat-panel {\n right: 8px;\n bottom: 8px;\n width: calc(100vw - 16px);\n height: min(78dvh, 760px);\n max-height: calc(100dvh - 16px);\n border-radius: 22px;\n }\n .dsh-side-chat-transcript { padding: 14px 14px 20px; }\n .dsh-side-chat-header { padding-left: 14px; }\n .dsh-side-chat-error { margin-inline: 12px; }\n}\n\n@media (max-height: 620px) {\n .dsh-side-chat-panel {\n bottom: 8px;\n height: calc(100dvh - 16px);\n max-height: calc(100dvh - 16px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dsh-side-chat-reasoning[data-state=\"running\"] .dsh-side-chat-reasoning-row::after { animation: none; }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .dsh-side-chat-panel { animation: dsh-side-chat-enter 160ms ease-out; }\n @keyframes dsh-side-chat-enter { from { transform: translateY(18px) scale(.985); opacity: .7; } }\n}\n\n@media (forced-colors: active) {\n.dsh-side-chat-panel,\n.dsh-side-chat-selection-actions,\n.dsh-side-chat-selection-comment,\n.dsh-side-chat-annotation-marker { border: 1px solid CanvasText; }\n}\n";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/client/parent-composer/add-to-conversation.ts
|
|
14
14
|
const SELECTION_REFERENCE_SOURCE = "dsh-side-chat-selection";
|
|
@@ -20,25 +20,61 @@ window.__ModuleLoader__.load({
|
|
|
20
20
|
const trimmedComment = comment?.trim();
|
|
21
21
|
return {
|
|
22
22
|
text: selection.text,
|
|
23
|
+
selection,
|
|
23
24
|
...trimmedComment === void 0 || trimmedComment.length === 0 ? {} : { comment: trimmedComment }
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
function encodeSelectionReference(annotations) {
|
|
27
28
|
return JSON.stringify({
|
|
28
|
-
version:
|
|
29
|
+
version: 2,
|
|
29
30
|
annotations
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
|
-
function
|
|
33
|
+
function isSelection(value) {
|
|
34
|
+
if (typeof value !== "object" || value === null) return false;
|
|
35
|
+
const selection = value;
|
|
36
|
+
if (typeof selection.parentSessionId !== "string" || typeof selection.text !== "string" || !Number.isSafeInteger(selection.atSeq) || !Array.isArray(selection.fragments) || typeof selection.rect !== "object" || selection.rect === null) return false;
|
|
37
|
+
const rect = selection.rect;
|
|
38
|
+
if (![
|
|
39
|
+
rect.x,
|
|
40
|
+
rect.y,
|
|
41
|
+
rect.width,
|
|
42
|
+
rect.height,
|
|
43
|
+
rect.viewportWidth,
|
|
44
|
+
rect.viewportHeight
|
|
45
|
+
].every((number) => typeof number === "number" && Number.isFinite(number))) return false;
|
|
46
|
+
return selection.fragments.every((candidate) => {
|
|
47
|
+
if (typeof candidate !== "object" || candidate === null) return false;
|
|
48
|
+
const fragment = candidate;
|
|
49
|
+
return typeof fragment.nodeKey === "string" && typeof fragment.nodeKind === "string" && typeof fragment.turnKey === "string" && Number.isSafeInteger(fragment.seq) && Number.isSafeInteger(fragment.startOffset) && Number.isSafeInteger(fragment.endOffset) && typeof fragment.text === "string" && [
|
|
50
|
+
"user",
|
|
51
|
+
"assistant",
|
|
52
|
+
"context",
|
|
53
|
+
"code"
|
|
54
|
+
].includes(fragment.source ?? "") && typeof fragment.modelVisible === "boolean" && typeof fragment.settled === "boolean";
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function isStoredAnnotation(value) {
|
|
33
58
|
if (typeof value !== "object" || value === null) return false;
|
|
34
59
|
const annotation = value;
|
|
35
|
-
return typeof annotation.text === "string" && (annotation.comment === void 0 || typeof annotation.comment === "string");
|
|
60
|
+
return typeof annotation.text === "string" && (annotation.comment === void 0 || typeof annotation.comment === "string") && (annotation.selection === void 0 || isSelection(annotation.selection));
|
|
36
61
|
}
|
|
37
|
-
function
|
|
62
|
+
function visibleAnnotation(annotation) {
|
|
63
|
+
return {
|
|
64
|
+
text: annotation.text,
|
|
65
|
+
...annotation.comment === void 0 ? {} : { comment: annotation.comment }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function decodeStoredSelectionReference(ref) {
|
|
38
69
|
const value = JSON.parse(ref);
|
|
39
|
-
if (
|
|
40
|
-
if (value
|
|
41
|
-
|
|
70
|
+
if (isStoredAnnotation(value)) return [value];
|
|
71
|
+
if (typeof value !== "object" || value === null) throw new Error("The selected conversation annotation is no longer valid.");
|
|
72
|
+
const payload = value;
|
|
73
|
+
if (payload.version !== 1 && payload.version !== 2 || !Array.isArray(payload.annotations) || payload.annotations.length === 0 || !payload.annotations.every(isStoredAnnotation)) throw new Error("The selected conversation annotation is no longer valid.");
|
|
74
|
+
return payload.annotations;
|
|
75
|
+
}
|
|
76
|
+
function decodeSelectionReference(ref) {
|
|
77
|
+
return decodeStoredSelectionReference(ref).map(visibleAnnotation);
|
|
42
78
|
}
|
|
43
79
|
function selectedContext(annotations) {
|
|
44
80
|
return [
|
|
@@ -63,16 +99,32 @@ window.__ModuleLoader__.load({
|
|
|
63
99
|
function selectionOccurrences(snapshot) {
|
|
64
100
|
return snapshot.occurrences.filter((occurrence) => occurrence.source === SELECTION_REFERENCE_SOURCE);
|
|
65
101
|
}
|
|
66
|
-
|
|
67
|
-
function conversationAnnotations(snapshot) {
|
|
102
|
+
function storedConversationAnnotations(snapshot) {
|
|
68
103
|
return selectionOccurrences(snapshot).flatMap((occurrence) => {
|
|
69
104
|
try {
|
|
70
|
-
return [...
|
|
105
|
+
return [...decodeStoredSelectionReference(occurrence.ref)];
|
|
71
106
|
} catch {
|
|
72
107
|
return [];
|
|
73
108
|
}
|
|
74
109
|
});
|
|
75
110
|
}
|
|
111
|
+
/** Read all plugin annotations represented by the current DSH input occurrence. */
|
|
112
|
+
function conversationAnnotations(snapshot) {
|
|
113
|
+
return storedConversationAnnotations(snapshot).map(visibleAnnotation);
|
|
114
|
+
}
|
|
115
|
+
/** Read annotations that retain an exact source-selection anchor. */
|
|
116
|
+
function conversationSelectionAnnotations(snapshot) {
|
|
117
|
+
const anchored = [];
|
|
118
|
+
storedConversationAnnotations(snapshot).forEach((annotation, annotationIndex) => {
|
|
119
|
+
if (annotation.selection === void 0) return;
|
|
120
|
+
anchored.push({
|
|
121
|
+
...visibleAnnotation(annotation),
|
|
122
|
+
annotationIndex,
|
|
123
|
+
selection: annotation.selection
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
return anchored;
|
|
127
|
+
}
|
|
76
128
|
function draftWithoutSelectionOccurrences(snapshot) {
|
|
77
129
|
const occurrences = [...selectionOccurrences(snapshot)].sort((a, b) => b.offset - a.offset);
|
|
78
130
|
let draft = snapshot.draft;
|
|
@@ -105,10 +157,7 @@ window.__ModuleLoader__.load({
|
|
|
105
157
|
}
|
|
106
158
|
}
|
|
107
159
|
};
|
|
108
|
-
|
|
109
|
-
function addSelectionToConversation(input, selection, comment) {
|
|
110
|
-
const before = input.state.getSnapshot();
|
|
111
|
-
const annotations = [...conversationAnnotations(before), annotationFromSelection(selection, comment)];
|
|
160
|
+
function writeConversationAnnotations(input, before, annotations) {
|
|
112
161
|
const draft = draftWithoutSelectionOccurrences(before);
|
|
113
162
|
if (selectionOccurrences(before).length > 0) input.setDraft(draft);
|
|
114
163
|
const insertionState = input.state.getSnapshot();
|
|
@@ -125,6 +174,61 @@ window.__ModuleLoader__.load({
|
|
|
125
174
|
input.setDraft(`${OBJECT_REPLACEMENT_CHARACTER}\n\n${draft}`);
|
|
126
175
|
return true;
|
|
127
176
|
}
|
|
177
|
+
/** Add one passage to the parent composer's aggregated annotation occurrence. */
|
|
178
|
+
function addSelectionToConversation(input, selection, comment) {
|
|
179
|
+
const before = input.state.getSnapshot();
|
|
180
|
+
return writeConversationAnnotations(input, before, [...storedConversationAnnotations(before), annotationFromSelection(selection, comment)]);
|
|
181
|
+
}
|
|
182
|
+
/** Replace the optional comment on one unsent selected-passage annotation. */
|
|
183
|
+
function updateConversationAnnotation(input, annotationIndex, comment) {
|
|
184
|
+
const before = input.state.getSnapshot();
|
|
185
|
+
const annotations = [...storedConversationAnnotations(before)];
|
|
186
|
+
const current = annotations[annotationIndex];
|
|
187
|
+
if (!Number.isSafeInteger(annotationIndex) || current === void 0) return false;
|
|
188
|
+
const trimmedComment = comment?.trim();
|
|
189
|
+
annotations[annotationIndex] = {
|
|
190
|
+
text: current.text,
|
|
191
|
+
...current.selection === void 0 ? {} : { selection: current.selection },
|
|
192
|
+
...trimmedComment === void 0 || trimmedComment.length === 0 ? {} : { comment: trimmedComment }
|
|
193
|
+
};
|
|
194
|
+
return writeConversationAnnotations(input, before, annotations);
|
|
195
|
+
}
|
|
196
|
+
/** Return the valid aggregated reference currently occupying the leading draft slot. */
|
|
197
|
+
function conversationAnnotationReference(snapshot) {
|
|
198
|
+
const occurrence = selectionOccurrences(snapshot).find((candidate) => candidate.offset === 0);
|
|
199
|
+
if (occurrence === void 0 || !snapshot.draft.startsWith(OBJECT_REPLACEMENT_CHARACTER)) return;
|
|
200
|
+
try {
|
|
201
|
+
decodeStoredSelectionReference(occurrence.ref);
|
|
202
|
+
return occurrence.ref;
|
|
203
|
+
} catch {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function draftWithoutOrphanedAnnotationPrefix(snapshot) {
|
|
208
|
+
const prefix = `${OBJECT_REPLACEMENT_CHARACTER}\n\n`;
|
|
209
|
+
if (!snapshot.draft.startsWith(prefix) || snapshot.occurrences.some((occurrence) => occurrence.offset === 0)) return;
|
|
210
|
+
return snapshot.draft.slice(prefix.length);
|
|
211
|
+
}
|
|
212
|
+
/** Remove the plugin-owned prefix when rc.6 restored its draft without occurrences. */
|
|
213
|
+
function removeOrphanedConversationAnnotationPlaceholder(input) {
|
|
214
|
+
const draft = draftWithoutOrphanedAnnotationPrefix(input.state.getSnapshot());
|
|
215
|
+
if (draft === void 0) return false;
|
|
216
|
+
input.setDraft(draft);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
/** Rehydrate a lost rc.6 occurrence only over the exact plugin-owned orphan prefix. */
|
|
220
|
+
function restoreConversationAnnotationReference(input, ref) {
|
|
221
|
+
let annotations;
|
|
222
|
+
try {
|
|
223
|
+
annotations = decodeStoredSelectionReference(ref);
|
|
224
|
+
} catch {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const draft = draftWithoutOrphanedAnnotationPrefix(input.state.getSnapshot());
|
|
228
|
+
if (draft === void 0) return false;
|
|
229
|
+
input.setDraft(draft);
|
|
230
|
+
return writeConversationAnnotations(input, input.state.getSnapshot(), annotations);
|
|
231
|
+
}
|
|
128
232
|
function unescapeXmlText(value) {
|
|
129
233
|
return value.replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
130
234
|
}
|
|
@@ -248,6 +352,22 @@ window.__ModuleLoader__.load({
|
|
|
248
352
|
(0, react.useEffect)(() => () => {
|
|
249
353
|
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
250
354
|
}, []);
|
|
355
|
+
(0, react.useEffect)(() => {
|
|
356
|
+
if (!expanded) return;
|
|
357
|
+
const dismissOutside = (event) => {
|
|
358
|
+
const quote = quoteRef.current;
|
|
359
|
+
const target = event.target;
|
|
360
|
+
if (quote !== null && target instanceof Node && quote.contains(target)) return;
|
|
361
|
+
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
362
|
+
leaveTimerRef.current = void 0;
|
|
363
|
+
setHovered(false);
|
|
364
|
+
setExpanded(false);
|
|
365
|
+
};
|
|
366
|
+
document.addEventListener("mousedown", dismissOutside, true);
|
|
367
|
+
return () => {
|
|
368
|
+
document.removeEventListener("mousedown", dismissOutside, true);
|
|
369
|
+
};
|
|
370
|
+
}, [expanded]);
|
|
251
371
|
const constrainDetailsToBoundary = () => {
|
|
252
372
|
const details = detailsRef.current;
|
|
253
373
|
const boundary = quoteRef.current?.closest(".dsh-side-chat-panel, [data-composer-seat], [data-chat-flow-kind]");
|
|
@@ -280,6 +400,11 @@ window.__ModuleLoader__.load({
|
|
|
280
400
|
"aria-expanded": expanded,
|
|
281
401
|
"aria-label": `${expanded ? messages.collapse : messages.expand}: ${messages.selectedPassage}`,
|
|
282
402
|
onClick: () => {
|
|
403
|
+
if (expanded) {
|
|
404
|
+
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
405
|
+
leaveTimerRef.current = void 0;
|
|
406
|
+
setHovered(false);
|
|
407
|
+
}
|
|
283
408
|
setExpanded((value) => !value);
|
|
284
409
|
},
|
|
285
410
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
@@ -384,9 +509,12 @@ window.__ModuleLoader__.load({
|
|
|
384
509
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
385
510
|
selections: parsed.annotations,
|
|
386
511
|
messages: SIDE_CHAT_MESSAGES[currentLocale()]
|
|
387
|
-
}), (0,
|
|
388
|
-
|
|
389
|
-
|
|
512
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
513
|
+
className: "dsh-side-chat-parent-user-message-body",
|
|
514
|
+
children: (0, react.createElement)(Original, {
|
|
515
|
+
...props,
|
|
516
|
+
node
|
|
517
|
+
})
|
|
390
518
|
})]
|
|
391
519
|
});
|
|
392
520
|
};
|
|
@@ -397,7 +525,7 @@ window.__ModuleLoader__.load({
|
|
|
397
525
|
const removeDock = slots.inject("conversation.input.dock", () => slots.register({
|
|
398
526
|
name: "conversation.input.dock",
|
|
399
527
|
id: "dsh-side-chat-annotations",
|
|
400
|
-
order:
|
|
528
|
+
order: 30
|
|
401
529
|
}, ({ input }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParentComposerAnnotations, {
|
|
402
530
|
input,
|
|
403
531
|
onRemove: removeAnnotations
|
|
@@ -589,10 +717,12 @@ window.__ModuleLoader__.load({
|
|
|
589
717
|
} catch (error) {
|
|
590
718
|
return failure(localError("selection_stale", error instanceof Error ? error.message : "The selected text is no longer available.", false));
|
|
591
719
|
}
|
|
720
|
+
const modelSelection = this.sessions.sideChatModelPreference();
|
|
592
721
|
this.publish({
|
|
593
722
|
phase: "draft",
|
|
594
723
|
parentSessionId,
|
|
595
724
|
...input.selection === void 0 ? {} : { selection: input.selection },
|
|
725
|
+
...modelSelection === void 0 ? {} : { modelSelection },
|
|
596
726
|
draft: input.draft ?? ""
|
|
597
727
|
});
|
|
598
728
|
return success(void 0);
|
|
@@ -616,6 +746,45 @@ window.__ModuleLoader__.load({
|
|
|
616
746
|
});
|
|
617
747
|
return success(void 0);
|
|
618
748
|
}
|
|
749
|
+
initializeModel(selection) {
|
|
750
|
+
const state = this.getSnapshot();
|
|
751
|
+
if (state.childSessionId !== void 0 || !["draft", "error"].includes(state.phase) || state.error?.operation === "close") return failure(localError("invalid_request", "The Side Chat model cannot be initialized right now.", false));
|
|
752
|
+
const selected = { ...selection };
|
|
753
|
+
this.publish({
|
|
754
|
+
...state,
|
|
755
|
+
modelSelection: selected
|
|
756
|
+
});
|
|
757
|
+
return success(selected);
|
|
758
|
+
}
|
|
759
|
+
async selectModel(selection) {
|
|
760
|
+
const state = this.getSnapshot();
|
|
761
|
+
if (state.phase === "closed" || [
|
|
762
|
+
"creating",
|
|
763
|
+
"opening",
|
|
764
|
+
"closing"
|
|
765
|
+
].includes(state.phase) || state.error?.operation === "close") return failure(localError("invalid_request", "The Side Chat model cannot be changed right now.", false));
|
|
766
|
+
const selected = { ...selection };
|
|
767
|
+
const childSessionId = state.childSessionId;
|
|
768
|
+
if (childSessionId === void 0) {
|
|
769
|
+
const initialized = this.initializeModel(selected);
|
|
770
|
+
if (initialized.ok) this.sessions.rememberSideChatModelPreference(initialized.value);
|
|
771
|
+
return initialized;
|
|
772
|
+
}
|
|
773
|
+
const result = await this.invoke(() => this.remote.selectModel({
|
|
774
|
+
childSessionId,
|
|
775
|
+
...selected
|
|
776
|
+
}));
|
|
777
|
+
if (!result.ok) return failure(result.error);
|
|
778
|
+
const latest = this.getSnapshot();
|
|
779
|
+
if (latest.childSessionId === childSessionId && !["closed", "closing"].includes(latest.phase)) {
|
|
780
|
+
this.publish({
|
|
781
|
+
...latest,
|
|
782
|
+
modelSelection: result.value.selected
|
|
783
|
+
});
|
|
784
|
+
this.sessions.rememberSideChatModelPreference(result.value.selected);
|
|
785
|
+
}
|
|
786
|
+
return success(result.value.selected);
|
|
787
|
+
}
|
|
619
788
|
async sendFirst(question) {
|
|
620
789
|
if (this.opening !== void 0) return failure(localError("invalid_request", "The Side Chat is already opening.", false));
|
|
621
790
|
const state = this.getSnapshot();
|
|
@@ -750,7 +919,8 @@ window.__ModuleLoader__.load({
|
|
|
750
919
|
});
|
|
751
920
|
const created = await this.invoke(() => this.remote.create({
|
|
752
921
|
parentSessionId,
|
|
753
|
-
atSeq
|
|
922
|
+
atSeq,
|
|
923
|
+
...original.modelSelection === void 0 ? {} : { modelSelection: original.modelSelection }
|
|
754
924
|
}));
|
|
755
925
|
if (!created.ok) {
|
|
756
926
|
if (this.closeRequested) this.reset();
|
|
@@ -824,6 +994,7 @@ window.__ModuleLoader__.load({
|
|
|
824
994
|
childSessionId: created.childSessionId,
|
|
825
995
|
boundarySeq: created.boundarySeq,
|
|
826
996
|
inheritedThroughSeq: created.inheritedThroughSeq,
|
|
997
|
+
...created.modelSelection === void 0 ? {} : { modelSelection: created.modelSelection },
|
|
827
998
|
firstQuestion: question,
|
|
828
999
|
error: void 0
|
|
829
1000
|
});
|
|
@@ -5064,6 +5235,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5064
5235
|
"side_chat_not_found",
|
|
5065
5236
|
"side_chat_open_failed",
|
|
5066
5237
|
"side_chat_prompt_failed",
|
|
5238
|
+
"side_chat_model_failed",
|
|
5067
5239
|
"side_chat_interrupt_failed",
|
|
5068
5240
|
"side_chat_destroy_failed",
|
|
5069
5241
|
"transport_error",
|
|
@@ -5073,6 +5245,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5073
5245
|
//#endregion
|
|
5074
5246
|
//#region src/shared/archived-wire.ts
|
|
5075
5247
|
const id = string().min(1).max(512);
|
|
5248
|
+
const modelSelectionSchema = object({
|
|
5249
|
+
provider: id,
|
|
5250
|
+
model: id,
|
|
5251
|
+
reasoningEffort: id.optional()
|
|
5252
|
+
}).strict();
|
|
5076
5253
|
const sideChatWireErrorSchema = object({
|
|
5077
5254
|
code: _enum(SIDE_CHAT_ERROR_CODES),
|
|
5078
5255
|
message: string(),
|
|
@@ -5080,15 +5257,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5080
5257
|
}).strict();
|
|
5081
5258
|
const archivedCreateRequestSchema = object({
|
|
5082
5259
|
parentSessionId: id,
|
|
5083
|
-
atSeq: number().finite().nonnegative()
|
|
5260
|
+
atSeq: number().finite().nonnegative(),
|
|
5261
|
+
modelSelection: modelSelectionSchema.optional()
|
|
5262
|
+
}).strict();
|
|
5263
|
+
const archivedSelectModelRequestSchema = object({
|
|
5264
|
+
childSessionId: id,
|
|
5265
|
+
provider: id,
|
|
5266
|
+
model: id,
|
|
5267
|
+
reasoningEffort: id.optional()
|
|
5084
5268
|
}).strict();
|
|
5085
5269
|
const archivedCloseRequestSchema = object({ childSessionId: id }).strict();
|
|
5086
5270
|
const createValueSchema = object({
|
|
5087
5271
|
parentSessionId: id,
|
|
5088
5272
|
childSessionId: id,
|
|
5089
5273
|
boundarySeq: number().int().nonnegative(),
|
|
5090
|
-
inheritedThroughSeq: number().int().nonnegative()
|
|
5274
|
+
inheritedThroughSeq: number().int().nonnegative(),
|
|
5275
|
+
modelSelection: modelSelectionSchema.optional()
|
|
5091
5276
|
}).strict();
|
|
5277
|
+
const selectModelValueSchema = object({ selected: modelSelectionSchema }).strict();
|
|
5092
5278
|
const closeValueSchema = object({ closed: literal(true) }).strict();
|
|
5093
5279
|
function resultSchema(value) {
|
|
5094
5280
|
return discriminatedUnion("ok", [object({
|
|
@@ -5100,10 +5286,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5100
5286
|
}).strict()]);
|
|
5101
5287
|
}
|
|
5102
5288
|
const archivedCreateResultSchema = resultSchema(createValueSchema);
|
|
5289
|
+
const archivedSelectModelResultSchema = resultSchema(selectModelValueSchema);
|
|
5103
5290
|
const archivedCloseResultSchema = resultSchema(closeValueSchema);
|
|
5104
5291
|
//#endregion
|
|
5105
5292
|
//#region src/typert.ts
|
|
5106
5293
|
function invocation(method, implementation, parameterSchema, resultSchema) {
|
|
5294
|
+
const requestType = method === "create" ? "CreateSideChatRequest" : method === "selectModel" ? "SelectSideChatModelRequest" : "CloseSideChatRequest";
|
|
5295
|
+
const resultType = method === "create" ? "ArchivedCreateResult" : method === "selectModel" ? "ArchivedSelectModelResult" : "ArchivedCloseResult";
|
|
5107
5296
|
return {
|
|
5108
5297
|
id: `@ahggg/dsh-side-chat#sideChatArchived/${method}`,
|
|
5109
5298
|
service: "sideChat",
|
|
@@ -5117,13 +5306,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5117
5306
|
source: "json",
|
|
5118
5307
|
codec: {
|
|
5119
5308
|
mode: "strict",
|
|
5120
|
-
typeSymbol: `@ahggg/dsh-side-chat/remote#${
|
|
5309
|
+
typeSymbol: `@ahggg/dsh-side-chat/remote#${requestType}`,
|
|
5121
5310
|
schema: parameterSchema
|
|
5122
5311
|
}
|
|
5123
5312
|
}],
|
|
5124
5313
|
result: {
|
|
5125
5314
|
mode: "strict",
|
|
5126
|
-
typeSymbol: `@ahggg/dsh-side-chat/remote
|
|
5315
|
+
typeSymbol: `@ahggg/dsh-side-chat/remote#${resultType}`,
|
|
5127
5316
|
schema: resultSchema
|
|
5128
5317
|
},
|
|
5129
5318
|
sourceLocation: {
|
|
@@ -5137,7 +5326,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5137
5326
|
//#region src/remote.ts
|
|
5138
5327
|
const TYPERT_REMOTE = {
|
|
5139
5328
|
package: "@ahggg/dsh-side-chat",
|
|
5140
|
-
descriptors: [
|
|
5329
|
+
descriptors: [
|
|
5330
|
+
invocation("create", "createArchived", archivedCreateRequestSchema, archivedCreateResultSchema),
|
|
5331
|
+
invocation("selectModel", "selectArchivedModel", archivedSelectModelRequestSchema, archivedSelectModelResultSchema),
|
|
5332
|
+
invocation("close", "closeArchived", archivedCloseRequestSchema, archivedCloseResultSchema)
|
|
5333
|
+
]
|
|
5141
5334
|
};
|
|
5142
5335
|
//#endregion
|
|
5143
5336
|
//#region src/client/rc6/remote-adapter.ts
|
|
@@ -5163,6 +5356,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5163
5356
|
error: remoteFailure(result.error)
|
|
5164
5357
|
};
|
|
5165
5358
|
},
|
|
5359
|
+
selectModel: async (request) => {
|
|
5360
|
+
const result = await archived.selectModel(request);
|
|
5361
|
+
return result.ok ? result.value : {
|
|
5362
|
+
ok: false,
|
|
5363
|
+
error: remoteFailure(result.error)
|
|
5364
|
+
};
|
|
5365
|
+
},
|
|
5166
5366
|
close: async (request) => {
|
|
5167
5367
|
const result = await archived.close(request);
|
|
5168
5368
|
return result.ok ? result.value : {
|
|
@@ -5175,6 +5375,414 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5175
5375
|
};
|
|
5176
5376
|
}
|
|
5177
5377
|
//#endregion
|
|
5378
|
+
//#region src/client/panel/SideChatModelSelect.tsx
|
|
5379
|
+
const MODEL_MESSAGES = {
|
|
5380
|
+
en: {
|
|
5381
|
+
selectModel: "Select model",
|
|
5382
|
+
menu: "Model and reasoning effort",
|
|
5383
|
+
model: "Model",
|
|
5384
|
+
effort: "Effort",
|
|
5385
|
+
providerDefault: "Default",
|
|
5386
|
+
loading: "Refreshing model list…",
|
|
5387
|
+
reload: "Reload",
|
|
5388
|
+
emptyModels: "No models available.",
|
|
5389
|
+
emptyEfforts: "This model provides no reasoning effort levels.",
|
|
5390
|
+
aria: (model, effort) => effort === void 0 ? `Select model, current ${model}` : `Select model, current ${model}, reasoning effort ${effort}`,
|
|
5391
|
+
operationFailed: (message) => `Model operation failed: ${message}`,
|
|
5392
|
+
groupFailed: (name, message) => `${name} failed to load: ${message}`
|
|
5393
|
+
},
|
|
5394
|
+
"zh-CN": {
|
|
5395
|
+
selectModel: "选择模型",
|
|
5396
|
+
menu: "模型与推理等级",
|
|
5397
|
+
model: "模型",
|
|
5398
|
+
effort: "推理等级",
|
|
5399
|
+
providerDefault: "Default",
|
|
5400
|
+
loading: "正在刷新模型列表…",
|
|
5401
|
+
reload: "重新加载",
|
|
5402
|
+
emptyModels: "没有可用的模型。",
|
|
5403
|
+
emptyEfforts: "当前模型未提供推理等级。",
|
|
5404
|
+
aria: (model, effort) => effort === void 0 ? `选择模型,当前 ${model}` : `选择模型,当前 ${model},推理等级 ${effort}`,
|
|
5405
|
+
operationFailed: (message) => `模型操作失败:${message}`,
|
|
5406
|
+
groupFailed: (name, message) => `${name} 加载失败:${message}`
|
|
5407
|
+
}
|
|
5408
|
+
};
|
|
5409
|
+
function sameModel(selection, provider, model) {
|
|
5410
|
+
return selection?.provider === provider && selection.model === model;
|
|
5411
|
+
}
|
|
5412
|
+
function sameSelection(left, right) {
|
|
5413
|
+
return left.provider === right.provider && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
|
|
5414
|
+
}
|
|
5415
|
+
function repairSelection(selection, choices, fallback) {
|
|
5416
|
+
const choice = choices.find((candidate) => sameModel(selection, candidate.group.id, candidate.model.id));
|
|
5417
|
+
if (choice === void 0) return fallback;
|
|
5418
|
+
const reasoning = choice.model.reasoning;
|
|
5419
|
+
if (reasoning === void 0) return {
|
|
5420
|
+
provider: selection.provider,
|
|
5421
|
+
model: selection.model
|
|
5422
|
+
};
|
|
5423
|
+
if (selection.reasoningEffort === void 0 || reasoning.efforts.some((effort) => effort.id === selection.reasoningEffort)) return selection;
|
|
5424
|
+
return {
|
|
5425
|
+
provider: selection.provider,
|
|
5426
|
+
model: selection.model,
|
|
5427
|
+
...reasoning.defaultEffort === void 0 ? {} : { reasoningEffort: reasoning.defaultEffort }
|
|
5428
|
+
};
|
|
5429
|
+
}
|
|
5430
|
+
/** Side Chat projection of DSH Web's native composer model selector. */
|
|
5431
|
+
function SideChatModelSelect({ directory, selection, locked, validateInitialSelection = true, locale = "en", onInitialize, onSelect }) {
|
|
5432
|
+
const messages = MODEL_MESSAGES[locale];
|
|
5433
|
+
const state = (0, react.useSyncExternalStore)((listener) => directory.store.subscribe(listener), () => directory.store.getSnapshot(), () => directory.store.getSnapshot());
|
|
5434
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
5435
|
+
const [pane, setPane] = (0, react.useState)("root");
|
|
5436
|
+
const [selecting, setSelecting] = (0, react.useState)(false);
|
|
5437
|
+
const [toast, setToast] = (0, react.useState)(null);
|
|
5438
|
+
const rootRef = (0, react.useRef)(null);
|
|
5439
|
+
const triggerRef = (0, react.useRef)(null);
|
|
5440
|
+
const itemRefs = (0, react.useRef)([]);
|
|
5441
|
+
const initialized = (0, react.useRef)(false);
|
|
5442
|
+
const operation = (0, react.useRef)(0);
|
|
5443
|
+
const toastSequence = (0, react.useRef)(0);
|
|
5444
|
+
const id = (0, react.useId)();
|
|
5445
|
+
const choices = (0, react.useMemo)(() => state.groups.flatMap((group) => group.models.map((model) => ({
|
|
5446
|
+
group,
|
|
5447
|
+
model
|
|
5448
|
+
}))), [state.groups]);
|
|
5449
|
+
const current = selection ?? state.current ?? void 0;
|
|
5450
|
+
const currentChoice = choices.find((choice) => sameModel(current, choice.group.id, choice.model.id));
|
|
5451
|
+
const reasoning = currentChoice?.model.reasoning;
|
|
5452
|
+
const effectiveEffort = current?.reasoningEffort ?? reasoning?.defaultEffort;
|
|
5453
|
+
const effortLabel = reasoning === void 0 ? void 0 : effectiveEffort === void 0 ? messages.providerDefault : reasoning.efforts.find((level) => level.id === effectiveEffort)?.name ?? effectiveEffort;
|
|
5454
|
+
const effortChoices = (0, react.useMemo)(() => reasoning === void 0 ? [] : [...reasoning.defaultEffort === void 0 ? [{
|
|
5455
|
+
key: "provider-default",
|
|
5456
|
+
effort: void 0,
|
|
5457
|
+
label: messages.providerDefault
|
|
5458
|
+
}] : [], ...reasoning.efforts.map((effort) => ({
|
|
5459
|
+
key: `effort:${effort.id}`,
|
|
5460
|
+
effort: effort.id,
|
|
5461
|
+
label: effort.name,
|
|
5462
|
+
...effort.description === void 0 ? {} : { description: effort.description }
|
|
5463
|
+
}))], [messages.providerDefault, reasoning]);
|
|
5464
|
+
const modelLabel = currentChoice?.model.name ?? messages.selectModel;
|
|
5465
|
+
const triggerLabel = effortLabel === void 0 ? modelLabel : `${modelLabel} · ${effortLabel}`;
|
|
5466
|
+
const reload = () => {
|
|
5467
|
+
directory.load().catch(() => void 0);
|
|
5468
|
+
};
|
|
5469
|
+
(0, react.useEffect)(() => {
|
|
5470
|
+
reload();
|
|
5471
|
+
}, [directory]);
|
|
5472
|
+
(0, react.useEffect)(() => {
|
|
5473
|
+
if (initialized.current) return;
|
|
5474
|
+
if (selection !== void 0 && !validateInitialSelection) {
|
|
5475
|
+
initialized.current = true;
|
|
5476
|
+
return;
|
|
5477
|
+
}
|
|
5478
|
+
if (state.current === null) return;
|
|
5479
|
+
const directoryCurrent = {
|
|
5480
|
+
provider: state.current.provider,
|
|
5481
|
+
model: state.current.model,
|
|
5482
|
+
...state.current.reasoningEffort === void 0 ? {} : { reasoningEffort: state.current.reasoningEffort }
|
|
5483
|
+
};
|
|
5484
|
+
if (selection === void 0) {
|
|
5485
|
+
initialized.current = true;
|
|
5486
|
+
onInitialize(directoryCurrent, { remember: false });
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
if (state.status !== "ready") return;
|
|
5490
|
+
initialized.current = true;
|
|
5491
|
+
const repaired = repairSelection(selection, choices, directoryCurrent);
|
|
5492
|
+
if (!sameSelection(selection, repaired)) onInitialize(repaired, { remember: true });
|
|
5493
|
+
}, [
|
|
5494
|
+
choices,
|
|
5495
|
+
onInitialize,
|
|
5496
|
+
selection,
|
|
5497
|
+
state.current,
|
|
5498
|
+
state.status,
|
|
5499
|
+
validateInitialSelection
|
|
5500
|
+
]);
|
|
5501
|
+
(0, react.useEffect)(() => {
|
|
5502
|
+
if (!open) return;
|
|
5503
|
+
const closeOutside = (event) => {
|
|
5504
|
+
if (!rootRef.current?.contains(event.target)) setOpen(false);
|
|
5505
|
+
};
|
|
5506
|
+
document.addEventListener("mousedown", closeOutside);
|
|
5507
|
+
return () => {
|
|
5508
|
+
document.removeEventListener("mousedown", closeOutside);
|
|
5509
|
+
};
|
|
5510
|
+
}, [open]);
|
|
5511
|
+
const show = () => {
|
|
5512
|
+
setPane("root");
|
|
5513
|
+
setOpen(true);
|
|
5514
|
+
reload();
|
|
5515
|
+
};
|
|
5516
|
+
const close = (restoreFocus = false) => {
|
|
5517
|
+
setOpen(false);
|
|
5518
|
+
setPane("root");
|
|
5519
|
+
if (restoreFocus) queueMicrotask(() => {
|
|
5520
|
+
triggerRef.current?.focus();
|
|
5521
|
+
});
|
|
5522
|
+
};
|
|
5523
|
+
const moveFocus = (offset) => {
|
|
5524
|
+
const items = itemRefs.current.filter((item) => item !== null);
|
|
5525
|
+
if (items.length === 0) return;
|
|
5526
|
+
const active = items.findIndex((item) => item === document.activeElement);
|
|
5527
|
+
items[(Math.max(active, 0) + offset + items.length) % items.length]?.focus();
|
|
5528
|
+
};
|
|
5529
|
+
const onKeyDown = (event) => {
|
|
5530
|
+
if (event.key === "Escape" && open) {
|
|
5531
|
+
event.preventDefault();
|
|
5532
|
+
if (pane !== "root") setPane("root");
|
|
5533
|
+
else close(true);
|
|
5534
|
+
return;
|
|
5535
|
+
}
|
|
5536
|
+
if (!open || event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
|
|
5537
|
+
event.preventDefault();
|
|
5538
|
+
moveFocus(event.key === "ArrowDown" ? 1 : -1);
|
|
5539
|
+
};
|
|
5540
|
+
const onBlur = (event) => {
|
|
5541
|
+
if (event.relatedTarget instanceof Node && rootRef.current?.contains(event.relatedTarget)) return;
|
|
5542
|
+
close();
|
|
5543
|
+
};
|
|
5544
|
+
const submitSelection = async (next) => {
|
|
5545
|
+
const generation = ++operation.current;
|
|
5546
|
+
setSelecting(true);
|
|
5547
|
+
const result = await onSelect(next);
|
|
5548
|
+
if (generation !== operation.current) return;
|
|
5549
|
+
setSelecting(false);
|
|
5550
|
+
if (!result.ok) {
|
|
5551
|
+
toastSequence.current += 1;
|
|
5552
|
+
setToast({
|
|
5553
|
+
seq: toastSequence.current,
|
|
5554
|
+
text: messages.operationFailed(result.error.message)
|
|
5555
|
+
});
|
|
5556
|
+
return;
|
|
5557
|
+
}
|
|
5558
|
+
close(true);
|
|
5559
|
+
};
|
|
5560
|
+
const chooseModel = (group, model) => {
|
|
5561
|
+
if (sameModel(current, group.id, model.id)) {
|
|
5562
|
+
close(true);
|
|
5563
|
+
return;
|
|
5564
|
+
}
|
|
5565
|
+
submitSelection({
|
|
5566
|
+
provider: group.id,
|
|
5567
|
+
model: model.id,
|
|
5568
|
+
...model.reasoning?.defaultEffort === void 0 ? {} : { reasoningEffort: model.reasoning.defaultEffort }
|
|
5569
|
+
});
|
|
5570
|
+
};
|
|
5571
|
+
const chooseEffort = (effort) => {
|
|
5572
|
+
if (current === void 0) return;
|
|
5573
|
+
if (effectiveEffort === effort) {
|
|
5574
|
+
close(true);
|
|
5575
|
+
return;
|
|
5576
|
+
}
|
|
5577
|
+
submitSelection({
|
|
5578
|
+
provider: current.provider,
|
|
5579
|
+
model: current.model,
|
|
5580
|
+
...effort === void 0 ? {} : { reasoningEffort: effort }
|
|
5581
|
+
});
|
|
5582
|
+
};
|
|
5583
|
+
itemRefs.current = [];
|
|
5584
|
+
let itemIndex = 0;
|
|
5585
|
+
const itemRef = () => {
|
|
5586
|
+
const index = itemIndex++;
|
|
5587
|
+
return (node) => {
|
|
5588
|
+
itemRefs.current[index] = node;
|
|
5589
|
+
};
|
|
5590
|
+
};
|
|
5591
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5592
|
+
ref: rootRef,
|
|
5593
|
+
className: "dsh-side-chat-model-root",
|
|
5594
|
+
"data-side-chat-model-select": "",
|
|
5595
|
+
onKeyDown,
|
|
5596
|
+
onBlur,
|
|
5597
|
+
children: [
|
|
5598
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5599
|
+
ref: triggerRef,
|
|
5600
|
+
type: "button",
|
|
5601
|
+
className: "dsh-side-chat-model-trigger",
|
|
5602
|
+
"aria-label": messages.aria(modelLabel, effortLabel),
|
|
5603
|
+
"aria-haspopup": "menu",
|
|
5604
|
+
"aria-expanded": open,
|
|
5605
|
+
"aria-controls": open ? `${id}-menu` : void 0,
|
|
5606
|
+
title: triggerLabel,
|
|
5607
|
+
disabled: locked,
|
|
5608
|
+
onClick: () => {
|
|
5609
|
+
if (open) close();
|
|
5610
|
+
else show();
|
|
5611
|
+
},
|
|
5612
|
+
children: [
|
|
5613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5614
|
+
className: "dsh-side-chat-model-trigger-label",
|
|
5615
|
+
children: modelLabel
|
|
5616
|
+
}),
|
|
5617
|
+
effortLabel !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5618
|
+
className: "dsh-side-chat-model-trigger-effort",
|
|
5619
|
+
children: effortLabel
|
|
5620
|
+
}),
|
|
5621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: `dsh-side-chat-model-chevron${open ? " dsh-side-chat-model-chevron-open" : ""}` })
|
|
5622
|
+
]
|
|
5623
|
+
}),
|
|
5624
|
+
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5625
|
+
id: `${id}-menu`,
|
|
5626
|
+
className: "dsh-side-chat-model-menu",
|
|
5627
|
+
role: "menu",
|
|
5628
|
+
"aria-label": messages.menu,
|
|
5629
|
+
"aria-busy": state.status === "loading" || selecting,
|
|
5630
|
+
children: [
|
|
5631
|
+
pane === "root" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5632
|
+
ref: itemRef(),
|
|
5633
|
+
type: "button",
|
|
5634
|
+
role: "menuitem",
|
|
5635
|
+
className: "dsh-side-chat-model-cell",
|
|
5636
|
+
onClick: () => {
|
|
5637
|
+
setPane("model");
|
|
5638
|
+
},
|
|
5639
|
+
children: [
|
|
5640
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5641
|
+
className: "dsh-side-chat-model-cell-label",
|
|
5642
|
+
children: messages.model
|
|
5643
|
+
}),
|
|
5644
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5645
|
+
className: "dsh-side-chat-model-cell-value",
|
|
5646
|
+
children: modelLabel
|
|
5647
|
+
}),
|
|
5648
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { className: "dsh-side-chat-model-cell-chevron" })
|
|
5649
|
+
]
|
|
5650
|
+
}), reasoning !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5651
|
+
ref: itemRef(),
|
|
5652
|
+
type: "button",
|
|
5653
|
+
role: "menuitem",
|
|
5654
|
+
className: "dsh-side-chat-model-cell",
|
|
5655
|
+
onClick: () => {
|
|
5656
|
+
setPane("effort");
|
|
5657
|
+
},
|
|
5658
|
+
children: [
|
|
5659
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5660
|
+
className: "dsh-side-chat-model-cell-label",
|
|
5661
|
+
children: messages.effort
|
|
5662
|
+
}),
|
|
5663
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5664
|
+
className: "dsh-side-chat-model-cell-value",
|
|
5665
|
+
children: effortLabel
|
|
5666
|
+
}),
|
|
5667
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { className: "dsh-side-chat-model-cell-chevron" })
|
|
5668
|
+
]
|
|
5669
|
+
})] }),
|
|
5670
|
+
pane === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5671
|
+
state.status === "loading" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5672
|
+
className: "dsh-side-chat-model-status",
|
|
5673
|
+
children: messages.loading
|
|
5674
|
+
}),
|
|
5675
|
+
state.error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5676
|
+
className: "dsh-side-chat-model-error",
|
|
5677
|
+
role: "alert",
|
|
5678
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: messages.operationFailed(state.error) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5679
|
+
type: "button",
|
|
5680
|
+
className: "dsh-side-chat-model-retry",
|
|
5681
|
+
onClick: reload,
|
|
5682
|
+
children: messages.reload
|
|
5683
|
+
})]
|
|
5684
|
+
}),
|
|
5685
|
+
state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5686
|
+
className: "dsh-side-chat-model-warning",
|
|
5687
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: messages.groupFailed(failure.name, failure.message) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5688
|
+
type: "button",
|
|
5689
|
+
className: "dsh-side-chat-model-retry",
|
|
5690
|
+
onClick: reload,
|
|
5691
|
+
children: messages.reload
|
|
5692
|
+
})]
|
|
5693
|
+
}, failure.id)),
|
|
5694
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5695
|
+
className: "dsh-side-chat-model-groups scrollable",
|
|
5696
|
+
children: state.groups.map((group) => {
|
|
5697
|
+
const headingId = `${id}-${group.id}`;
|
|
5698
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
5699
|
+
role: "group",
|
|
5700
|
+
"aria-labelledby": headingId,
|
|
5701
|
+
className: "dsh-side-chat-model-group",
|
|
5702
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5703
|
+
id: headingId,
|
|
5704
|
+
className: "dsh-side-chat-model-group-title",
|
|
5705
|
+
children: group.name
|
|
5706
|
+
}), group.models.map((model) => {
|
|
5707
|
+
const selected = sameModel(current, group.id, model.id);
|
|
5708
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5709
|
+
ref: itemRef(),
|
|
5710
|
+
type: "button",
|
|
5711
|
+
role: "menuitemradio",
|
|
5712
|
+
"aria-checked": selected,
|
|
5713
|
+
className: `dsh-side-chat-model-option${selected ? " dsh-side-chat-model-selected" : ""}`,
|
|
5714
|
+
title: model.name,
|
|
5715
|
+
disabled: selecting,
|
|
5716
|
+
onClick: () => {
|
|
5717
|
+
chooseModel(group, model);
|
|
5718
|
+
},
|
|
5719
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5720
|
+
className: "dsh-side-chat-model-option-copy",
|
|
5721
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5722
|
+
className: "dsh-side-chat-model-name",
|
|
5723
|
+
children: model.name
|
|
5724
|
+
}), model.description !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5725
|
+
className: "dsh-side-chat-model-description",
|
|
5726
|
+
children: model.description
|
|
5727
|
+
})]
|
|
5728
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5729
|
+
className: "dsh-side-chat-model-check",
|
|
5730
|
+
children: selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
|
|
5731
|
+
})]
|
|
5732
|
+
}, model.id);
|
|
5733
|
+
})]
|
|
5734
|
+
}, group.id);
|
|
5735
|
+
})
|
|
5736
|
+
}),
|
|
5737
|
+
state.status === "ready" && choices.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5738
|
+
className: "dsh-side-chat-model-empty",
|
|
5739
|
+
children: messages.emptyModels
|
|
5740
|
+
})
|
|
5741
|
+
] }),
|
|
5742
|
+
pane === "effort" && (effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5743
|
+
className: "dsh-side-chat-model-empty",
|
|
5744
|
+
children: messages.emptyEfforts
|
|
5745
|
+
}) : effortChoices.map((level) => {
|
|
5746
|
+
const selected = effectiveEffort === level.effort;
|
|
5747
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5748
|
+
ref: itemRef(),
|
|
5749
|
+
type: "button",
|
|
5750
|
+
role: "menuitemradio",
|
|
5751
|
+
"aria-checked": selected,
|
|
5752
|
+
className: `dsh-side-chat-model-option${selected ? " dsh-side-chat-model-selected" : ""}`,
|
|
5753
|
+
disabled: selecting,
|
|
5754
|
+
onClick: () => {
|
|
5755
|
+
chooseEffort(level.effort);
|
|
5756
|
+
},
|
|
5757
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5758
|
+
className: "dsh-side-chat-model-option-copy",
|
|
5759
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5760
|
+
className: "dsh-side-chat-model-name",
|
|
5761
|
+
children: level.label
|
|
5762
|
+
}), level.description !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5763
|
+
className: "dsh-side-chat-model-description",
|
|
5764
|
+
children: level.description
|
|
5765
|
+
})]
|
|
5766
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5767
|
+
className: "dsh-side-chat-model-check",
|
|
5768
|
+
children: selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
|
|
5769
|
+
})]
|
|
5770
|
+
}, level.key);
|
|
5771
|
+
}))
|
|
5772
|
+
]
|
|
5773
|
+
}),
|
|
5774
|
+
toast !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
5775
|
+
text: toast.text,
|
|
5776
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16, {}),
|
|
5777
|
+
anchor: rootRef.current?.closest("[data-composer-card]") ?? null,
|
|
5778
|
+
onDone: () => {
|
|
5779
|
+
setToast(null);
|
|
5780
|
+
}
|
|
5781
|
+
}, toast.seq)
|
|
5782
|
+
]
|
|
5783
|
+
});
|
|
5784
|
+
}
|
|
5785
|
+
//#endregion
|
|
5178
5786
|
//#region src/client/panel/SendIcon.tsx
|
|
5179
5787
|
/** Arrow used by DSH's native 34px primary send button. */
|
|
5180
5788
|
function SendIcon() {
|
|
@@ -5253,7 +5861,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5253
5861
|
}
|
|
5254
5862
|
//#endregion
|
|
5255
5863
|
//#region src/client/panel/SideChatPanel.tsx
|
|
5256
|
-
function SideChatPanel({ state, locale = "en", embeddedConversation, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent, onRemoveSelection }) {
|
|
5864
|
+
function SideChatPanel({ state, locale = "en", embeddedConversation, modelControl, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent, onRemoveSelection }) {
|
|
5257
5865
|
const messages = SIDE_CHAT_MESSAGES[locale];
|
|
5258
5866
|
const [submitting, setSubmitting] = (0, react.useState)(false);
|
|
5259
5867
|
const draftRef = useAutoGrowingTextarea(state.draft);
|
|
@@ -5294,6 +5902,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5294
5902
|
}),
|
|
5295
5903
|
state.childSessionId !== void 0 && embeddedConversation !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SideChatBody, { children: embeddedConversation }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
5296
5904
|
className: "dsh-side-chat-draft",
|
|
5905
|
+
"data-composer-card": "",
|
|
5297
5906
|
onSubmit: (event) => {
|
|
5298
5907
|
submit(event);
|
|
5299
5908
|
},
|
|
@@ -5329,12 +5938,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5329
5938
|
}
|
|
5330
5939
|
}
|
|
5331
5940
|
}),
|
|
5332
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5941
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5942
|
+
className: "dsh-side-chat-draft-actions",
|
|
5943
|
+
children: [modelControl, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5944
|
+
type: "submit",
|
|
5945
|
+
className: "dsh-side-chat-send-button",
|
|
5946
|
+
"aria-label": messages.send,
|
|
5947
|
+
disabled: submitting || state.draft.trim().length === 0,
|
|
5948
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SendIcon, {})
|
|
5949
|
+
})]
|
|
5338
5950
|
})
|
|
5339
5951
|
]
|
|
5340
5952
|
}),
|
|
@@ -5445,14 +6057,280 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5445
6057
|
}
|
|
5446
6058
|
});
|
|
5447
6059
|
}
|
|
6060
|
+
function anchorByKey(root, nodeKey) {
|
|
6061
|
+
return [...root.querySelectorAll("[data-chat-anchor-key]")].find((anchor) => anchor.dataset["chatAnchorKey"] === nodeKey);
|
|
6062
|
+
}
|
|
6063
|
+
function restoreFragmentRanges(root, fragment) {
|
|
6064
|
+
const anchor = anchorByKey(root, fragment.nodeKey);
|
|
6065
|
+
if (anchor === void 0) return;
|
|
6066
|
+
const nodes = acceptedTextNodes(anchor, root);
|
|
6067
|
+
const visibleText = nodes.map((node) => node.data).join("");
|
|
6068
|
+
if (!Number.isSafeInteger(fragment.startOffset) || !Number.isSafeInteger(fragment.endOffset) || fragment.startOffset < 0 || fragment.endOffset <= fragment.startOffset || fragment.endOffset > visibleText.length || visibleText.slice(fragment.startOffset, fragment.endOffset) !== fragment.text) return;
|
|
6069
|
+
const ranges = [];
|
|
6070
|
+
let visibleOffset = 0;
|
|
6071
|
+
for (const node of nodes) {
|
|
6072
|
+
const nodeEnd = visibleOffset + node.data.length;
|
|
6073
|
+
const start = Math.max(fragment.startOffset, visibleOffset) - visibleOffset;
|
|
6074
|
+
const end = Math.min(fragment.endOffset, nodeEnd) - visibleOffset;
|
|
6075
|
+
if (end > start) {
|
|
6076
|
+
const range = document.createRange();
|
|
6077
|
+
range.setStart(node, start);
|
|
6078
|
+
range.setEnd(node, end);
|
|
6079
|
+
ranges.push(range);
|
|
6080
|
+
}
|
|
6081
|
+
visibleOffset = nodeEnd;
|
|
6082
|
+
if (visibleOffset >= fragment.endOffset) break;
|
|
6083
|
+
}
|
|
6084
|
+
return ranges.length === 0 ? void 0 : ranges;
|
|
6085
|
+
}
|
|
6086
|
+
/** Rebuild a saved selection only when its anchored visible text still matches. */
|
|
6087
|
+
function restoreDomConversationSelection(input) {
|
|
6088
|
+
const ranges = [];
|
|
6089
|
+
for (const fragment of input.selection.fragments) {
|
|
6090
|
+
const restored = restoreFragmentRanges(input.conversationRoot, fragment);
|
|
6091
|
+
if (restored === void 0) return;
|
|
6092
|
+
ranges.push(...restored);
|
|
6093
|
+
}
|
|
6094
|
+
const first = ranges[0];
|
|
6095
|
+
const last = ranges.at(-1);
|
|
6096
|
+
if (first === void 0 || last === void 0) return;
|
|
6097
|
+
const browserRange = document.createRange();
|
|
6098
|
+
browserRange.setStart(first.startContainer, first.startOffset);
|
|
6099
|
+
browserRange.setEnd(last.endContainer, last.endOffset);
|
|
6100
|
+
return {
|
|
6101
|
+
ranges,
|
|
6102
|
+
browserRange
|
|
6103
|
+
};
|
|
6104
|
+
}
|
|
6105
|
+
//#endregion
|
|
6106
|
+
//#region src/client/selection/ConversationAnnotationMarkers.tsx
|
|
6107
|
+
const ANNOTATION_HIGHLIGHT = "dsh-side-chat-annotations";
|
|
6108
|
+
const ACTIVE_ANNOTATION_HIGHLIGHT = "dsh-side-chat-active-annotation";
|
|
6109
|
+
function clamp$1(value, minimum, maximum) {
|
|
6110
|
+
return Math.min(Math.max(minimum, value), Math.max(minimum, maximum));
|
|
6111
|
+
}
|
|
6112
|
+
function boundsOf(rect) {
|
|
6113
|
+
const left = Number.isFinite(rect.left) ? rect.left : rect.x;
|
|
6114
|
+
const top = Number.isFinite(rect.top) ? rect.top : rect.y;
|
|
6115
|
+
const right = Number.isFinite(rect.right) ? rect.right : left + rect.width;
|
|
6116
|
+
const bottom = Number.isFinite(rect.bottom) ? rect.bottom : top + rect.height;
|
|
6117
|
+
return [
|
|
6118
|
+
left,
|
|
6119
|
+
top,
|
|
6120
|
+
right,
|
|
6121
|
+
bottom
|
|
6122
|
+
].every(Number.isFinite) ? {
|
|
6123
|
+
left,
|
|
6124
|
+
top,
|
|
6125
|
+
right,
|
|
6126
|
+
bottom
|
|
6127
|
+
} : void 0;
|
|
6128
|
+
}
|
|
6129
|
+
function rangeBounds(ranges) {
|
|
6130
|
+
const boxes = [];
|
|
6131
|
+
for (const range of ranges) {
|
|
6132
|
+
const clientRects = typeof range.getClientRects === "function" ? [...range.getClientRects()] : [];
|
|
6133
|
+
const rects = clientRects.length > 0 ? clientRects : typeof range.getBoundingClientRect === "function" ? [range.getBoundingClientRect()] : [];
|
|
6134
|
+
for (const rect of rects) {
|
|
6135
|
+
const bounds = boundsOf(rect);
|
|
6136
|
+
if (bounds !== void 0 && (bounds.right > bounds.left || bounds.bottom > bounds.top)) boxes.push(bounds);
|
|
6137
|
+
}
|
|
6138
|
+
}
|
|
6139
|
+
if (boxes.length === 0) return;
|
|
6140
|
+
return {
|
|
6141
|
+
left: Math.min(...boxes.map((box) => box.left)),
|
|
6142
|
+
top: Math.min(...boxes.map((box) => box.top)),
|
|
6143
|
+
right: Math.max(...boxes.map((box) => box.right)),
|
|
6144
|
+
bottom: Math.max(...boxes.map((box) => box.bottom))
|
|
6145
|
+
};
|
|
6146
|
+
}
|
|
6147
|
+
function selectionRect(bounds) {
|
|
6148
|
+
return {
|
|
6149
|
+
x: bounds.left,
|
|
6150
|
+
y: bounds.top,
|
|
6151
|
+
width: bounds.right - bounds.left,
|
|
6152
|
+
height: bounds.bottom - bounds.top,
|
|
6153
|
+
viewportWidth: window.innerWidth,
|
|
6154
|
+
viewportHeight: window.innerHeight
|
|
6155
|
+
};
|
|
6156
|
+
}
|
|
6157
|
+
function visibleViewport(range) {
|
|
6158
|
+
let viewport = {
|
|
6159
|
+
left: 0,
|
|
6160
|
+
top: 0,
|
|
6161
|
+
right: window.innerWidth,
|
|
6162
|
+
bottom: window.innerHeight
|
|
6163
|
+
};
|
|
6164
|
+
const start = range.startContainer;
|
|
6165
|
+
const scrollport = (start.nodeType === Node.ELEMENT_NODE ? start : start.parentElement)?.closest("[data-conversation-scroll]");
|
|
6166
|
+
if (scrollport === null || scrollport === void 0) return viewport;
|
|
6167
|
+
const scrollBounds = boundsOf(scrollport.getBoundingClientRect());
|
|
6168
|
+
if (scrollBounds !== void 0 && scrollBounds.right > scrollBounds.left && scrollBounds.bottom > scrollBounds.top) viewport = {
|
|
6169
|
+
left: Math.max(viewport.left, scrollBounds.left),
|
|
6170
|
+
top: Math.max(viewport.top, scrollBounds.top),
|
|
6171
|
+
right: Math.min(viewport.right, scrollBounds.right),
|
|
6172
|
+
bottom: Math.min(viewport.bottom, scrollBounds.bottom)
|
|
6173
|
+
};
|
|
6174
|
+
const composer = scrollport.querySelector("[data-composer-seat]");
|
|
6175
|
+
const composerBounds = composer === null ? void 0 : boundsOf(composer.getBoundingClientRect());
|
|
6176
|
+
if (composerBounds !== void 0 && composerBounds.right > composerBounds.left && composerBounds.bottom > composerBounds.top && composerBounds.bottom > viewport.top && composerBounds.top < viewport.bottom) viewport = {
|
|
6177
|
+
...viewport,
|
|
6178
|
+
bottom: Math.min(viewport.bottom, composerBounds.top)
|
|
6179
|
+
};
|
|
6180
|
+
return viewport;
|
|
6181
|
+
}
|
|
6182
|
+
function intersects(bounds, viewport) {
|
|
6183
|
+
return bounds.right > viewport.left && bounds.bottom > viewport.top && bounds.left < viewport.right && bounds.top < viewport.bottom;
|
|
6184
|
+
}
|
|
6185
|
+
function markerPositionsEqual(previous, next) {
|
|
6186
|
+
return previous.length === next.length && previous.every((position, index) => {
|
|
6187
|
+
const candidate = next[index];
|
|
6188
|
+
return candidate !== void 0 && candidate.annotationIndex === position.annotationIndex && candidate.left === position.left && candidate.top === position.top;
|
|
6189
|
+
});
|
|
6190
|
+
}
|
|
6191
|
+
function clearHighlights() {
|
|
6192
|
+
if (typeof CSS === "undefined" || CSS.highlights === void 0) return;
|
|
6193
|
+
CSS.highlights.delete(ANNOTATION_HIGHLIGHT);
|
|
6194
|
+
CSS.highlights.delete(ACTIVE_ANNOTATION_HIGHLIGHT);
|
|
6195
|
+
}
|
|
6196
|
+
function publishHighlights(ranges, activeRanges) {
|
|
6197
|
+
if (typeof CSS === "undefined" || CSS.highlights === void 0 || typeof Highlight === "undefined") return;
|
|
6198
|
+
CSS.highlights.set(ANNOTATION_HIGHLIGHT, new Highlight(...ranges));
|
|
6199
|
+
if (activeRanges.length === 0) {
|
|
6200
|
+
CSS.highlights.delete(ACTIVE_ANNOTATION_HIGHLIGHT);
|
|
6201
|
+
return;
|
|
6202
|
+
}
|
|
6203
|
+
const active = new Highlight(...activeRanges);
|
|
6204
|
+
active.priority = 1;
|
|
6205
|
+
CSS.highlights.set(ACTIVE_ANNOTATION_HIGHLIGHT, active);
|
|
6206
|
+
}
|
|
6207
|
+
function restoreBrowserSelection(range) {
|
|
6208
|
+
const browserSelection = window.getSelection();
|
|
6209
|
+
if (browserSelection === null) return;
|
|
6210
|
+
browserSelection.removeAllRanges();
|
|
6211
|
+
browserSelection.addRange(range);
|
|
6212
|
+
}
|
|
6213
|
+
/** Persistent source markers for unsent parent-composer annotations. */
|
|
6214
|
+
function ConversationAnnotationMarkers({ annotations, activeAnnotationIndex, onEdit }) {
|
|
6215
|
+
const resolvedRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
6216
|
+
const [positions, setPositions] = (0, react.useState)([]);
|
|
6217
|
+
(0, react.useEffect)(() => {
|
|
6218
|
+
if (annotations.length === 0) {
|
|
6219
|
+
resolvedRef.current.clear();
|
|
6220
|
+
setPositions((previous) => previous.length === 0 ? previous : []);
|
|
6221
|
+
clearHighlights();
|
|
6222
|
+
return;
|
|
6223
|
+
}
|
|
6224
|
+
let animationFrame;
|
|
6225
|
+
let observedConversationRoot = null;
|
|
6226
|
+
let resizeObserver;
|
|
6227
|
+
const refresh = () => {
|
|
6228
|
+
animationFrame = void 0;
|
|
6229
|
+
const conversationRoot = document.querySelector("[data-chat-flow]");
|
|
6230
|
+
if (conversationRoot !== observedConversationRoot) {
|
|
6231
|
+
resizeObserver?.disconnect();
|
|
6232
|
+
observedConversationRoot = conversationRoot;
|
|
6233
|
+
if (conversationRoot !== null) resizeObserver?.observe(conversationRoot);
|
|
6234
|
+
}
|
|
6235
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
6236
|
+
const nextPositions = [];
|
|
6237
|
+
const highlightRanges = [];
|
|
6238
|
+
const activeRanges = [];
|
|
6239
|
+
if (conversationRoot !== null) for (const annotation of annotations) {
|
|
6240
|
+
const restored = restoreDomConversationSelection({
|
|
6241
|
+
selection: annotation.selection,
|
|
6242
|
+
conversationRoot
|
|
6243
|
+
});
|
|
6244
|
+
if (restored === void 0) continue;
|
|
6245
|
+
highlightRanges.push(...restored.ranges);
|
|
6246
|
+
if (annotation.annotationIndex === activeAnnotationIndex) activeRanges.push(...restored.ranges);
|
|
6247
|
+
const bounds = rangeBounds(restored.ranges);
|
|
6248
|
+
const viewport = visibleViewport(restored.browserRange);
|
|
6249
|
+
if (bounds === void 0 || !intersects(bounds, viewport)) continue;
|
|
6250
|
+
const rect = selectionRect(bounds);
|
|
6251
|
+
resolved.set(annotation.annotationIndex, {
|
|
6252
|
+
browserRange: restored.browserRange,
|
|
6253
|
+
rect
|
|
6254
|
+
});
|
|
6255
|
+
nextPositions.push({
|
|
6256
|
+
annotationIndex: annotation.annotationIndex,
|
|
6257
|
+
left: clamp$1(bounds.right + 3, viewport.left + 4, viewport.right - 26),
|
|
6258
|
+
top: clamp$1(bounds.top - 12, viewport.top + 4, viewport.bottom - 26)
|
|
6259
|
+
});
|
|
6260
|
+
}
|
|
6261
|
+
resolvedRef.current = resolved;
|
|
6262
|
+
setPositions((previous) => markerPositionsEqual(previous, nextPositions) ? previous : nextPositions);
|
|
6263
|
+
publishHighlights(highlightRanges, activeRanges);
|
|
6264
|
+
};
|
|
6265
|
+
const scheduleRefresh = () => {
|
|
6266
|
+
if (animationFrame !== void 0) return;
|
|
6267
|
+
animationFrame = window.requestAnimationFrame(refresh);
|
|
6268
|
+
};
|
|
6269
|
+
resizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(scheduleRefresh);
|
|
6270
|
+
refresh();
|
|
6271
|
+
const mutationObserver = new MutationObserver(scheduleRefresh);
|
|
6272
|
+
mutationObserver.observe(document.body, {
|
|
6273
|
+
childList: true,
|
|
6274
|
+
characterData: true,
|
|
6275
|
+
subtree: true
|
|
6276
|
+
});
|
|
6277
|
+
document.addEventListener("scroll", scheduleRefresh, true);
|
|
6278
|
+
window.addEventListener("resize", scheduleRefresh);
|
|
6279
|
+
return () => {
|
|
6280
|
+
if (animationFrame !== void 0) window.cancelAnimationFrame(animationFrame);
|
|
6281
|
+
mutationObserver?.disconnect();
|
|
6282
|
+
resizeObserver?.disconnect();
|
|
6283
|
+
document.removeEventListener("scroll", scheduleRefresh, true);
|
|
6284
|
+
window.removeEventListener("resize", scheduleRefresh);
|
|
6285
|
+
clearHighlights();
|
|
6286
|
+
};
|
|
6287
|
+
}, [activeAnnotationIndex, annotations]);
|
|
6288
|
+
return positions.map((position) => {
|
|
6289
|
+
const annotation = annotations.find((candidate) => candidate.annotationIndex === position.annotationIndex);
|
|
6290
|
+
if (annotation === void 0) return null;
|
|
6291
|
+
const style = {
|
|
6292
|
+
left: position.left,
|
|
6293
|
+
top: position.top
|
|
6294
|
+
};
|
|
6295
|
+
const number = annotation.annotationIndex + 1;
|
|
6296
|
+
const badge = number > 99 ? "99+" : String(number);
|
|
6297
|
+
const activate = () => {
|
|
6298
|
+
const resolved = resolvedRef.current.get(annotation.annotationIndex);
|
|
6299
|
+
if (resolved === void 0) return;
|
|
6300
|
+
restoreBrowserSelection(resolved.browserRange);
|
|
6301
|
+
onEdit(annotation, {
|
|
6302
|
+
...annotation.selection,
|
|
6303
|
+
rect: resolved.rect
|
|
6304
|
+
});
|
|
6305
|
+
window.requestAnimationFrame(() => {
|
|
6306
|
+
restoreBrowserSelection(resolved.browserRange);
|
|
6307
|
+
});
|
|
6308
|
+
};
|
|
6309
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6310
|
+
type: "button",
|
|
6311
|
+
className: "dsh-side-chat-annotation-marker",
|
|
6312
|
+
style,
|
|
6313
|
+
"data-active": annotation.annotationIndex === activeAnnotationIndex || void 0,
|
|
6314
|
+
"data-large": number > 99 || void 0,
|
|
6315
|
+
"aria-label": `Edit annotation ${String(number)}`,
|
|
6316
|
+
title: `Edit annotation ${String(number)}`,
|
|
6317
|
+
onMouseDown: (event) => {
|
|
6318
|
+
event.preventDefault();
|
|
6319
|
+
event.stopPropagation();
|
|
6320
|
+
},
|
|
6321
|
+
onClick: activate,
|
|
6322
|
+
children: badge
|
|
6323
|
+
}, `${annotation.selection.parentSessionId}:${annotation.selection.fragments[0]?.nodeKey ?? ""}:${String(annotation.annotationIndex)}`);
|
|
6324
|
+
});
|
|
6325
|
+
}
|
|
5448
6326
|
//#endregion
|
|
5449
6327
|
//#region src/client/selection/SelectionActions.tsx
|
|
5450
6328
|
function clamp(value, minimum, maximum) {
|
|
5451
6329
|
return Math.min(Math.max(minimum, value), Math.max(minimum, maximum));
|
|
5452
6330
|
}
|
|
5453
|
-
function SelectionActions({ selection, askDisabledReason, annotationNumber = 1, onAddToChat, onMoreDetails, onAskInSideChat, onAnnotationEditorChange, onDismiss }) {
|
|
5454
|
-
const [editingAnnotation, setEditingAnnotation] = (0, react.useState)(
|
|
5455
|
-
const [comment, setComment] = (0, react.useState)("");
|
|
6331
|
+
function SelectionActions({ selection, askDisabledReason, annotationNumber = 1, annotationEditor, onAddToChat, onMoreDetails, onAskInSideChat, onAnnotationEditorChange, onDismiss }) {
|
|
6332
|
+
const [editingAnnotation, setEditingAnnotation] = (0, react.useState)(annotationEditor !== void 0);
|
|
6333
|
+
const [comment, setComment] = (0, react.useState)(annotationEditor?.initialComment ?? "");
|
|
5456
6334
|
const commentRef = (0, react.useRef)(null);
|
|
5457
6335
|
const center = selection.rect.x + selection.rect.width / 2;
|
|
5458
6336
|
const style = {
|
|
@@ -5468,9 +6346,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5468
6346
|
width: editorWidth
|
|
5469
6347
|
};
|
|
5470
6348
|
const markerStyle = {
|
|
5471
|
-
left: clamp(selection.rect.x + selection.rect.width
|
|
5472
|
-
top: selection.rect.y
|
|
6349
|
+
left: clamp(selection.rect.x + selection.rect.width + 3, 4, selection.rect.viewportWidth - 26),
|
|
6350
|
+
top: clamp(selection.rect.y - 12, 4, selection.rect.viewportHeight - 26)
|
|
5473
6351
|
};
|
|
6352
|
+
const markerNumber = annotationNumber > 99 ? "99+" : String(annotationNumber);
|
|
5474
6353
|
const keepSelection = (event) => {
|
|
5475
6354
|
event.preventDefault();
|
|
5476
6355
|
};
|
|
@@ -5481,6 +6360,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5481
6360
|
setEditingAnnotation(false);
|
|
5482
6361
|
setComment("");
|
|
5483
6362
|
onAnnotationEditorChange?.(false);
|
|
6363
|
+
if (annotationEditor !== void 0) onDismiss();
|
|
5484
6364
|
};
|
|
5485
6365
|
const saveAnnotation = () => {
|
|
5486
6366
|
const trimmed = comment.trim();
|
|
@@ -5504,15 +6384,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5504
6384
|
saveAnnotation();
|
|
5505
6385
|
}
|
|
5506
6386
|
};
|
|
5507
|
-
if (editingAnnotation) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6387
|
+
if (editingAnnotation) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [annotationEditor === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5508
6388
|
className: "dsh-side-chat-selection-marker",
|
|
5509
6389
|
"aria-hidden": "true",
|
|
6390
|
+
"data-large": annotationNumber > 99 || void 0,
|
|
5510
6391
|
style: markerStyle,
|
|
5511
|
-
children:
|
|
6392
|
+
children: markerNumber
|
|
5512
6393
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
5513
6394
|
className: "dsh-side-chat-selection-comment",
|
|
5514
6395
|
role: "dialog",
|
|
5515
|
-
"aria-label": "Add annotation comment",
|
|
6396
|
+
"aria-label": annotationEditor?.dialogLabel ?? "Add annotation comment",
|
|
5516
6397
|
style: editorStyle,
|
|
5517
6398
|
onSubmit: submitAnnotation,
|
|
5518
6399
|
onMouseDown: (event) => {
|
|
@@ -5656,7 +6537,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5656
6537
|
function booleanValue(value) {
|
|
5657
6538
|
return typeof value === "boolean" ? value : void 0;
|
|
5658
6539
|
}
|
|
5659
|
-
function firstLine(text) {
|
|
6540
|
+
function firstLine$1(text) {
|
|
5660
6541
|
const newline = text.indexOf("\n");
|
|
5661
6542
|
return newline === -1 ? text : text.slice(0, newline);
|
|
5662
6543
|
}
|
|
@@ -5718,7 +6599,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5718
6599
|
}
|
|
5719
6600
|
function summaryFromArguments(name, variant, argsRaw, callId, cwd) {
|
|
5720
6601
|
const args = parseArguments(argsRaw);
|
|
5721
|
-
const base = relativizeToCwd(firstLine((args === null ? void 0 : pickArgument(args, SUMMARY_KEYS[variant])) ?? (argsRaw === "" || argsRaw === "{}" ? callId : argsRaw)), cwd);
|
|
6602
|
+
const base = relativizeToCwd(firstLine$1((args === null ? void 0 : pickArgument(args, SUMMARY_KEYS[variant])) ?? (argsRaw === "" || argsRaw === "{}" ? callId : argsRaw)), cwd);
|
|
5722
6603
|
return variant === "others" && name !== "" ? `${name} · ${base}` : base;
|
|
5723
6604
|
}
|
|
5724
6605
|
function filePathFromArguments(variant, argsRaw) {
|
|
@@ -5956,7 +6837,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5956
6837
|
const code = variant === "code" && args !== null ? stringValue(args["code"]) : void 0;
|
|
5957
6838
|
const body = genericBody(variant, argsRaw);
|
|
5958
6839
|
const summary = terminal?.description ?? stringValue(record(resultView)?.["title"]) ?? summaryFromArguments(name, variant, argsRaw, callId, cwd);
|
|
5959
|
-
const failureLine = visualState === "error" && output !== void 0 ? firstLine(output) : null;
|
|
6840
|
+
const failureLine = visualState === "error" && output !== void 0 ? firstLine$1(output) : null;
|
|
5960
6841
|
const summaryText = failureLine ?? summary;
|
|
5961
6842
|
const expandable = terminal !== null || read !== null || search !== null || diffs !== null || web !== null || code !== void 0 || body !== null || output !== void 0;
|
|
5962
6843
|
const open = expanded && expandable;
|
|
@@ -6116,16 +6997,102 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6116
6997
|
function firstSideChatQuestion(text) {
|
|
6117
6998
|
return /<user_question>([\s\S]*?)<\/user_question>/u.exec(text)?.[1]?.trim() ?? text;
|
|
6118
6999
|
}
|
|
6119
|
-
function
|
|
7000
|
+
function firstLine(text) {
|
|
7001
|
+
const newline = text.indexOf("\n");
|
|
7002
|
+
return newline === -1 ? text : text.slice(0, newline);
|
|
7003
|
+
}
|
|
7004
|
+
function latestLine(text) {
|
|
7005
|
+
const visible = text.trimEnd();
|
|
7006
|
+
const newline = visible.lastIndexOf("\n");
|
|
7007
|
+
return newline === -1 ? visible : visible.slice(newline + 1);
|
|
7008
|
+
}
|
|
7009
|
+
function useThrottledVisualUpdate(update, intervalFrames = 3) {
|
|
7010
|
+
const updateRef = (0, react.useRef)(update);
|
|
7011
|
+
updateRef.current = update;
|
|
7012
|
+
const pendingFrameRef = (0, react.useRef)(null);
|
|
7013
|
+
(0, react.useLayoutEffect)(() => () => {
|
|
7014
|
+
if (pendingFrameRef.current === null) return;
|
|
7015
|
+
cancelAnimationFrame(pendingFrameRef.current);
|
|
7016
|
+
pendingFrameRef.current = null;
|
|
7017
|
+
}, []);
|
|
7018
|
+
return (0, react.useCallback)(() => {
|
|
7019
|
+
if (pendingFrameRef.current !== null) return;
|
|
7020
|
+
let remainingFrames = intervalFrames;
|
|
7021
|
+
const advance = () => {
|
|
7022
|
+
remainingFrames -= 1;
|
|
7023
|
+
if (remainingFrames > 0) {
|
|
7024
|
+
pendingFrameRef.current = requestAnimationFrame(advance);
|
|
7025
|
+
return;
|
|
7026
|
+
}
|
|
7027
|
+
pendingFrameRef.current = null;
|
|
7028
|
+
updateRef.current();
|
|
7029
|
+
};
|
|
7030
|
+
pendingFrameRef.current = requestAnimationFrame(advance);
|
|
7031
|
+
}, [intervalFrames]);
|
|
7032
|
+
}
|
|
7033
|
+
function ReasoningRow({ text, running, locale }) {
|
|
7034
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
7035
|
+
const summaryRef = (0, react.useRef)(null);
|
|
7036
|
+
const summary = running ? latestLine(text) : firstLine(text);
|
|
7037
|
+
const scheduleSummaryScroll = useThrottledVisualUpdate(() => {
|
|
7038
|
+
const element = summaryRef.current;
|
|
7039
|
+
if (element === null) return;
|
|
7040
|
+
element.scrollLeft = running ? element.scrollWidth - element.clientWidth : 0;
|
|
7041
|
+
});
|
|
7042
|
+
(0, react.useEffect)(() => {
|
|
7043
|
+
scheduleSummaryScroll();
|
|
7044
|
+
}, [
|
|
7045
|
+
running,
|
|
7046
|
+
scheduleSummaryScroll,
|
|
7047
|
+
summary
|
|
7048
|
+
]);
|
|
7049
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7050
|
+
className: "dsh-side-chat-reasoning",
|
|
7051
|
+
"data-variant": "think",
|
|
7052
|
+
"data-state": running ? "running" : "ok",
|
|
7053
|
+
children: [running && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7054
|
+
className: "dsh-side-chat-reasoning-visually-hidden",
|
|
7055
|
+
children: locale === "zh-CN" ? "运行中" : "Running"
|
|
7056
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
7057
|
+
rowClassName: "dsh-side-chat-reasoning-row",
|
|
7058
|
+
leadingClassName: "dsh-side-chat-reasoning-leading",
|
|
7059
|
+
titleClassName: "dsh-side-chat-reasoning-title",
|
|
7060
|
+
chevronClassName: "dsh-side-chat-reasoning-chevron",
|
|
7061
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutline14, { size: 14 }),
|
|
7062
|
+
title: "Think",
|
|
7063
|
+
open: expanded,
|
|
7064
|
+
expandable: true,
|
|
7065
|
+
expandOnRowClick: true,
|
|
7066
|
+
onToggle: () => {
|
|
7067
|
+
setExpanded((value) => !value);
|
|
7068
|
+
},
|
|
7069
|
+
collapsedContent: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7070
|
+
className: "dsh-side-chat-reasoning-separator",
|
|
7071
|
+
"aria-hidden": "true"
|
|
7072
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7073
|
+
ref: summaryRef,
|
|
7074
|
+
className: "dsh-side-chat-reasoning-summary",
|
|
7075
|
+
"data-follow-end": running || void 0,
|
|
7076
|
+
children: summary
|
|
7077
|
+
})] }),
|
|
7078
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7079
|
+
className: "dsh-side-chat-reasoning-body",
|
|
7080
|
+
children: text
|
|
7081
|
+
})
|
|
7082
|
+
})]
|
|
7083
|
+
});
|
|
7084
|
+
}
|
|
7085
|
+
function AssistantBlocks({ blocks, streaming = false, projectedToolCallIds, unprojectedToolState = "pending", cwd, locale }) {
|
|
6120
7086
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: blocks.map((block, index) => {
|
|
6121
7087
|
const key = `${block.kind}-${String(index)}`;
|
|
6122
7088
|
if (block.kind === "text") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
6123
7089
|
text: block.text,
|
|
6124
7090
|
streaming
|
|
6125
7091
|
}, key);
|
|
6126
|
-
if (block.kind === "reasoning") return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6127
|
-
|
|
6128
|
-
|
|
7092
|
+
if (block.kind === "reasoning") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningRow, {
|
|
7093
|
+
text: block.text,
|
|
7094
|
+
running: streaming && index === blocks.length - 1,
|
|
7095
|
+
locale
|
|
6129
7096
|
}, key);
|
|
6130
7097
|
if (block.kind === "image") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: "[Image attachment]" }, key);
|
|
6131
7098
|
if (block.kind === "tool-call") {
|
|
@@ -6141,7 +7108,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6141
7108
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: stringify(block.block) }, key);
|
|
6142
7109
|
}) });
|
|
6143
7110
|
}
|
|
6144
|
-
function MessageRow({ node, projectedToolCallIds, cwd }) {
|
|
7111
|
+
function MessageRow({ node, projectedToolCallIds, cwd, locale }) {
|
|
6145
7112
|
if (node.kind === "user" || node.kind === "steering") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
6146
7113
|
className: "dsh-side-chat-message",
|
|
6147
7114
|
"data-role": "user",
|
|
@@ -6165,7 +7132,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6165
7132
|
blocks: node.blocks,
|
|
6166
7133
|
projectedToolCallIds,
|
|
6167
7134
|
unprojectedToolState: node.interrupted === true ? "interrupted" : "pending",
|
|
6168
|
-
cwd
|
|
7135
|
+
cwd,
|
|
7136
|
+
locale
|
|
6169
7137
|
}),
|
|
6170
7138
|
node.interrupted === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6171
7139
|
className: "dsh-side-chat-message-note",
|
|
@@ -6350,7 +7318,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6350
7318
|
});
|
|
6351
7319
|
}
|
|
6352
7320
|
/** Functional rc.6 conversation surface bound to a non-current child Session. */
|
|
6353
|
-
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en", cwd }) {
|
|
7321
|
+
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en", cwd, modelControl }) {
|
|
6354
7322
|
const snapshot = (0, react.useSyncExternalStore)((listener) => face.subscribe(listener), () => face.getSnapshot(), () => face.getSnapshot());
|
|
6355
7323
|
const [draft, setDraft] = (0, react.useState)("");
|
|
6356
7324
|
const [sending, setSending] = (0, react.useState)(false);
|
|
@@ -6404,12 +7372,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6404
7372
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, {
|
|
6405
7373
|
node,
|
|
6406
7374
|
projectedToolCallIds,
|
|
6407
|
-
cwd
|
|
7375
|
+
cwd,
|
|
7376
|
+
locale
|
|
6408
7377
|
})]
|
|
6409
7378
|
}, `${node.kind}-${String(node.seq)}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, {
|
|
6410
7379
|
node,
|
|
6411
7380
|
projectedToolCallIds,
|
|
6412
|
-
cwd
|
|
7381
|
+
cwd,
|
|
7382
|
+
locale
|
|
6413
7383
|
}, `${node.kind}-${String(node.seq)}`)),
|
|
6414
7384
|
snapshot.partial !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
6415
7385
|
className: "dsh-side-chat-message",
|
|
@@ -6422,7 +7392,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6422
7392
|
streaming: true,
|
|
6423
7393
|
projectedToolCallIds,
|
|
6424
7394
|
unprojectedToolState: "running",
|
|
6425
|
-
cwd
|
|
7395
|
+
cwd,
|
|
7396
|
+
locale
|
|
6426
7397
|
})]
|
|
6427
7398
|
}),
|
|
6428
7399
|
runningCalls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RunningToolCard, {
|
|
@@ -6445,6 +7416,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6445
7416
|
]
|
|
6446
7417
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
6447
7418
|
className: "dsh-side-chat-composer",
|
|
7419
|
+
"data-composer-card": "",
|
|
6448
7420
|
onSubmit: (event) => {
|
|
6449
7421
|
submit(event);
|
|
6450
7422
|
},
|
|
@@ -6462,22 +7434,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6462
7434
|
event.currentTarget.form?.requestSubmit();
|
|
6463
7435
|
}
|
|
6464
7436
|
}
|
|
6465
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
7437
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7438
|
+
className: "dsh-side-chat-composer-actions",
|
|
7439
|
+
children: [modelControl, snapshot.running ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7440
|
+
type: "button",
|
|
7441
|
+
className: "dsh-side-chat-stop-button",
|
|
7442
|
+
"aria-label": "Stop generating",
|
|
7443
|
+
title: "Stop generating",
|
|
7444
|
+
onClick: () => {
|
|
7445
|
+
controller.cancel();
|
|
7446
|
+
},
|
|
7447
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StopIcon, {})
|
|
7448
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7449
|
+
type: "submit",
|
|
7450
|
+
className: "dsh-side-chat-send-button",
|
|
7451
|
+
"aria-label": "Send",
|
|
7452
|
+
disabled: sending || draft.trim().length === 0,
|
|
7453
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SendIcon, {})
|
|
7454
|
+
})]
|
|
7455
|
+
})]
|
|
6481
7456
|
})]
|
|
6482
7457
|
});
|
|
6483
7458
|
}
|
|
@@ -6487,6 +7462,138 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6487
7462
|
return value;
|
|
6488
7463
|
}
|
|
6489
7464
|
//#endregion
|
|
7465
|
+
//#region src/client/parent-composer/annotation-persistence.ts
|
|
7466
|
+
const STORAGE_PREFIX = "dsh-side-chat:composer-annotations:";
|
|
7467
|
+
function browserSessionStorage() {
|
|
7468
|
+
if (typeof window === "undefined") return;
|
|
7469
|
+
try {
|
|
7470
|
+
return window.sessionStorage;
|
|
7471
|
+
} catch {
|
|
7472
|
+
return;
|
|
7473
|
+
}
|
|
7474
|
+
}
|
|
7475
|
+
function storageKey(sessionId) {
|
|
7476
|
+
return `${STORAGE_PREFIX}${encodeURIComponent(sessionId)}`;
|
|
7477
|
+
}
|
|
7478
|
+
function recordOf(snapshot) {
|
|
7479
|
+
const ref = conversationAnnotationReference(snapshot);
|
|
7480
|
+
return ref === void 0 ? void 0 : {
|
|
7481
|
+
version: 1,
|
|
7482
|
+
draft: snapshot.draft,
|
|
7483
|
+
ref
|
|
7484
|
+
};
|
|
7485
|
+
}
|
|
7486
|
+
/** Tab-scoped recovery for rc.6 drafts that persist U+FFFC without occurrences. */
|
|
7487
|
+
var ConversationAnnotationPersistence = class {
|
|
7488
|
+
storage;
|
|
7489
|
+
observedSessions = /* @__PURE__ */ new Set();
|
|
7490
|
+
constructor(storage = browserSessionStorage()) {
|
|
7491
|
+
this.storage = storage;
|
|
7492
|
+
}
|
|
7493
|
+
reconcile(sessionId, input) {
|
|
7494
|
+
const key = storageKey(sessionId);
|
|
7495
|
+
const snapshot = input.state.getSnapshot();
|
|
7496
|
+
const current = recordOf(snapshot);
|
|
7497
|
+
if (current !== void 0) {
|
|
7498
|
+
this.observedSessions.add(key);
|
|
7499
|
+
this.write(key, current);
|
|
7500
|
+
return;
|
|
7501
|
+
}
|
|
7502
|
+
const stored = this.read(key);
|
|
7503
|
+
if (stored !== void 0 && snapshot.draft === stored.draft) {
|
|
7504
|
+
this.observedSessions.add(key);
|
|
7505
|
+
if (restoreConversationAnnotationReference(input, stored.ref)) return;
|
|
7506
|
+
this.remove(key);
|
|
7507
|
+
removeOrphanedConversationAnnotationPlaceholder(input);
|
|
7508
|
+
return;
|
|
7509
|
+
}
|
|
7510
|
+
if (this.observedSessions.has(key)) {
|
|
7511
|
+
this.remove(key);
|
|
7512
|
+
removeOrphanedConversationAnnotationPlaceholder(input);
|
|
7513
|
+
return;
|
|
7514
|
+
}
|
|
7515
|
+
if (stored !== void 0 && snapshot.draft === "") return;
|
|
7516
|
+
if (stored !== void 0) this.remove(key);
|
|
7517
|
+
removeOrphanedConversationAnnotationPlaceholder(input);
|
|
7518
|
+
}
|
|
7519
|
+
read(key) {
|
|
7520
|
+
if (this.storage === void 0) return;
|
|
7521
|
+
try {
|
|
7522
|
+
const raw = this.storage.getItem(key);
|
|
7523
|
+
if (raw === null) return;
|
|
7524
|
+
const value = JSON.parse(raw);
|
|
7525
|
+
return value.version === 1 && typeof value.draft === "string" && typeof value.ref === "string" ? {
|
|
7526
|
+
version: 1,
|
|
7527
|
+
draft: value.draft,
|
|
7528
|
+
ref: value.ref
|
|
7529
|
+
} : void 0;
|
|
7530
|
+
} catch {
|
|
7531
|
+
return;
|
|
7532
|
+
}
|
|
7533
|
+
}
|
|
7534
|
+
write(key, record) {
|
|
7535
|
+
if (this.storage === void 0) return;
|
|
7536
|
+
try {
|
|
7537
|
+
this.storage.setItem(key, JSON.stringify(record));
|
|
7538
|
+
} catch {}
|
|
7539
|
+
}
|
|
7540
|
+
remove(key) {
|
|
7541
|
+
if (this.storage === void 0) return;
|
|
7542
|
+
try {
|
|
7543
|
+
this.storage.removeItem(key);
|
|
7544
|
+
} catch {}
|
|
7545
|
+
}
|
|
7546
|
+
};
|
|
7547
|
+
//#endregion
|
|
7548
|
+
//#region src/client/model-preference.ts
|
|
7549
|
+
const STORAGE_KEY = "dsh-side-chat:model-preference:v1";
|
|
7550
|
+
function browserLocalStorage() {
|
|
7551
|
+
if (typeof window === "undefined") return;
|
|
7552
|
+
try {
|
|
7553
|
+
return window.localStorage;
|
|
7554
|
+
} catch {
|
|
7555
|
+
return;
|
|
7556
|
+
}
|
|
7557
|
+
}
|
|
7558
|
+
function modelSelection(value) {
|
|
7559
|
+
if (typeof value !== "object" || value === null) return;
|
|
7560
|
+
const candidate = value;
|
|
7561
|
+
if (typeof candidate.provider !== "string" || candidate.provider === "" || typeof candidate.model !== "string" || candidate.model === "" || candidate.reasoningEffort !== void 0 && (typeof candidate.reasoningEffort !== "string" || candidate.reasoningEffort === "")) return;
|
|
7562
|
+
return {
|
|
7563
|
+
provider: candidate.provider,
|
|
7564
|
+
model: candidate.model,
|
|
7565
|
+
...candidate.reasoningEffort === void 0 ? {} : { reasoningEffort: candidate.reasoningEffort }
|
|
7566
|
+
};
|
|
7567
|
+
}
|
|
7568
|
+
/** Browser-persistent default shared by every Side Chat in this DSH profile. */
|
|
7569
|
+
var SideChatModelPreferences = class {
|
|
7570
|
+
storage;
|
|
7571
|
+
constructor(storage = browserLocalStorage()) {
|
|
7572
|
+
this.storage = storage;
|
|
7573
|
+
}
|
|
7574
|
+
get() {
|
|
7575
|
+
if (this.storage === void 0) return;
|
|
7576
|
+
try {
|
|
7577
|
+
const raw = this.storage.getItem(STORAGE_KEY);
|
|
7578
|
+
if (raw === null) return;
|
|
7579
|
+
const parsed = JSON.parse(raw);
|
|
7580
|
+
return parsed.version === 1 ? modelSelection(parsed.selection) : void 0;
|
|
7581
|
+
} catch {
|
|
7582
|
+
return;
|
|
7583
|
+
}
|
|
7584
|
+
}
|
|
7585
|
+
set(selection) {
|
|
7586
|
+
if (this.storage === void 0) return;
|
|
7587
|
+
const preference = {
|
|
7588
|
+
version: 1,
|
|
7589
|
+
selection: { ...selection }
|
|
7590
|
+
};
|
|
7591
|
+
try {
|
|
7592
|
+
this.storage.setItem(STORAGE_KEY, JSON.stringify(preference));
|
|
7593
|
+
} catch {}
|
|
7594
|
+
}
|
|
7595
|
+
};
|
|
7596
|
+
//#endregion
|
|
6490
7597
|
//#region src/client/rc6/sessions-adapter.ts
|
|
6491
7598
|
const BINDING_WAIT_MS = 8e3;
|
|
6492
7599
|
function sideChatError(error, fallback) {
|
|
@@ -6628,11 +7735,35 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6628
7735
|
var Rc6SideChatSessions = class {
|
|
6629
7736
|
ctx;
|
|
6630
7737
|
renamed = /* @__PURE__ */ new Set();
|
|
7738
|
+
annotationPersistence = new ConversationAnnotationPersistence();
|
|
7739
|
+
modelPreferences = new SideChatModelPreferences();
|
|
6631
7740
|
constructor(ctx) {
|
|
6632
7741
|
this.ctx = ctx;
|
|
6633
7742
|
}
|
|
6634
7743
|
/** Observable rc.6 Session-list surface used to follow main-session switches. */
|
|
6635
7744
|
subscribeList = (listener) => this.ctx.sessions.list.subscribe(listener);
|
|
7745
|
+
/** Follow both current-session switches and that session's composer state. */
|
|
7746
|
+
subscribeConversationInput = (listener) => {
|
|
7747
|
+
let input;
|
|
7748
|
+
let removeInputListener = () => {};
|
|
7749
|
+
const bindInput = () => {
|
|
7750
|
+
const next = this.currentParentInput();
|
|
7751
|
+
if (next === input) return;
|
|
7752
|
+
removeInputListener();
|
|
7753
|
+
input = next;
|
|
7754
|
+
removeInputListener = input?.state.subscribe?.(listener) ?? (() => {});
|
|
7755
|
+
};
|
|
7756
|
+
bindInput();
|
|
7757
|
+
const removeListListener = this.ctx.sessions.list.subscribe(() => {
|
|
7758
|
+
bindInput();
|
|
7759
|
+
listener();
|
|
7760
|
+
});
|
|
7761
|
+
return () => {
|
|
7762
|
+
removeListListener();
|
|
7763
|
+
removeInputListener();
|
|
7764
|
+
};
|
|
7765
|
+
};
|
|
7766
|
+
currentConversationInputSnapshot = () => this.currentParentInput()?.state.getSnapshot();
|
|
6636
7767
|
currentSessionId() {
|
|
6637
7768
|
const current = this.ctx.sessions.list.getSnapshot().current;
|
|
6638
7769
|
return current === void 0 ? void 0 : SessionId(current);
|
|
@@ -6653,25 +7784,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6653
7784
|
/** Add one selected passage to the native composer of its parent Session. */
|
|
6654
7785
|
addSelectionToConversation(selection, comment) {
|
|
6655
7786
|
if (this.currentSessionId() !== selection.parentSessionId) return false;
|
|
6656
|
-
const
|
|
6657
|
-
if (
|
|
6658
|
-
|
|
7787
|
+
const input = this.currentParentInput();
|
|
7788
|
+
if (input === void 0 || !addSelectionToConversation(input, selection, comment)) return false;
|
|
7789
|
+
this.annotationPersistence.reconcile(selection.parentSessionId, input);
|
|
7790
|
+
return true;
|
|
7791
|
+
}
|
|
7792
|
+
/** Update an existing unsent annotation without adding a duplicate passage. */
|
|
7793
|
+
updateConversationAnnotation(annotationIndex, comment) {
|
|
7794
|
+
const sessionId = this.currentSessionId();
|
|
7795
|
+
const input = this.currentParentInput();
|
|
7796
|
+
if (sessionId === void 0 || input === void 0 || !updateConversationAnnotation(input, annotationIndex, comment)) return false;
|
|
7797
|
+
this.annotationPersistence.reconcile(sessionId, input);
|
|
7798
|
+
return true;
|
|
7799
|
+
}
|
|
7800
|
+
/** Mirror or recover the current Session's unsent annotation occurrence. */
|
|
7801
|
+
reconcileConversationAnnotationPersistence() {
|
|
7802
|
+
const sessionId = this.currentSessionId();
|
|
7803
|
+
const input = this.currentParentInput();
|
|
7804
|
+
if (sessionId !== void 0 && input !== void 0) this.annotationPersistence.reconcile(sessionId, input);
|
|
6659
7805
|
}
|
|
6660
7806
|
/** Number assigned to the next annotation shown beside the selected passage. */
|
|
6661
7807
|
nextConversationAnnotationNumber() {
|
|
6662
|
-
const
|
|
6663
|
-
|
|
6664
|
-
const scope = this.ctx.sessions.scope(dshSessionId(sessionId));
|
|
6665
|
-
if (scope === void 0) return 1;
|
|
6666
|
-
return conversationAnnotations(this.ctx.conversation.input.for(scope).state.getSnapshot()).length + 1;
|
|
7808
|
+
const snapshot = this.currentConversationInputSnapshot();
|
|
7809
|
+
return snapshot === void 0 ? 1 : conversationAnnotations(snapshot).length + 1;
|
|
6667
7810
|
}
|
|
6668
7811
|
/** Remove the current Session's unsent selected-passage annotations. */
|
|
6669
7812
|
removeConversationAnnotations() {
|
|
6670
7813
|
const sessionId = this.currentSessionId();
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
return
|
|
7814
|
+
const input = this.currentParentInput();
|
|
7815
|
+
if (sessionId === void 0 || input === void 0 || !removeConversationAnnotations(input)) return false;
|
|
7816
|
+
this.annotationPersistence.reconcile(sessionId, input);
|
|
7817
|
+
return true;
|
|
6675
7818
|
}
|
|
6676
7819
|
async retain(sessionId) {
|
|
6677
7820
|
const binding = await this.waitForBinding(dshSessionId(sessionId));
|
|
@@ -6704,6 +7847,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6704
7847
|
cwd(sessionId) {
|
|
6705
7848
|
return this.ctx.sessions.list.getSnapshot().byId[dshSessionId(sessionId)]?.cwd;
|
|
6706
7849
|
}
|
|
7850
|
+
modelDirectory(sessionId) {
|
|
7851
|
+
try {
|
|
7852
|
+
return this.ctx.modelDirectories.directoryFor(dshSessionId(sessionId));
|
|
7853
|
+
} catch {
|
|
7854
|
+
return;
|
|
7855
|
+
}
|
|
7856
|
+
}
|
|
7857
|
+
sideChatModelPreference() {
|
|
7858
|
+
return this.modelPreferences.get();
|
|
7859
|
+
}
|
|
7860
|
+
rememberSideChatModelPreference(selection) {
|
|
7861
|
+
this.modelPreferences.set(selection);
|
|
7862
|
+
}
|
|
7863
|
+
currentParentInput() {
|
|
7864
|
+
const sessionId = this.currentSessionId();
|
|
7865
|
+
if (sessionId === void 0) return;
|
|
7866
|
+
const scope = this.ctx.sessions.scope(dshSessionId(sessionId));
|
|
7867
|
+
return scope === void 0 ? void 0 : this.ctx.conversation.input.for(scope);
|
|
7868
|
+
}
|
|
6707
7869
|
waitForBinding(sessionId) {
|
|
6708
7870
|
const immediate = this.ctx.sessions.binding(sessionId);
|
|
6709
7871
|
if (immediate !== void 0) return Promise.resolve(immediate);
|
|
@@ -6754,7 +7916,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6754
7916
|
return !(target instanceof Element && target.closest([
|
|
6755
7917
|
"[data-side-chat-panel]",
|
|
6756
7918
|
".dsh-side-chat-selection-actions",
|
|
6757
|
-
".dsh-side-chat-selection-comment"
|
|
7919
|
+
".dsh-side-chat-selection-comment",
|
|
7920
|
+
".dsh-side-chat-annotation-marker"
|
|
6758
7921
|
].join(", ")) !== null);
|
|
6759
7922
|
}
|
|
6760
7923
|
function focusParentComposer() {
|
|
@@ -6780,7 +7943,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6780
7943
|
function Rc6SideChatOverlay({ controller, sessions }) {
|
|
6781
7944
|
const state = (0, react.useSyncExternalStore)(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
|
|
6782
7945
|
const currentSessionId = (0, react.useSyncExternalStore)(sessions.subscribeList, () => sessions.currentSessionId(), () => sessions.currentSessionId());
|
|
7946
|
+
const composerInput = (0, react.useSyncExternalStore)(sessions.subscribeConversationInput, sessions.currentConversationInputSnapshot, sessions.currentConversationInputSnapshot);
|
|
7947
|
+
const annotations = (0, react.useMemo)(() => composerInput === void 0 ? [] : conversationSelectionAnnotations(composerInput), [composerInput]);
|
|
6783
7948
|
const [selection, setSelection] = (0, react.useState)(null);
|
|
7949
|
+
const [editingAnnotation, setEditingAnnotation] = (0, react.useState)(null);
|
|
6784
7950
|
const captureGeneration = (0, react.useRef)(0);
|
|
6785
7951
|
const mouseDownPoint = (0, react.useRef)(null);
|
|
6786
7952
|
const annotationEditing = (0, react.useRef)(false);
|
|
@@ -6823,6 +7989,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6823
7989
|
annotationEditing.current = false;
|
|
6824
7990
|
++captureGeneration.current;
|
|
6825
7991
|
setSelection(null);
|
|
7992
|
+
setEditingAnnotation(null);
|
|
6826
7993
|
};
|
|
6827
7994
|
const onMouseUp = (event) => {
|
|
6828
7995
|
const start = mouseDownPoint.current;
|
|
@@ -6840,7 +8007,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6840
8007
|
const onKeyUp = (event) => {
|
|
6841
8008
|
if (event.key === "Escape") {
|
|
6842
8009
|
++captureGeneration.current;
|
|
8010
|
+
annotationEditing.current = false;
|
|
6843
8011
|
setSelection(null);
|
|
8012
|
+
setEditingAnnotation(null);
|
|
6844
8013
|
controller.close();
|
|
6845
8014
|
return;
|
|
6846
8015
|
}
|
|
@@ -6861,81 +8030,158 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6861
8030
|
++captureGeneration.current;
|
|
6862
8031
|
annotationEditing.current = false;
|
|
6863
8032
|
setSelection(null);
|
|
8033
|
+
setEditingAnnotation(null);
|
|
6864
8034
|
}, [currentSessionId]);
|
|
8035
|
+
(0, react.useEffect)(() => {
|
|
8036
|
+
if (composerInput !== void 0) sessions.reconcileConversationAnnotationPersistence();
|
|
8037
|
+
}, [composerInput, sessions]);
|
|
8038
|
+
(0, react.useEffect)(() => {
|
|
8039
|
+
if (editingAnnotation === null) return;
|
|
8040
|
+
if (annotations.some((annotation) => annotation.annotationIndex === editingAnnotation.annotationIndex)) return;
|
|
8041
|
+
annotationEditing.current = false;
|
|
8042
|
+
setEditingAnnotation(null);
|
|
8043
|
+
}, [annotations, editingAnnotation]);
|
|
6865
8044
|
const askDisabledReason = state.phase === "closed" ? void 0 : "Close the current Side Chat before starting another one.";
|
|
6866
8045
|
const childFace = state.childSessionId === void 0 ? void 0 : sessions.face(state.childSessionId);
|
|
6867
8046
|
const childCwd = state.childSessionId === void 0 ? void 0 : sessions.cwd(state.childSessionId);
|
|
6868
8047
|
const inheritedThroughSeq = state.inheritedThroughSeq;
|
|
6869
8048
|
const locale = navigator.language.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
|
|
8049
|
+
const modelDirectory = state.parentSessionId === void 0 ? void 0 : sessions.modelDirectory?.(state.parentSessionId);
|
|
8050
|
+
const modelControl = modelDirectory === void 0 ? void 0 : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SideChatModelSelect, {
|
|
8051
|
+
directory: modelDirectory,
|
|
8052
|
+
selection: state.modelSelection,
|
|
8053
|
+
locked: [
|
|
8054
|
+
"creating",
|
|
8055
|
+
"opening",
|
|
8056
|
+
"closing"
|
|
8057
|
+
].includes(state.phase) || state.error?.operation === "close",
|
|
8058
|
+
validateInitialSelection: state.childSessionId === void 0,
|
|
8059
|
+
locale,
|
|
8060
|
+
onInitialize: (selection, options) => {
|
|
8061
|
+
if (options.remember) controller.selectModel(selection);
|
|
8062
|
+
else controller.initializeModel(selection);
|
|
8063
|
+
},
|
|
8064
|
+
onSelect: (selection) => controller.selectModel(selection)
|
|
8065
|
+
}, `${state.parentSessionId}:${state.childSessionId ?? "draft"}`);
|
|
6870
8066
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6871
8067
|
className: "dsh-side-chat-overlay",
|
|
6872
|
-
children: [
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
8068
|
+
children: [
|
|
8069
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConversationAnnotationMarkers, {
|
|
8070
|
+
annotations,
|
|
8071
|
+
...editingAnnotation === null ? {} : { activeAnnotationIndex: editingAnnotation.annotationIndex },
|
|
8072
|
+
onEdit: (annotation, restoredSelection) => {
|
|
8073
|
+
annotationEditing.current = true;
|
|
8074
|
+
++captureGeneration.current;
|
|
8075
|
+
setSelection(null);
|
|
8076
|
+
setEditingAnnotation({
|
|
8077
|
+
...annotation,
|
|
8078
|
+
selection: restoredSelection
|
|
8079
|
+
});
|
|
8080
|
+
}
|
|
8081
|
+
}),
|
|
8082
|
+
selection !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionActions, {
|
|
8083
|
+
selection,
|
|
8084
|
+
annotationNumber: sessions.nextConversationAnnotationNumber(),
|
|
8085
|
+
...askDisabledReason === void 0 ? {} : { askDisabledReason },
|
|
8086
|
+
onAddToChat: (captured, comment) => {
|
|
8087
|
+
try {
|
|
8088
|
+
if (sessions.addSelectionToConversation(captured, comment)) focusParentComposer();
|
|
8089
|
+
else sessions.notify({
|
|
8090
|
+
kind: "warning",
|
|
8091
|
+
text: "Could not add the selection to the current chat."
|
|
8092
|
+
});
|
|
8093
|
+
} catch {
|
|
8094
|
+
sessions.notify({
|
|
8095
|
+
kind: "warning",
|
|
8096
|
+
text: "Could not add the selection to the current chat."
|
|
8097
|
+
});
|
|
8098
|
+
}
|
|
8099
|
+
setSelection(null);
|
|
8100
|
+
},
|
|
8101
|
+
onAnnotationEditorChange: (open) => {
|
|
8102
|
+
annotationEditing.current = open;
|
|
8103
|
+
},
|
|
8104
|
+
onMoreDetails: (captured) => {
|
|
8105
|
+
const opened = controller.openDraft({ selection: captured });
|
|
8106
|
+
if (!opened.ok) sessions.notify({
|
|
6880
8107
|
kind: "warning",
|
|
6881
|
-
text:
|
|
8108
|
+
text: opened.error.message
|
|
6882
8109
|
});
|
|
6883
|
-
|
|
6884
|
-
|
|
8110
|
+
else controller.sendFirst(MORE_DETAILS_PROMPT);
|
|
8111
|
+
setSelection(null);
|
|
8112
|
+
},
|
|
8113
|
+
onAskInSideChat: (captured) => {
|
|
8114
|
+
const opened = controller.openDraft({ selection: captured });
|
|
8115
|
+
if (!opened.ok) sessions.notify({
|
|
6885
8116
|
kind: "warning",
|
|
6886
|
-
text:
|
|
8117
|
+
text: opened.error.message
|
|
6887
8118
|
});
|
|
8119
|
+
setSelection(null);
|
|
8120
|
+
},
|
|
8121
|
+
onDismiss: () => {
|
|
8122
|
+
annotationEditing.current = false;
|
|
8123
|
+
setSelection(null);
|
|
6888
8124
|
}
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
locale
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
8125
|
+
}),
|
|
8126
|
+
editingAnnotation !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionActions, {
|
|
8127
|
+
selection: editingAnnotation.selection,
|
|
8128
|
+
annotationNumber: editingAnnotation.annotationIndex + 1,
|
|
8129
|
+
annotationEditor: {
|
|
8130
|
+
...editingAnnotation.comment === void 0 ? {} : { initialComment: editingAnnotation.comment },
|
|
8131
|
+
dialogLabel: "Edit annotation comment"
|
|
8132
|
+
},
|
|
8133
|
+
onAddToChat: (_captured, comment) => {
|
|
8134
|
+
try {
|
|
8135
|
+
if (!sessions.updateConversationAnnotation(editingAnnotation.annotationIndex, comment)) sessions.notify({
|
|
8136
|
+
kind: "warning",
|
|
8137
|
+
text: "Could not update the annotation."
|
|
8138
|
+
});
|
|
8139
|
+
} catch {
|
|
8140
|
+
sessions.notify({
|
|
8141
|
+
kind: "warning",
|
|
8142
|
+
text: "Could not update the annotation."
|
|
8143
|
+
});
|
|
8144
|
+
}
|
|
8145
|
+
annotationEditing.current = false;
|
|
8146
|
+
setEditingAnnotation(null);
|
|
8147
|
+
},
|
|
8148
|
+
onAnnotationEditorChange: (open) => {
|
|
8149
|
+
annotationEditing.current = open;
|
|
8150
|
+
},
|
|
8151
|
+
onMoreDetails: () => {},
|
|
8152
|
+
onAskInSideChat: () => {},
|
|
8153
|
+
onDismiss: () => {
|
|
8154
|
+
annotationEditing.current = false;
|
|
8155
|
+
setEditingAnnotation(null);
|
|
8156
|
+
}
|
|
8157
|
+
}, `annotation:${String(editingAnnotation.annotationIndex)}`),
|
|
8158
|
+
state.phase !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SideChatPanel, {
|
|
8159
|
+
state,
|
|
8160
|
+
locale,
|
|
8161
|
+
...childFace === void 0 || inheritedThroughSeq === void 0 ? {} : { embeddedConversation: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArchivedConversation, {
|
|
8162
|
+
face: childFace,
|
|
8163
|
+
inheritedThroughSeq,
|
|
8164
|
+
controller,
|
|
8165
|
+
cwd: childCwd,
|
|
8166
|
+
...state.selection === void 0 ? {} : { selection: state.selection },
|
|
8167
|
+
locale,
|
|
8168
|
+
modelControl
|
|
8169
|
+
}) },
|
|
8170
|
+
modelControl,
|
|
8171
|
+
onDraftChange: (draft) => {
|
|
8172
|
+
controller.setDraft(draft);
|
|
8173
|
+
},
|
|
8174
|
+
onFirstSend: (question) => controller.sendFirst(question),
|
|
8175
|
+
onClose: () => controller.close(),
|
|
8176
|
+
onRetry: () => controller.retry(),
|
|
8177
|
+
onFocusParent: () => {
|
|
8178
|
+
if (state.parentSessionId !== void 0) sessions.openSession(state.parentSessionId);
|
|
8179
|
+
},
|
|
8180
|
+
onRemoveSelection: () => {
|
|
8181
|
+
controller.clearSelection();
|
|
8182
|
+
}
|
|
8183
|
+
})
|
|
8184
|
+
]
|
|
6939
8185
|
});
|
|
6940
8186
|
}
|
|
6941
8187
|
//#endregion
|
|
@@ -6944,6 +8190,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6944
8190
|
const inject = [
|
|
6945
8191
|
"conversation",
|
|
6946
8192
|
"inputTriggers",
|
|
8193
|
+
"modelDirectories",
|
|
6947
8194
|
"remote",
|
|
6948
8195
|
"sessions",
|
|
6949
8196
|
"slots"
|
|
@@ -6995,6 +8242,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6995
8242
|
exports.inject = inject;
|
|
6996
8243
|
exports.name = name;
|
|
6997
8244
|
exports.normalizeSelectedText = normalizeSelectedText;
|
|
8245
|
+
exports.restoreDomConversationSelection = restoreDomConversationSelection;
|
|
6998
8246
|
exports.selectionFitsLimit = selectionFitsLimit;
|
|
6999
8247
|
exports.summarizeSelection = summarizeSelection;
|
|
7000
8248
|
exports.utf8ByteLength = utf8ByteLength;
|