@ahggg/dsh-side-chat 0.2.0 → 0.4.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 +19 -8
- package/README.zh-CN.md +19 -8
- package/lib/client/apply.d.ts.map +1 -1
- package/lib/client/apply.js +7 -1
- package/lib/client/apply.js.map +1 -1
- package/lib/client/panel/SelectionQuote.d.ts +6 -4
- package/lib/client/panel/SelectionQuote.d.ts.map +1 -1
- package/lib/client/panel/SelectionQuote.js +43 -3
- package/lib/client/panel/SelectionQuote.js.map +1 -1
- package/lib/client/panel/SideChatPanel.d.ts +1 -2
- package/lib/client/panel/SideChatPanel.d.ts.map +1 -1
- package/lib/client/panel/SideChatPanel.js +2 -2
- package/lib/client/panel/SideChatPanel.js.map +1 -1
- package/lib/client/panel/StopIcon.d.ts +3 -0
- package/lib/client/panel/StopIcon.d.ts.map +1 -0
- package/lib/client/panel/StopIcon.js +6 -0
- package/lib/client/panel/StopIcon.js.map +1 -0
- package/lib/client/panel/messages.d.ts +2 -2
- package/lib/client/panel/messages.d.ts.map +1 -1
- package/lib/client/panel/messages.js +4 -4
- package/lib/client/panel/messages.js.map +1 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts +27 -0
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts.map +1 -0
- package/lib/client/parent-composer/ParentConversationAnnotations.js +97 -0
- package/lib/client/parent-composer/ParentConversationAnnotations.js.map +1 -0
- package/lib/client/parent-composer/add-to-conversation.d.ts +64 -0
- package/lib/client/parent-composer/add-to-conversation.d.ts.map +1 -1
- package/lib/client/parent-composer/add-to-conversation.js +182 -0
- package/lib/client/parent-composer/add-to-conversation.js.map +1 -1
- package/lib/client/rc6/ArchivedConversation.d.ts +1 -2
- package/lib/client/rc6/ArchivedConversation.d.ts.map +1 -1
- package/lib/client/rc6/ArchivedConversation.js +8 -6
- 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 +56 -10
- package/lib/client/rc6/Rc6SideChatOverlay.js.map +1 -1
- package/lib/client/rc6/context.d.ts +6 -1
- package/lib/client/rc6/context.d.ts.map +1 -1
- package/lib/client/rc6/sessions-adapter.d.ts +6 -0
- package/lib/client/rc6/sessions-adapter.d.ts.map +1 -1
- package/lib/client/rc6/sessions-adapter.js +30 -0
- package/lib/client/rc6/sessions-adapter.js.map +1 -1
- package/lib/client/selection/SelectionActions.d.ts +5 -1
- package/lib/client/selection/SelectionActions.d.ts.map +1 -1
- package/lib/client/selection/SelectionActions.js +69 -7
- package/lib/client/selection/SelectionActions.js.map +1 -1
- package/lib/client.js +665 -162
- package/lib/client.js.map +1 -1
- package/package.json +5 -1
package/lib/client.js
CHANGED
|
@@ -6,8 +6,424 @@ window.__ModuleLoader__.load({
|
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
10
|
//#region \0dsh-side-chat-css:L2hvbWUvcnVubmVyL3dvcmsvZHNoLXNpZGUtY2hhdC9kc2gtc2lkZS1jaGF0L3NyYy9jbGllbnQvcGFuZWwvc2lkZS1jaGF0LmNzcw
|
|
10
|
-
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 max-width: 100%;\n border-color: transparent;\n background: transparent;\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-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 opacity: 0;\n pointer-events: none;\n transform: translateY(4px);\n visibility: hidden;\n transition: opacity 100ms ease, transform 120ms ease, visibility 100ms ease;\n}\n.dsh-side-chat-quote:hover .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 transform: translateY(0);\n visibility: visible;\n}\n.dsh-side-chat-quote[data-expanded] .dsh-side-chat-quote-details { pointer-events: auto; }\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-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-details-header button {\n min-height: 28px;\n padding-inline: 10px;\n border: 1px solid var(--side-chat-border);\n border-radius: 999px;\n background: var(--side-chat-bg);\n color: inherit;\n cursor: pointer;\n}\n.dsh-side-chat-quote pre { max-height: 180px; margin: 8px 0 0; overflow: auto; white-space: pre-wrap; font: inherit; }\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.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 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 background: var(--dsw-alias-button-info-hover, #3467d6);\n}\n.dsh-side-chat-panel .dsh-side-chat-send-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 transition: background-color 120ms ease;\n}\n.dsh-side-chat-selection-actions:hover,\n.dsh-side-chat-selection-actions:focus-within { background: var(--dsw-surface-subtle, #f3f3f5); }\n.dsh-side-chat-selection-actions button {\n min-height: 36px;\n padding: 0 14px;\n border: 0;\n border-radius: inherit;\n background: transparent;\n color: inherit;\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 { 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 max-width: 100%;\n border-color: transparent;\n background: transparent;\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-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";
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/client/parent-composer/add-to-conversation.ts
|
|
14
|
+
const SELECTION_REFERENCE_SOURCE = "dsh-side-chat-selection";
|
|
15
|
+
const OBJECT_REPLACEMENT_CHARACTER = "";
|
|
16
|
+
function escapeXmlText(value) {
|
|
17
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
18
|
+
}
|
|
19
|
+
function annotationFromSelection(selection, comment) {
|
|
20
|
+
const trimmedComment = comment?.trim();
|
|
21
|
+
return {
|
|
22
|
+
text: selection.text,
|
|
23
|
+
...trimmedComment === void 0 || trimmedComment.length === 0 ? {} : { comment: trimmedComment }
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function encodeSelectionReference(annotations) {
|
|
27
|
+
return JSON.stringify({
|
|
28
|
+
version: 1,
|
|
29
|
+
annotations
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function isAnnotation(value) {
|
|
33
|
+
if (typeof value !== "object" || value === null) return false;
|
|
34
|
+
const annotation = value;
|
|
35
|
+
return typeof annotation.text === "string" && (annotation.comment === void 0 || typeof annotation.comment === "string");
|
|
36
|
+
}
|
|
37
|
+
function decodeSelectionReference(ref) {
|
|
38
|
+
const value = JSON.parse(ref);
|
|
39
|
+
if (isAnnotation(value)) return [value];
|
|
40
|
+
if (value.version !== 1 || !Array.isArray(value.annotations) || value.annotations.length === 0 || !value.annotations.every(isAnnotation)) throw new Error("The selected conversation annotation is no longer valid.");
|
|
41
|
+
return value.annotations;
|
|
42
|
+
}
|
|
43
|
+
function selectedContext(annotations) {
|
|
44
|
+
return [
|
|
45
|
+
"<selected_context>",
|
|
46
|
+
...annotations.flatMap((annotation, index) => annotation.comment === void 0 ? [
|
|
47
|
+
`<annotation index="${String(index + 1)}">`,
|
|
48
|
+
escapeXmlText(annotation.text),
|
|
49
|
+
"</annotation>"
|
|
50
|
+
] : [
|
|
51
|
+
`<annotation index="${String(index + 1)}">`,
|
|
52
|
+
"<selected_text>",
|
|
53
|
+
escapeXmlText(annotation.text),
|
|
54
|
+
"</selected_text>",
|
|
55
|
+
"<user_comment>",
|
|
56
|
+
escapeXmlText(annotation.comment),
|
|
57
|
+
"</user_comment>",
|
|
58
|
+
"</annotation>"
|
|
59
|
+
]),
|
|
60
|
+
"</selected_context>"
|
|
61
|
+
].join("\n");
|
|
62
|
+
}
|
|
63
|
+
function selectionOccurrences(snapshot) {
|
|
64
|
+
return snapshot.occurrences.filter((occurrence) => occurrence.source === SELECTION_REFERENCE_SOURCE);
|
|
65
|
+
}
|
|
66
|
+
/** Read all plugin annotations represented by the current DSH input occurrence. */
|
|
67
|
+
function conversationAnnotations(snapshot) {
|
|
68
|
+
return selectionOccurrences(snapshot).flatMap((occurrence) => {
|
|
69
|
+
try {
|
|
70
|
+
return [...decodeSelectionReference(occurrence.ref)];
|
|
71
|
+
} catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function draftWithoutSelectionOccurrences(snapshot) {
|
|
77
|
+
const occurrences = [...selectionOccurrences(snapshot)].sort((a, b) => b.offset - a.offset);
|
|
78
|
+
let draft = snapshot.draft;
|
|
79
|
+
for (const occurrence of occurrences) draft = draft.slice(0, occurrence.offset) + draft.slice(occurrence.offset + 1);
|
|
80
|
+
if (occurrences.some((occurrence) => occurrence.offset === 0)) {
|
|
81
|
+
if (draft.startsWith("\n\n")) draft = draft.slice(2);
|
|
82
|
+
else if (draft.startsWith("\n")) draft = draft.slice(1);
|
|
83
|
+
}
|
|
84
|
+
return draft;
|
|
85
|
+
}
|
|
86
|
+
/** Remove every unsent plugin annotation while preserving the user's draft. */
|
|
87
|
+
function removeConversationAnnotations(input) {
|
|
88
|
+
const snapshot = input.state.getSnapshot();
|
|
89
|
+
if (selectionOccurrences(snapshot).length === 0) return false;
|
|
90
|
+
input.setDraft(draftWithoutSelectionOccurrences(snapshot));
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
/** Reference codec used by DSH's native composer chip and submit pipeline. */
|
|
94
|
+
const selectionReferenceSource = {
|
|
95
|
+
trigger: "@",
|
|
96
|
+
name: SELECTION_REFERENCE_SOURCE,
|
|
97
|
+
order: 1e3,
|
|
98
|
+
candidates: async () => [],
|
|
99
|
+
onPick: () => void 0,
|
|
100
|
+
codec: {
|
|
101
|
+
clipboardText: (ref) => decodeSelectionReference(ref).map((annotation) => annotation.text).join("\n\n"),
|
|
102
|
+
serialize: async (ref, signal) => {
|
|
103
|
+
if (signal.aborted) throw signal.reason;
|
|
104
|
+
return selectedContext(decodeSelectionReference(ref));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
/** Add one passage to the parent composer's aggregated annotation occurrence. */
|
|
109
|
+
function addSelectionToConversation(input, selection, comment) {
|
|
110
|
+
const before = input.state.getSnapshot();
|
|
111
|
+
const annotations = [...conversationAnnotations(before), annotationFromSelection(selection, comment)];
|
|
112
|
+
const draft = draftWithoutSelectionOccurrences(before);
|
|
113
|
+
if (selectionOccurrences(before).length > 0) input.setDraft(draft);
|
|
114
|
+
const insertionState = input.state.getSnapshot();
|
|
115
|
+
if (!input.insertReference({
|
|
116
|
+
source: SELECTION_REFERENCE_SOURCE,
|
|
117
|
+
ref: encodeSelectionReference(annotations),
|
|
118
|
+
label: "__dsh_side_chat_annotations__",
|
|
119
|
+
clipboardText: annotations.map((annotation) => annotation.text).join("\n\n")
|
|
120
|
+
}, {
|
|
121
|
+
start: 0,
|
|
122
|
+
end: 0,
|
|
123
|
+
draftRev: insertionState.draftRev
|
|
124
|
+
})) return false;
|
|
125
|
+
input.setDraft(`${OBJECT_REPLACEMENT_CHARACTER}\n\n${draft}`);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
function unescapeXmlText(value) {
|
|
129
|
+
return value.replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
130
|
+
}
|
|
131
|
+
function parseAnnotationBody(body) {
|
|
132
|
+
const selectedText = /^<selected_text>\n([\s\S]*?)\n<\/selected_text>(?:\n<user_comment>\n([\s\S]*?)\n<\/user_comment>)?$/u.exec(body);
|
|
133
|
+
if (selectedText === null) return { text: unescapeXmlText(body) };
|
|
134
|
+
const comment = selectedText[2];
|
|
135
|
+
return {
|
|
136
|
+
text: unescapeXmlText(selectedText[1] ?? ""),
|
|
137
|
+
...comment === void 0 ? {} : { comment: unescapeXmlText(comment) }
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/** Parse the durable model form back into the user-facing annotation capsule. */
|
|
141
|
+
function parseAnnotatedConversationPrompt(text) {
|
|
142
|
+
const current = /^<selected_context>\n([\s\S]*?)\n<\/selected_context>\s*/u.exec(text);
|
|
143
|
+
if (current !== null) {
|
|
144
|
+
const annotations = [];
|
|
145
|
+
for (const match of current[1]?.matchAll(/<annotation(?: index="\d+")?>\n([\s\S]*?)\n<\/annotation>/gu) ?? []) annotations.push(parseAnnotationBody(match[1] ?? ""));
|
|
146
|
+
if (annotations.length > 0) return {
|
|
147
|
+
annotations,
|
|
148
|
+
message: text.slice(current[0].length).trim()
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const legacyXml = /^<selected_context source="current-conversation" event-seq="(\d+)">\n?([\s\S]*?)\n?<\/selected_context>\s*/u.exec(text);
|
|
152
|
+
if (legacyXml !== null) return {
|
|
153
|
+
annotations: [{ text: unescapeXmlText(legacyXml[2] ?? "") }],
|
|
154
|
+
message: text.slice(legacyXml[0].length).trim()
|
|
155
|
+
};
|
|
156
|
+
const legacyText = /^Selected passage from the current conversation \(message (\d+)\):\n([\s\S]*?)\nEnd selected passage\.\s*/u.exec(text);
|
|
157
|
+
if (legacyText === null) return void 0;
|
|
158
|
+
return {
|
|
159
|
+
annotations: [{ text: legacyText[2] ?? "" }],
|
|
160
|
+
message: text.slice(legacyText[0].length).trim()
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** Add the selected quote to the first child prompt. */
|
|
164
|
+
function buildSideChatPrompt(selection, question) {
|
|
165
|
+
const trimmed = question.trim();
|
|
166
|
+
if (selection === void 0) return [{
|
|
167
|
+
type: "text",
|
|
168
|
+
text: trimmed
|
|
169
|
+
}];
|
|
170
|
+
return [{
|
|
171
|
+
type: "text",
|
|
172
|
+
text: [
|
|
173
|
+
`<selected_context source="current-conversation" event-seq="${selection.atSeq}">`,
|
|
174
|
+
escapeXmlText(selection.text),
|
|
175
|
+
"</selected_context>",
|
|
176
|
+
"",
|
|
177
|
+
"<user_question>",
|
|
178
|
+
escapeXmlText(trimmed),
|
|
179
|
+
"</user_question>"
|
|
180
|
+
].join("\n")
|
|
181
|
+
}];
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/client/panel/messages.ts
|
|
185
|
+
const SIDE_CHAT_MESSAGES = Object.freeze({
|
|
186
|
+
en: Object.freeze({
|
|
187
|
+
title: "Side Chat",
|
|
188
|
+
close: "Close Side Chat",
|
|
189
|
+
placeholder: "Ask about this in a Side Chat",
|
|
190
|
+
send: "Send",
|
|
191
|
+
selectedPassage: "Selected passage",
|
|
192
|
+
selectionAttachments: (count) => `${String(count)} ${count === 1 ? "annotation" : "annotations"}`,
|
|
193
|
+
selectionPreviewLabel: "Selected text",
|
|
194
|
+
selectionCommentLabel: "User comment",
|
|
195
|
+
removeSelection: "Remove annotation",
|
|
196
|
+
expand: "Expand",
|
|
197
|
+
collapse: "Collapse",
|
|
198
|
+
temporary: "Archived when closed; history remains on disk",
|
|
199
|
+
referenceOnly: "Inherits the complete parent conversation prefix",
|
|
200
|
+
cannotReopen: "No reopen action",
|
|
201
|
+
sharedWorkspace: "Shares the parent workspace",
|
|
202
|
+
retry: "Retry",
|
|
203
|
+
genericError: "Side Chat error",
|
|
204
|
+
closeError: "Could not close the Side Chat"
|
|
205
|
+
}),
|
|
206
|
+
"zh-CN": Object.freeze({
|
|
207
|
+
title: "侧边对话",
|
|
208
|
+
close: "关闭侧边对话",
|
|
209
|
+
placeholder: "在侧边对话中询问这段内容",
|
|
210
|
+
send: "发送",
|
|
211
|
+
selectedPassage: "所选段落",
|
|
212
|
+
selectionAttachments: (count) => `${String(count)} 条引用`,
|
|
213
|
+
selectionPreviewLabel: "所选文本",
|
|
214
|
+
selectionCommentLabel: "用户批注",
|
|
215
|
+
removeSelection: "移除引用",
|
|
216
|
+
expand: "展开",
|
|
217
|
+
collapse: "收起",
|
|
218
|
+
temporary: "关闭时归档;历史仍保存在磁盘上",
|
|
219
|
+
referenceOnly: "完整继承父会话对话前缀",
|
|
220
|
+
cannotReopen: "不提供重新打开操作",
|
|
221
|
+
sharedWorkspace: "与父会话共享工作区",
|
|
222
|
+
retry: "重试",
|
|
223
|
+
genericError: "侧边对话错误",
|
|
224
|
+
closeError: "无法关闭侧边对话"
|
|
225
|
+
})
|
|
226
|
+
});
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/client/panel/SelectionQuote.tsx
|
|
229
|
+
/** Selected passage displayed separately from the user's first question. */
|
|
230
|
+
function SelectionQuote({ selections, messages, onRemove }) {
|
|
231
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
232
|
+
const [hovered, setHovered] = (0, react.useState)(false);
|
|
233
|
+
const quoteRef = (0, react.useRef)(null);
|
|
234
|
+
const detailsRef = (0, react.useRef)(null);
|
|
235
|
+
const leaveTimerRef = (0, react.useRef)();
|
|
236
|
+
const keepHoverOpen = () => {
|
|
237
|
+
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
238
|
+
leaveTimerRef.current = void 0;
|
|
239
|
+
setHovered(true);
|
|
240
|
+
};
|
|
241
|
+
const closeHoverAfterGrace = () => {
|
|
242
|
+
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
243
|
+
leaveTimerRef.current = window.setTimeout(() => {
|
|
244
|
+
leaveTimerRef.current = void 0;
|
|
245
|
+
setHovered(false);
|
|
246
|
+
}, 220);
|
|
247
|
+
};
|
|
248
|
+
(0, react.useEffect)(() => () => {
|
|
249
|
+
if (leaveTimerRef.current !== void 0) window.clearTimeout(leaveTimerRef.current);
|
|
250
|
+
}, []);
|
|
251
|
+
const constrainDetailsToBoundary = () => {
|
|
252
|
+
const details = detailsRef.current;
|
|
253
|
+
const boundary = quoteRef.current?.closest(".dsh-side-chat-panel, [data-composer-seat], [data-chat-flow-kind]");
|
|
254
|
+
if (details === null) return;
|
|
255
|
+
details.style.setProperty("--dsh-side-chat-quote-offset-x", "0px");
|
|
256
|
+
const detailsRect = details.getBoundingClientRect();
|
|
257
|
+
const boundaryRect = boundary?.getBoundingClientRect();
|
|
258
|
+
const leftEdge = (boundaryRect?.left ?? 0) + 16;
|
|
259
|
+
const rightEdge = (boundaryRect?.right ?? window.innerWidth) - 16;
|
|
260
|
+
const offset = detailsRect.left < leftEdge ? leftEdge - detailsRect.left : detailsRect.right > rightEdge ? rightEdge - detailsRect.right : 0;
|
|
261
|
+
details.style.setProperty("--dsh-side-chat-quote-offset-x", `${String(offset)}px`);
|
|
262
|
+
};
|
|
263
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
264
|
+
ref: quoteRef,
|
|
265
|
+
className: "dsh-side-chat-quote",
|
|
266
|
+
"aria-label": messages.selectedPassage,
|
|
267
|
+
"data-expanded": expanded || void 0,
|
|
268
|
+
"data-hovered": hovered || void 0,
|
|
269
|
+
onMouseEnter: () => {
|
|
270
|
+
keepHoverOpen();
|
|
271
|
+
constrainDetailsToBoundary();
|
|
272
|
+
},
|
|
273
|
+
onMouseLeave: closeHoverAfterGrace,
|
|
274
|
+
onFocusCapture: constrainDetailsToBoundary,
|
|
275
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
276
|
+
className: "dsh-side-chat-quote-chip",
|
|
277
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
278
|
+
type: "button",
|
|
279
|
+
className: "dsh-side-chat-quote-trigger",
|
|
280
|
+
"aria-expanded": expanded,
|
|
281
|
+
"aria-label": `${expanded ? messages.collapse : messages.expand}: ${messages.selectedPassage}`,
|
|
282
|
+
onClick: () => {
|
|
283
|
+
setExpanded((value) => !value);
|
|
284
|
+
},
|
|
285
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
286
|
+
className: "dsh-side-chat-quote-icon",
|
|
287
|
+
viewBox: "0 0 24 24",
|
|
288
|
+
"aria-hidden": "true",
|
|
289
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8 8h8M8 12h5" })]
|
|
290
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: messages.selectionAttachments(selections.length) })]
|
|
291
|
+
}), onRemove !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
292
|
+
type: "button",
|
|
293
|
+
className: "dsh-side-chat-quote-remove",
|
|
294
|
+
"aria-label": messages.removeSelection,
|
|
295
|
+
onClick: onRemove,
|
|
296
|
+
children: "×"
|
|
297
|
+
})]
|
|
298
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
299
|
+
ref: detailsRef,
|
|
300
|
+
className: "dsh-side-chat-quote-details",
|
|
301
|
+
role: "tooltip",
|
|
302
|
+
children: selections.map((selection, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
303
|
+
className: "dsh-side-chat-quote-detail",
|
|
304
|
+
children: [
|
|
305
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
306
|
+
className: "dsh-side-chat-quote-details-header",
|
|
307
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [
|
|
308
|
+
String(index + 1),
|
|
309
|
+
". ",
|
|
310
|
+
messages.selectionPreviewLabel,
|
|
311
|
+
":"
|
|
312
|
+
] })
|
|
313
|
+
}),
|
|
314
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: selection.text }),
|
|
315
|
+
selection.comment !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
316
|
+
className: "dsh-side-chat-quote-comment",
|
|
317
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [messages.selectionCommentLabel, ":"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: selection.comment })]
|
|
318
|
+
})
|
|
319
|
+
]
|
|
320
|
+
}, `${String(index)}-${selection.text}`))
|
|
321
|
+
})]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/client/parent-composer/ParentConversationAnnotations.tsx
|
|
326
|
+
function currentLocale() {
|
|
327
|
+
return navigator.language.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
|
|
328
|
+
}
|
|
329
|
+
/** The interactive annotation capsule occupying the reserved first composer row. */
|
|
330
|
+
function ParentComposerAnnotations({ input, onRemove, locale = currentLocale() }) {
|
|
331
|
+
const annotations = conversationAnnotations(input);
|
|
332
|
+
if (annotations.length === 0) return null;
|
|
333
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
334
|
+
className: "dsh-side-chat-parent-annotation-dock",
|
|
335
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
336
|
+
selections: annotations,
|
|
337
|
+
messages: SIDE_CHAT_MESSAGES[locale],
|
|
338
|
+
onRemove
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function contentText$1(content) {
|
|
343
|
+
return content.map((block) => {
|
|
344
|
+
if (typeof block !== "object" || block === null) return "";
|
|
345
|
+
const value = block;
|
|
346
|
+
return value.type === "text" && typeof value.text === "string" ? value.text : "";
|
|
347
|
+
}).join("");
|
|
348
|
+
}
|
|
349
|
+
function visibleMessage(message) {
|
|
350
|
+
return /^<user_question>\n?([\s\S]*?)\n?<\/user_question>$/u.exec(message)?.[1]?.trim() ?? message;
|
|
351
|
+
}
|
|
352
|
+
function replaceTextContent(content, message) {
|
|
353
|
+
let replaced = false;
|
|
354
|
+
const next = content.flatMap((block) => {
|
|
355
|
+
if (typeof block !== "object" || block === null) return [block];
|
|
356
|
+
const value = block;
|
|
357
|
+
if (value.type !== "text" || typeof value.text !== "string") return [block];
|
|
358
|
+
if (replaced) return [];
|
|
359
|
+
replaced = true;
|
|
360
|
+
return [{
|
|
361
|
+
...value,
|
|
362
|
+
text: message
|
|
363
|
+
}];
|
|
364
|
+
});
|
|
365
|
+
return replaced ? next : [{
|
|
366
|
+
type: "text",
|
|
367
|
+
text: message
|
|
368
|
+
}, ...next];
|
|
369
|
+
}
|
|
370
|
+
/** Wrap DSH's own user renderer only when this plugin's durable prefix exists. */
|
|
371
|
+
function annotatedUserMessageRenderer(Original) {
|
|
372
|
+
return function AnnotatedUserMessageRenderer(props) {
|
|
373
|
+
const parsed = parseAnnotatedConversationPrompt(contentText$1(props.node.data.content));
|
|
374
|
+
if (parsed === void 0) return (0, react.createElement)(Original, props);
|
|
375
|
+
const node = {
|
|
376
|
+
...props.node,
|
|
377
|
+
data: {
|
|
378
|
+
...props.node.data,
|
|
379
|
+
content: replaceTextContent(props.node.data.content, visibleMessage(parsed.message))
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
383
|
+
className: "dsh-side-chat-parent-user-message",
|
|
384
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
385
|
+
selections: parsed.annotations,
|
|
386
|
+
messages: SIDE_CHAT_MESSAGES[currentLocale()]
|
|
387
|
+
}), (0, react.createElement)(Original, {
|
|
388
|
+
...props,
|
|
389
|
+
node
|
|
390
|
+
})]
|
|
391
|
+
});
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
/** Mount the composer capsule and a thin wrapper around DSH's user renderers. */
|
|
395
|
+
function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
396
|
+
const slots = ctx.slots;
|
|
397
|
+
const removeDock = slots.inject("conversation.input.dock", () => slots.register({
|
|
398
|
+
name: "conversation.input.dock",
|
|
399
|
+
id: "dsh-side-chat-annotations",
|
|
400
|
+
order: -100
|
|
401
|
+
}, ({ input }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParentComposerAnnotations, {
|
|
402
|
+
input,
|
|
403
|
+
onRemove: removeAnnotations
|
|
404
|
+
})));
|
|
405
|
+
const shadow = (key) => slots.inject("conversation.chat.node", () => {
|
|
406
|
+
const ShadowedUserMessage = (props) => {
|
|
407
|
+
const original = slots.entries("conversation.chat.node").find((entry) => entry.options.key === key && entry.component !== ShadowedUserMessage && (entry.options.priority ?? 0) >= 0)?.component;
|
|
408
|
+
if (original === void 0) return null;
|
|
409
|
+
const Renderer = annotatedUserMessageRenderer(original);
|
|
410
|
+
return (0, react.createElement)(Renderer, props);
|
|
411
|
+
};
|
|
412
|
+
return slots.register({
|
|
413
|
+
name: "conversation.chat.node",
|
|
414
|
+
key,
|
|
415
|
+
priority: -100,
|
|
416
|
+
locale: "conversation"
|
|
417
|
+
}, ShadowedUserMessage);
|
|
418
|
+
});
|
|
419
|
+
const removeUser = shadow("user");
|
|
420
|
+
const removeSteering = shadow("steering");
|
|
421
|
+
return () => {
|
|
422
|
+
removeSteering();
|
|
423
|
+
removeUser();
|
|
424
|
+
removeDock();
|
|
425
|
+
};
|
|
426
|
+
}
|
|
11
427
|
//#endregion
|
|
12
428
|
//#region src/shared/observable.ts
|
|
13
429
|
/** Immutable-value observable with contained subscriber failures. */
|
|
@@ -46,31 +462,6 @@ window.__ModuleLoader__.load({
|
|
|
46
462
|
this.listeners.clear();
|
|
47
463
|
}
|
|
48
464
|
};
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/client/parent-composer/add-to-conversation.ts
|
|
51
|
-
function escapeXmlText(value) {
|
|
52
|
-
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
53
|
-
}
|
|
54
|
-
/** Add the selected quote to the first child prompt. */
|
|
55
|
-
function buildSideChatPrompt(selection, question) {
|
|
56
|
-
const trimmed = question.trim();
|
|
57
|
-
if (selection === void 0) return [{
|
|
58
|
-
type: "text",
|
|
59
|
-
text: trimmed
|
|
60
|
-
}];
|
|
61
|
-
return [{
|
|
62
|
-
type: "text",
|
|
63
|
-
text: [
|
|
64
|
-
`<selected_context source="current-conversation" event-seq="${selection.atSeq}">`,
|
|
65
|
-
escapeXmlText(selection.text),
|
|
66
|
-
"</selected_context>",
|
|
67
|
-
"",
|
|
68
|
-
"<user_question>",
|
|
69
|
-
escapeXmlText(trimmed),
|
|
70
|
-
"</user_question>"
|
|
71
|
-
].join("\n")
|
|
72
|
-
}];
|
|
73
|
-
}
|
|
74
465
|
Object.freeze({
|
|
75
466
|
repository: "https://github.com/deepseek-ai/deepseek-harness",
|
|
76
467
|
npmPackage: "@deepseek-ai/dsh",
|
|
@@ -4784,102 +5175,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4784
5175
|
};
|
|
4785
5176
|
}
|
|
4786
5177
|
//#endregion
|
|
4787
|
-
//#region src/client/panel/messages.ts
|
|
4788
|
-
const SIDE_CHAT_MESSAGES = Object.freeze({
|
|
4789
|
-
en: Object.freeze({
|
|
4790
|
-
title: "Side Chat",
|
|
4791
|
-
close: "Close Side Chat",
|
|
4792
|
-
placeholder: "Ask about this in a Side Chat",
|
|
4793
|
-
send: "Send",
|
|
4794
|
-
selectedPassage: "Selected passage",
|
|
4795
|
-
selectionAttachment: "1 annotation",
|
|
4796
|
-
selectionPreviewLabel: "Selected text",
|
|
4797
|
-
removeSelection: "Remove annotation",
|
|
4798
|
-
expand: "Expand",
|
|
4799
|
-
collapse: "Collapse",
|
|
4800
|
-
copy: "Copy",
|
|
4801
|
-
temporary: "Archived when closed; history remains on disk",
|
|
4802
|
-
referenceOnly: "Inherits the complete parent conversation prefix",
|
|
4803
|
-
cannotReopen: "No reopen action",
|
|
4804
|
-
sharedWorkspace: "Shares the parent workspace",
|
|
4805
|
-
retry: "Retry",
|
|
4806
|
-
genericError: "Side Chat error",
|
|
4807
|
-
closeError: "Could not close the Side Chat"
|
|
4808
|
-
}),
|
|
4809
|
-
"zh-CN": Object.freeze({
|
|
4810
|
-
title: "侧边对话",
|
|
4811
|
-
close: "关闭侧边对话",
|
|
4812
|
-
placeholder: "在侧边对话中询问这段内容",
|
|
4813
|
-
send: "发送",
|
|
4814
|
-
selectedPassage: "所选段落",
|
|
4815
|
-
selectionAttachment: "1 条引用",
|
|
4816
|
-
selectionPreviewLabel: "所选文本",
|
|
4817
|
-
removeSelection: "移除引用",
|
|
4818
|
-
expand: "展开",
|
|
4819
|
-
collapse: "收起",
|
|
4820
|
-
copy: "复制",
|
|
4821
|
-
temporary: "关闭时归档;历史仍保存在磁盘上",
|
|
4822
|
-
referenceOnly: "完整继承父会话对话前缀",
|
|
4823
|
-
cannotReopen: "不提供重新打开操作",
|
|
4824
|
-
sharedWorkspace: "与父会话共享工作区",
|
|
4825
|
-
retry: "重试",
|
|
4826
|
-
genericError: "侧边对话错误",
|
|
4827
|
-
closeError: "无法关闭侧边对话"
|
|
4828
|
-
})
|
|
4829
|
-
});
|
|
4830
|
-
//#endregion
|
|
4831
|
-
//#region src/client/panel/SelectionQuote.tsx
|
|
4832
|
-
/** Selected passage displayed separately from the user's first question. */
|
|
4833
|
-
function SelectionQuote({ selection, messages, onCopy, onRemove }) {
|
|
4834
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
4835
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
4836
|
-
className: "dsh-side-chat-quote",
|
|
4837
|
-
"aria-label": messages.selectedPassage,
|
|
4838
|
-
"data-expanded": expanded || void 0,
|
|
4839
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4840
|
-
className: "dsh-side-chat-quote-chip",
|
|
4841
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4842
|
-
type: "button",
|
|
4843
|
-
className: "dsh-side-chat-quote-trigger",
|
|
4844
|
-
"aria-expanded": expanded,
|
|
4845
|
-
"aria-label": `${expanded ? messages.collapse : messages.expand}: ${messages.selectedPassage}`,
|
|
4846
|
-
onClick: () => {
|
|
4847
|
-
setExpanded((value) => !value);
|
|
4848
|
-
},
|
|
4849
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
4850
|
-
className: "dsh-side-chat-quote-icon",
|
|
4851
|
-
viewBox: "0 0 24 24",
|
|
4852
|
-
"aria-hidden": "true",
|
|
4853
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8 8h8M8 12h5" })]
|
|
4854
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: messages.selectionAttachment })]
|
|
4855
|
-
}), onRemove !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4856
|
-
type: "button",
|
|
4857
|
-
className: "dsh-side-chat-quote-remove",
|
|
4858
|
-
"aria-label": messages.removeSelection,
|
|
4859
|
-
onClick: onRemove,
|
|
4860
|
-
children: "×"
|
|
4861
|
-
})]
|
|
4862
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4863
|
-
className: "dsh-side-chat-quote-details",
|
|
4864
|
-
role: "tooltip",
|
|
4865
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4866
|
-
className: "dsh-side-chat-quote-details-header",
|
|
4867
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [
|
|
4868
|
-
"1. ",
|
|
4869
|
-
messages.selectionPreviewLabel,
|
|
4870
|
-
":"
|
|
4871
|
-
] }), onCopy !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4872
|
-
type: "button",
|
|
4873
|
-
onClick: () => {
|
|
4874
|
-
onCopy(selection.text);
|
|
4875
|
-
},
|
|
4876
|
-
children: messages.copy
|
|
4877
|
-
})]
|
|
4878
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: selection.text })]
|
|
4879
|
-
})]
|
|
4880
|
-
});
|
|
4881
|
-
}
|
|
4882
|
-
//#endregion
|
|
4883
5178
|
//#region src/client/panel/SendIcon.tsx
|
|
4884
5179
|
/** Arrow used by DSH's native 34px primary send button. */
|
|
4885
5180
|
function SendIcon() {
|
|
@@ -4958,7 +5253,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4958
5253
|
}
|
|
4959
5254
|
//#endregion
|
|
4960
5255
|
//#region src/client/panel/SideChatPanel.tsx
|
|
4961
|
-
function SideChatPanel({ state, locale = "en", embeddedConversation, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent,
|
|
5256
|
+
function SideChatPanel({ state, locale = "en", embeddedConversation, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent, onRemoveSelection }) {
|
|
4962
5257
|
const messages = SIDE_CHAT_MESSAGES[locale];
|
|
4963
5258
|
const [submitting, setSubmitting] = (0, react.useState)(false);
|
|
4964
5259
|
const draftRef = useAutoGrowingTextarea(state.draft);
|
|
@@ -5004,9 +5299,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5004
5299
|
},
|
|
5005
5300
|
children: [
|
|
5006
5301
|
state.selection !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
5007
|
-
|
|
5302
|
+
selections: [state.selection],
|
|
5008
5303
|
messages,
|
|
5009
|
-
...onCopySelection === void 0 ? {} : { onCopy: onCopySelection },
|
|
5010
5304
|
...onRemoveSelection === void 0 ? {} : { onRemove: onRemoveSelection }
|
|
5011
5305
|
}),
|
|
5012
5306
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
@@ -5153,17 +5447,104 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5153
5447
|
}
|
|
5154
5448
|
//#endregion
|
|
5155
5449
|
//#region src/client/selection/SelectionActions.tsx
|
|
5156
|
-
function
|
|
5450
|
+
function clamp(value, minimum, maximum) {
|
|
5451
|
+
return Math.min(Math.max(minimum, value), Math.max(minimum, maximum));
|
|
5452
|
+
}
|
|
5453
|
+
function SelectionActions({ selection, askDisabledReason, annotationNumber = 1, onAddToChat, onMoreDetails, onAskInSideChat, onAnnotationEditorChange, onDismiss }) {
|
|
5454
|
+
const [editingAnnotation, setEditingAnnotation] = (0, react.useState)(false);
|
|
5455
|
+
const [comment, setComment] = (0, react.useState)("");
|
|
5456
|
+
const commentRef = (0, react.useRef)(null);
|
|
5157
5457
|
const center = selection.rect.x + selection.rect.width / 2;
|
|
5158
5458
|
const style = {
|
|
5159
5459
|
left: Math.min(Math.max(8, center), selection.rect.viewportWidth - 8),
|
|
5160
5460
|
top: selection.rect.y < 56 ? selection.rect.y + selection.rect.height + 8 : selection.rect.y - 8,
|
|
5161
5461
|
transform: selection.rect.y < 56 ? "translate(0, 0)" : "translate(0, -100%)"
|
|
5162
5462
|
};
|
|
5463
|
+
const editorWidth = Math.min(420, selection.rect.viewportWidth - 16);
|
|
5464
|
+
const editorAbove = selection.rect.y - 118;
|
|
5465
|
+
const editorStyle = {
|
|
5466
|
+
left: clamp(selection.rect.x + selection.rect.width + 28, 8, selection.rect.viewportWidth - editorWidth - 8),
|
|
5467
|
+
top: editorAbove >= 8 ? editorAbove : clamp(selection.rect.y + selection.rect.height + 12, 8, selection.rect.viewportHeight - 126),
|
|
5468
|
+
width: editorWidth
|
|
5469
|
+
};
|
|
5470
|
+
const markerStyle = {
|
|
5471
|
+
left: clamp(selection.rect.x + selection.rect.width - 10, 8, selection.rect.viewportWidth - 36),
|
|
5472
|
+
top: selection.rect.y >= 38 ? selection.rect.y - 34 : selection.rect.y + selection.rect.height + 6
|
|
5473
|
+
};
|
|
5163
5474
|
const keepSelection = (event) => {
|
|
5164
5475
|
event.preventDefault();
|
|
5165
5476
|
};
|
|
5166
|
-
|
|
5477
|
+
(0, react.useEffect)(() => {
|
|
5478
|
+
if (editingAnnotation) commentRef.current?.focus();
|
|
5479
|
+
}, [editingAnnotation]);
|
|
5480
|
+
const closeEditor = () => {
|
|
5481
|
+
setEditingAnnotation(false);
|
|
5482
|
+
setComment("");
|
|
5483
|
+
onAnnotationEditorChange?.(false);
|
|
5484
|
+
};
|
|
5485
|
+
const saveAnnotation = () => {
|
|
5486
|
+
const trimmed = comment.trim();
|
|
5487
|
+
onAddToChat(selection, trimmed.length === 0 ? void 0 : trimmed);
|
|
5488
|
+
onAnnotationEditorChange?.(false);
|
|
5489
|
+
onDismiss();
|
|
5490
|
+
};
|
|
5491
|
+
const submitAnnotation = (event) => {
|
|
5492
|
+
event.preventDefault();
|
|
5493
|
+
saveAnnotation();
|
|
5494
|
+
};
|
|
5495
|
+
const annotationKeyDown = (event) => {
|
|
5496
|
+
if (event.key === "Escape") {
|
|
5497
|
+
event.preventDefault();
|
|
5498
|
+
event.stopPropagation();
|
|
5499
|
+
closeEditor();
|
|
5500
|
+
return;
|
|
5501
|
+
}
|
|
5502
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
5503
|
+
event.preventDefault();
|
|
5504
|
+
saveAnnotation();
|
|
5505
|
+
}
|
|
5506
|
+
};
|
|
5507
|
+
if (editingAnnotation) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5508
|
+
className: "dsh-side-chat-selection-marker",
|
|
5509
|
+
"aria-hidden": "true",
|
|
5510
|
+
style: markerStyle,
|
|
5511
|
+
children: String(annotationNumber)
|
|
5512
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
5513
|
+
className: "dsh-side-chat-selection-comment",
|
|
5514
|
+
role: "dialog",
|
|
5515
|
+
"aria-label": "Add annotation comment",
|
|
5516
|
+
style: editorStyle,
|
|
5517
|
+
onSubmit: submitAnnotation,
|
|
5518
|
+
onMouseDown: (event) => {
|
|
5519
|
+
event.stopPropagation();
|
|
5520
|
+
},
|
|
5521
|
+
onKeyUp: (event) => {
|
|
5522
|
+
event.stopPropagation();
|
|
5523
|
+
},
|
|
5524
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
5525
|
+
ref: commentRef,
|
|
5526
|
+
value: comment,
|
|
5527
|
+
rows: 2,
|
|
5528
|
+
"aria-label": "Optional annotation comment",
|
|
5529
|
+
placeholder: "Add an optional comment…",
|
|
5530
|
+
onChange: (event) => {
|
|
5531
|
+
setComment(event.currentTarget.value);
|
|
5532
|
+
},
|
|
5533
|
+
onKeyDown: annotationKeyDown
|
|
5534
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5535
|
+
className: "dsh-side-chat-selection-comment-actions",
|
|
5536
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5537
|
+
type: "button",
|
|
5538
|
+
onClick: closeEditor,
|
|
5539
|
+
children: "Cancel"
|
|
5540
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5541
|
+
type: "submit",
|
|
5542
|
+
className: "dsh-side-chat-selection-comment-save",
|
|
5543
|
+
children: "Save"
|
|
5544
|
+
})]
|
|
5545
|
+
})]
|
|
5546
|
+
})] });
|
|
5547
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5167
5548
|
className: "dsh-side-chat-selection-actions",
|
|
5168
5549
|
role: "toolbar",
|
|
5169
5550
|
"aria-label": "Selected conversation text actions",
|
|
@@ -5172,15 +5553,54 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5172
5553
|
onKeyDown: (event) => {
|
|
5173
5554
|
if (event.key === "Escape") onDismiss();
|
|
5174
5555
|
},
|
|
5175
|
-
children:
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5556
|
+
children: [
|
|
5557
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5558
|
+
type: "button",
|
|
5559
|
+
onClick: () => {
|
|
5560
|
+
setEditingAnnotation(true);
|
|
5561
|
+
onAnnotationEditorChange?.(true);
|
|
5562
|
+
},
|
|
5563
|
+
children: "Add to chat"
|
|
5564
|
+
}),
|
|
5565
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5566
|
+
type: "button",
|
|
5567
|
+
disabled: askDisabledReason !== void 0,
|
|
5568
|
+
title: askDisabledReason,
|
|
5569
|
+
onClick: () => {
|
|
5570
|
+
onMoreDetails(selection);
|
|
5571
|
+
onDismiss();
|
|
5572
|
+
},
|
|
5573
|
+
children: "More details"
|
|
5574
|
+
}),
|
|
5575
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5576
|
+
type: "button",
|
|
5577
|
+
disabled: askDisabledReason !== void 0,
|
|
5578
|
+
title: askDisabledReason,
|
|
5579
|
+
onClick: () => {
|
|
5580
|
+
onAskInSideChat(selection);
|
|
5581
|
+
onDismiss();
|
|
5582
|
+
},
|
|
5583
|
+
children: "Ask in side chat"
|
|
5584
|
+
})
|
|
5585
|
+
]
|
|
5586
|
+
});
|
|
5587
|
+
}
|
|
5588
|
+
//#endregion
|
|
5589
|
+
//#region src/client/panel/StopIcon.tsx
|
|
5590
|
+
/** Rounded-square stop glyph used by DSH's native primary action button. */
|
|
5591
|
+
function StopIcon() {
|
|
5592
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
5593
|
+
viewBox: "0 0 16 16",
|
|
5594
|
+
width: "16",
|
|
5595
|
+
height: "16",
|
|
5596
|
+
"aria-hidden": "true",
|
|
5597
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
5598
|
+
x: "3",
|
|
5599
|
+
y: "3",
|
|
5600
|
+
width: "10",
|
|
5601
|
+
height: "10",
|
|
5602
|
+
rx: "3",
|
|
5603
|
+
fill: "currentColor"
|
|
5184
5604
|
})
|
|
5185
5605
|
});
|
|
5186
5606
|
}
|
|
@@ -5206,12 +5626,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5206
5626
|
function firstSideChatQuestion(text) {
|
|
5207
5627
|
return /<user_question>([\s\S]*?)<\/user_question>/u.exec(text)?.[1]?.trim() ?? text;
|
|
5208
5628
|
}
|
|
5209
|
-
function AssistantBlocks({ blocks }) {
|
|
5629
|
+
function AssistantBlocks({ blocks, streaming = false }) {
|
|
5210
5630
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: blocks.map((block, index) => {
|
|
5211
5631
|
const key = `${block.kind}-${String(index)}`;
|
|
5212
|
-
if (block.kind === "text") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5213
|
-
|
|
5214
|
-
|
|
5632
|
+
if (block.kind === "text") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
5633
|
+
text: block.text,
|
|
5634
|
+
streaming
|
|
5215
5635
|
}, key);
|
|
5216
5636
|
if (block.kind === "reasoning") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
5217
5637
|
className: "dsh-side-chat-reasoning",
|
|
@@ -5434,7 +5854,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5434
5854
|
});
|
|
5435
5855
|
}
|
|
5436
5856
|
/** Functional rc.6 conversation surface bound to a non-current child Session. */
|
|
5437
|
-
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en"
|
|
5857
|
+
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en" }) {
|
|
5438
5858
|
const snapshot = (0, react.useSyncExternalStore)((listener) => face.subscribe(listener), () => face.getSnapshot(), () => face.getSnapshot());
|
|
5439
5859
|
const [draft, setDraft] = (0, react.useState)("");
|
|
5440
5860
|
const [sending, setSending] = (0, react.useState)(false);
|
|
@@ -5481,9 +5901,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5481
5901
|
nodes.map((node) => selection !== void 0 && node === annotatedUserNode ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5482
5902
|
className: "dsh-side-chat-annotated-user-message",
|
|
5483
5903
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
5484
|
-
selection,
|
|
5485
|
-
messages: SIDE_CHAT_MESSAGES[locale]
|
|
5486
|
-
...onCopySelection === void 0 ? {} : { onCopy: onCopySelection }
|
|
5904
|
+
selections: [selection],
|
|
5905
|
+
messages: SIDE_CHAT_MESSAGES[locale]
|
|
5487
5906
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, { node })]
|
|
5488
5907
|
}, `${node.kind}-${String(node.seq)}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, { node }, `${node.kind}-${String(node.seq)}`)),
|
|
5489
5908
|
snapshot.partial !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
@@ -5492,7 +5911,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5492
5911
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5493
5912
|
className: "dsh-side-chat-message-role",
|
|
5494
5913
|
children: "Assistant"
|
|
5495
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AssistantBlocks, {
|
|
5914
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AssistantBlocks, {
|
|
5915
|
+
blocks: snapshot.partial.blocks,
|
|
5916
|
+
streaming: true
|
|
5917
|
+
})]
|
|
5496
5918
|
}),
|
|
5497
5919
|
snapshot.runningCalls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
5498
5920
|
className: "dsh-side-chat-message dsh-side-chat-tool",
|
|
@@ -5531,19 +5953,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5531
5953
|
event.currentTarget.form?.requestSubmit();
|
|
5532
5954
|
}
|
|
5533
5955
|
}
|
|
5534
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
5956
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: snapshot.running ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5535
5957
|
type: "button",
|
|
5958
|
+
className: "dsh-side-chat-stop-button",
|
|
5959
|
+
"aria-label": "Stop generating",
|
|
5960
|
+
title: "Stop generating",
|
|
5536
5961
|
onClick: () => {
|
|
5537
5962
|
controller.cancel();
|
|
5538
5963
|
},
|
|
5539
|
-
children:
|
|
5540
|
-
})
|
|
5964
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StopIcon, {})
|
|
5965
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5541
5966
|
type: "submit",
|
|
5542
5967
|
className: "dsh-side-chat-send-button",
|
|
5543
|
-
"aria-label":
|
|
5968
|
+
"aria-label": "Send",
|
|
5544
5969
|
disabled: sending || draft.trim().length === 0,
|
|
5545
5970
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SendIcon, {})
|
|
5546
|
-
})
|
|
5971
|
+
}) })]
|
|
5547
5972
|
})]
|
|
5548
5973
|
});
|
|
5549
5974
|
}
|
|
@@ -5716,6 +6141,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5716
6141
|
return node !== void 0 && node.visibility === "visible" && node.kind === fragment.nodeKind && node.anchorSeq === fragment.seq && locationSettled(node.location);
|
|
5717
6142
|
});
|
|
5718
6143
|
}
|
|
6144
|
+
/** Add one selected passage to the native composer of its parent Session. */
|
|
6145
|
+
addSelectionToConversation(selection, comment) {
|
|
6146
|
+
if (this.currentSessionId() !== selection.parentSessionId) return false;
|
|
6147
|
+
const scope = this.ctx.sessions.scope(dshSessionId(selection.parentSessionId));
|
|
6148
|
+
if (scope === void 0) return false;
|
|
6149
|
+
return addSelectionToConversation(this.ctx.conversation.input.for(scope), selection, comment);
|
|
6150
|
+
}
|
|
6151
|
+
/** Number assigned to the next annotation shown beside the selected passage. */
|
|
6152
|
+
nextConversationAnnotationNumber() {
|
|
6153
|
+
const sessionId = this.currentSessionId();
|
|
6154
|
+
if (sessionId === void 0) return 1;
|
|
6155
|
+
const scope = this.ctx.sessions.scope(dshSessionId(sessionId));
|
|
6156
|
+
if (scope === void 0) return 1;
|
|
6157
|
+
return conversationAnnotations(this.ctx.conversation.input.for(scope).state.getSnapshot()).length + 1;
|
|
6158
|
+
}
|
|
6159
|
+
/** Remove the current Session's unsent selected-passage annotations. */
|
|
6160
|
+
removeConversationAnnotations() {
|
|
6161
|
+
const sessionId = this.currentSessionId();
|
|
6162
|
+
if (sessionId === void 0) return false;
|
|
6163
|
+
const scope = this.ctx.sessions.scope(dshSessionId(sessionId));
|
|
6164
|
+
if (scope === void 0) return false;
|
|
6165
|
+
return removeConversationAnnotations(this.ctx.conversation.input.for(scope));
|
|
6166
|
+
}
|
|
5719
6167
|
async retain(sessionId) {
|
|
5720
6168
|
const binding = await this.waitForBinding(dshSessionId(sessionId));
|
|
5721
6169
|
await binding.session.open();
|
|
@@ -5787,10 +6235,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5787
6235
|
}
|
|
5788
6236
|
//#endregion
|
|
5789
6237
|
//#region src/client/rc6/Rc6SideChatOverlay.tsx
|
|
6238
|
+
const MORE_DETAILS_PROMPT = "Please explain the selected passage in more detail.";
|
|
5790
6239
|
function captureEvent(event) {
|
|
5791
6240
|
if (event instanceof KeyboardEvent && event.key === "Escape") return false;
|
|
5792
6241
|
const target = event.target;
|
|
5793
|
-
return !(target instanceof Element && target.closest(
|
|
6242
|
+
return !(target instanceof Element && target.closest([
|
|
6243
|
+
"[data-side-chat-panel]",
|
|
6244
|
+
".dsh-side-chat-selection-actions",
|
|
6245
|
+
".dsh-side-chat-selection-comment"
|
|
6246
|
+
].join(", ")) !== null);
|
|
6247
|
+
}
|
|
6248
|
+
function focusParentComposer() {
|
|
6249
|
+
const input = document.querySelector([
|
|
6250
|
+
"[data-composer-seat] textarea",
|
|
6251
|
+
"[data-composer-seat] [role=\"textbox\"]",
|
|
6252
|
+
"[data-composer-seat] [contenteditable=\"true\"]"
|
|
6253
|
+
].join(", "));
|
|
6254
|
+
if (input === null) return;
|
|
6255
|
+
input.focus();
|
|
6256
|
+
if (input instanceof HTMLTextAreaElement) {
|
|
6257
|
+
input.setSelectionRange(input.value.length, input.value.length);
|
|
6258
|
+
return;
|
|
6259
|
+
}
|
|
6260
|
+
const range = document.createRange();
|
|
6261
|
+
range.selectNodeContents(input);
|
|
6262
|
+
range.collapse(false);
|
|
6263
|
+
const selection = window.getSelection();
|
|
6264
|
+
selection?.removeAllRanges();
|
|
6265
|
+
selection?.addRange(range);
|
|
5794
6266
|
}
|
|
5795
6267
|
/** rc.6 compatibility surface: selection toolbar plus a non-current child conversation panel. */
|
|
5796
6268
|
function Rc6SideChatOverlay({ controller, sessions }) {
|
|
@@ -5799,6 +6271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5799
6271
|
const [selection, setSelection] = (0, react.useState)(null);
|
|
5800
6272
|
const captureGeneration = (0, react.useRef)(0);
|
|
5801
6273
|
const mouseDownPoint = (0, react.useRef)(null);
|
|
6274
|
+
const annotationEditing = (0, react.useRef)(false);
|
|
5802
6275
|
const capture = (0, react.useCallback)(async () => {
|
|
5803
6276
|
const generation = ++captureGeneration.current;
|
|
5804
6277
|
const parentSessionId = sessions.currentSessionId();
|
|
@@ -5835,6 +6308,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5835
6308
|
x: event.clientX,
|
|
5836
6309
|
y: event.clientY
|
|
5837
6310
|
};
|
|
6311
|
+
annotationEditing.current = false;
|
|
5838
6312
|
++captureGeneration.current;
|
|
5839
6313
|
setSelection(null);
|
|
5840
6314
|
};
|
|
@@ -5845,6 +6319,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5845
6319
|
if (start === null || Math.abs(event.clientX - start.x) > 2 || Math.abs(event.clientY - start.y) > 2 || event.detail > 1 || event.shiftKey) capture();
|
|
5846
6320
|
};
|
|
5847
6321
|
const onSelectionChange = () => {
|
|
6322
|
+
if (annotationEditing.current) return;
|
|
5848
6323
|
const browserSelection = window.getSelection();
|
|
5849
6324
|
if (browserSelection !== null && !browserSelection.isCollapsed) return;
|
|
5850
6325
|
++captureGeneration.current;
|
|
@@ -5872,25 +6347,46 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5872
6347
|
}, [capture, controller]);
|
|
5873
6348
|
(0, react.useEffect)(() => {
|
|
5874
6349
|
++captureGeneration.current;
|
|
6350
|
+
annotationEditing.current = false;
|
|
5875
6351
|
setSelection(null);
|
|
5876
6352
|
}, [currentSessionId]);
|
|
5877
6353
|
const askDisabledReason = state.phase === "closed" ? void 0 : "Close the current Side Chat before starting another one.";
|
|
5878
6354
|
const childFace = state.childSessionId === void 0 ? void 0 : sessions.face(state.childSessionId);
|
|
5879
6355
|
const inheritedThroughSeq = state.inheritedThroughSeq;
|
|
5880
6356
|
const locale = navigator.language.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
|
|
5881
|
-
const copySelection = (text) => {
|
|
5882
|
-
navigator.clipboard.writeText(text).catch(() => {
|
|
5883
|
-
sessions.notify({
|
|
5884
|
-
kind: "warning",
|
|
5885
|
-
text: "Could not copy the selected text."
|
|
5886
|
-
});
|
|
5887
|
-
});
|
|
5888
|
-
};
|
|
5889
6357
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5890
6358
|
className: "dsh-side-chat-overlay",
|
|
5891
6359
|
children: [selection !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionActions, {
|
|
5892
6360
|
selection,
|
|
6361
|
+
annotationNumber: sessions.nextConversationAnnotationNumber(),
|
|
5893
6362
|
...askDisabledReason === void 0 ? {} : { askDisabledReason },
|
|
6363
|
+
onAddToChat: (captured, comment) => {
|
|
6364
|
+
try {
|
|
6365
|
+
if (sessions.addSelectionToConversation(captured, comment)) focusParentComposer();
|
|
6366
|
+
else sessions.notify({
|
|
6367
|
+
kind: "warning",
|
|
6368
|
+
text: "Could not add the selection to the current chat."
|
|
6369
|
+
});
|
|
6370
|
+
} catch {
|
|
6371
|
+
sessions.notify({
|
|
6372
|
+
kind: "warning",
|
|
6373
|
+
text: "Could not add the selection to the current chat."
|
|
6374
|
+
});
|
|
6375
|
+
}
|
|
6376
|
+
setSelection(null);
|
|
6377
|
+
},
|
|
6378
|
+
onAnnotationEditorChange: (open) => {
|
|
6379
|
+
annotationEditing.current = open;
|
|
6380
|
+
},
|
|
6381
|
+
onMoreDetails: (captured) => {
|
|
6382
|
+
const opened = controller.openDraft({ selection: captured });
|
|
6383
|
+
if (!opened.ok) sessions.notify({
|
|
6384
|
+
kind: "warning",
|
|
6385
|
+
text: opened.error.message
|
|
6386
|
+
});
|
|
6387
|
+
else controller.sendFirst(MORE_DETAILS_PROMPT);
|
|
6388
|
+
setSelection(null);
|
|
6389
|
+
},
|
|
5894
6390
|
onAskInSideChat: (captured) => {
|
|
5895
6391
|
const opened = controller.openDraft({ selection: captured });
|
|
5896
6392
|
if (!opened.ok) sessions.notify({
|
|
@@ -5900,6 +6396,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5900
6396
|
setSelection(null);
|
|
5901
6397
|
},
|
|
5902
6398
|
onDismiss: () => {
|
|
6399
|
+
annotationEditing.current = false;
|
|
5903
6400
|
setSelection(null);
|
|
5904
6401
|
}
|
|
5905
6402
|
}), state.phase !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SideChatPanel, {
|
|
@@ -5910,8 +6407,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5910
6407
|
inheritedThroughSeq,
|
|
5911
6408
|
controller,
|
|
5912
6409
|
...state.selection === void 0 ? {} : { selection: state.selection },
|
|
5913
|
-
locale
|
|
5914
|
-
onCopySelection: copySelection
|
|
6410
|
+
locale
|
|
5915
6411
|
}) },
|
|
5916
6412
|
onDraftChange: (draft) => {
|
|
5917
6413
|
controller.setDraft(draft);
|
|
@@ -5922,7 +6418,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5922
6418
|
onFocusParent: () => {
|
|
5923
6419
|
if (state.parentSessionId !== void 0) sessions.openSession(state.parentSessionId);
|
|
5924
6420
|
},
|
|
5925
|
-
onCopySelection: copySelection,
|
|
5926
6421
|
onRemoveSelection: () => {
|
|
5927
6422
|
controller.clearSelection();
|
|
5928
6423
|
}
|
|
@@ -5933,6 +6428,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5933
6428
|
//#region src/client/apply.ts
|
|
5934
6429
|
const name = "side-chat-client";
|
|
5935
6430
|
const inject = [
|
|
6431
|
+
"conversation",
|
|
6432
|
+
"inputTriggers",
|
|
5936
6433
|
"remote",
|
|
5937
6434
|
"sessions",
|
|
5938
6435
|
"slots"
|
|
@@ -5945,7 +6442,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5945
6442
|
document.head.append(stylesheet);
|
|
5946
6443
|
const clientCtx = ctx;
|
|
5947
6444
|
const mounted = await mountArchivedRemote(clientCtx);
|
|
6445
|
+
const removeSelectionReferenceSource = clientCtx.inputTriggers.registerSource(selectionReferenceSource);
|
|
5948
6446
|
const sessions = new Rc6SideChatSessions(clientCtx);
|
|
6447
|
+
const removeParentAnnotations = mountParentConversationAnnotations(clientCtx, () => {
|
|
6448
|
+
sessions.removeConversationAnnotations();
|
|
6449
|
+
});
|
|
5949
6450
|
const controller = new SideChatController(mounted.remote, sessions);
|
|
5950
6451
|
const removeOverlay = clientCtx.slots.inject("shell.overlay", () => clientCtx.slots.register({
|
|
5951
6452
|
name: "shell.overlay",
|
|
@@ -5959,6 +6460,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5959
6460
|
try {
|
|
5960
6461
|
await controller.dispose();
|
|
5961
6462
|
} finally {
|
|
6463
|
+
removeParentAnnotations();
|
|
6464
|
+
removeSelectionReferenceSource();
|
|
5962
6465
|
removeOverlay();
|
|
5963
6466
|
await mounted.dispose();
|
|
5964
6467
|
stylesheet.remove();
|