@ahggg/dsh-side-chat 0.3.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 +8 -6
- package/README.zh-CN.md +8 -6
- 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 +32 -9
- 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/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 +2 -2
- 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 +48 -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 +4 -1
- package/lib/client/selection/SelectionActions.d.ts.map +1 -1
- package/lib/client/selection/SelectionActions.js +62 -3
- package/lib/client/selection/SelectionActions.js.map +1 -1
- package/lib/client.js +619 -179
- package/lib/client.js.map +1 -1
- package/package.json +2 -1
package/lib/client.js
CHANGED
|
@@ -8,7 +8,422 @@ 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 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: 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: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: translate(var(--dsh-side-chat-quote-offset-x, 0px), 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.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@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
|
+
}
|
|
12
427
|
//#endregion
|
|
13
428
|
//#region src/shared/observable.ts
|
|
14
429
|
/** Immutable-value observable with contained subscriber failures. */
|
|
@@ -47,31 +462,6 @@ window.__ModuleLoader__.load({
|
|
|
47
462
|
this.listeners.clear();
|
|
48
463
|
}
|
|
49
464
|
};
|
|
50
|
-
//#endregion
|
|
51
|
-
//#region src/client/parent-composer/add-to-conversation.ts
|
|
52
|
-
function escapeXmlText(value) {
|
|
53
|
-
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
54
|
-
}
|
|
55
|
-
/** Add the selected quote to the first child prompt. */
|
|
56
|
-
function buildSideChatPrompt(selection, question) {
|
|
57
|
-
const trimmed = question.trim();
|
|
58
|
-
if (selection === void 0) return [{
|
|
59
|
-
type: "text",
|
|
60
|
-
text: trimmed
|
|
61
|
-
}];
|
|
62
|
-
return [{
|
|
63
|
-
type: "text",
|
|
64
|
-
text: [
|
|
65
|
-
`<selected_context source="current-conversation" event-seq="${selection.atSeq}">`,
|
|
66
|
-
escapeXmlText(selection.text),
|
|
67
|
-
"</selected_context>",
|
|
68
|
-
"",
|
|
69
|
-
"<user_question>",
|
|
70
|
-
escapeXmlText(trimmed),
|
|
71
|
-
"</user_question>"
|
|
72
|
-
].join("\n")
|
|
73
|
-
}];
|
|
74
|
-
}
|
|
75
465
|
Object.freeze({
|
|
76
466
|
repository: "https://github.com/deepseek-ai/deepseek-harness",
|
|
77
467
|
npmPackage: "@deepseek-ai/dsh",
|
|
@@ -4785,120 +5175,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4785
5175
|
};
|
|
4786
5176
|
}
|
|
4787
5177
|
//#endregion
|
|
4788
|
-
//#region src/client/panel/messages.ts
|
|
4789
|
-
const SIDE_CHAT_MESSAGES = Object.freeze({
|
|
4790
|
-
en: Object.freeze({
|
|
4791
|
-
title: "Side Chat",
|
|
4792
|
-
close: "Close Side Chat",
|
|
4793
|
-
placeholder: "Ask about this in a Side Chat",
|
|
4794
|
-
send: "Send",
|
|
4795
|
-
selectedPassage: "Selected passage",
|
|
4796
|
-
selectionAttachment: "1 annotation",
|
|
4797
|
-
selectionPreviewLabel: "Selected text",
|
|
4798
|
-
removeSelection: "Remove annotation",
|
|
4799
|
-
expand: "Expand",
|
|
4800
|
-
collapse: "Collapse",
|
|
4801
|
-
copy: "Copy",
|
|
4802
|
-
temporary: "Archived when closed; history remains on disk",
|
|
4803
|
-
referenceOnly: "Inherits the complete parent conversation prefix",
|
|
4804
|
-
cannotReopen: "No reopen action",
|
|
4805
|
-
sharedWorkspace: "Shares the parent workspace",
|
|
4806
|
-
retry: "Retry",
|
|
4807
|
-
genericError: "Side Chat error",
|
|
4808
|
-
closeError: "Could not close the Side Chat"
|
|
4809
|
-
}),
|
|
4810
|
-
"zh-CN": Object.freeze({
|
|
4811
|
-
title: "侧边对话",
|
|
4812
|
-
close: "关闭侧边对话",
|
|
4813
|
-
placeholder: "在侧边对话中询问这段内容",
|
|
4814
|
-
send: "发送",
|
|
4815
|
-
selectedPassage: "所选段落",
|
|
4816
|
-
selectionAttachment: "1 条引用",
|
|
4817
|
-
selectionPreviewLabel: "所选文本",
|
|
4818
|
-
removeSelection: "移除引用",
|
|
4819
|
-
expand: "展开",
|
|
4820
|
-
collapse: "收起",
|
|
4821
|
-
copy: "复制",
|
|
4822
|
-
temporary: "关闭时归档;历史仍保存在磁盘上",
|
|
4823
|
-
referenceOnly: "完整继承父会话对话前缀",
|
|
4824
|
-
cannotReopen: "不提供重新打开操作",
|
|
4825
|
-
sharedWorkspace: "与父会话共享工作区",
|
|
4826
|
-
retry: "重试",
|
|
4827
|
-
genericError: "侧边对话错误",
|
|
4828
|
-
closeError: "无法关闭侧边对话"
|
|
4829
|
-
})
|
|
4830
|
-
});
|
|
4831
|
-
//#endregion
|
|
4832
|
-
//#region src/client/panel/SelectionQuote.tsx
|
|
4833
|
-
/** Selected passage displayed separately from the user's first question. */
|
|
4834
|
-
function SelectionQuote({ selection, messages, onCopy, onRemove }) {
|
|
4835
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
4836
|
-
const quoteRef = (0, react.useRef)(null);
|
|
4837
|
-
const detailsRef = (0, react.useRef)(null);
|
|
4838
|
-
const constrainDetailsToPanel = () => {
|
|
4839
|
-
const details = detailsRef.current;
|
|
4840
|
-
const panel = quoteRef.current?.closest(".dsh-side-chat-panel");
|
|
4841
|
-
if (details === null || panel === void 0 || panel === null) return;
|
|
4842
|
-
details.style.setProperty("--dsh-side-chat-quote-offset-x", "0px");
|
|
4843
|
-
const detailsRect = details.getBoundingClientRect();
|
|
4844
|
-
const panelRect = panel.getBoundingClientRect();
|
|
4845
|
-
const leftEdge = panelRect.left + 16;
|
|
4846
|
-
const rightEdge = panelRect.right - 16;
|
|
4847
|
-
const offset = detailsRect.left < leftEdge ? leftEdge - detailsRect.left : detailsRect.right > rightEdge ? rightEdge - detailsRect.right : 0;
|
|
4848
|
-
details.style.setProperty("--dsh-side-chat-quote-offset-x", `${String(offset)}px`);
|
|
4849
|
-
};
|
|
4850
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
4851
|
-
ref: quoteRef,
|
|
4852
|
-
className: "dsh-side-chat-quote",
|
|
4853
|
-
"aria-label": messages.selectedPassage,
|
|
4854
|
-
"data-expanded": expanded || void 0,
|
|
4855
|
-
onMouseEnter: constrainDetailsToPanel,
|
|
4856
|
-
onFocusCapture: constrainDetailsToPanel,
|
|
4857
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4858
|
-
className: "dsh-side-chat-quote-chip",
|
|
4859
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4860
|
-
type: "button",
|
|
4861
|
-
className: "dsh-side-chat-quote-trigger",
|
|
4862
|
-
"aria-expanded": expanded,
|
|
4863
|
-
"aria-label": `${expanded ? messages.collapse : messages.expand}: ${messages.selectedPassage}`,
|
|
4864
|
-
onClick: () => {
|
|
4865
|
-
setExpanded((value) => !value);
|
|
4866
|
-
},
|
|
4867
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
4868
|
-
className: "dsh-side-chat-quote-icon",
|
|
4869
|
-
viewBox: "0 0 24 24",
|
|
4870
|
-
"aria-hidden": "true",
|
|
4871
|
-
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" })]
|
|
4872
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: messages.selectionAttachment })]
|
|
4873
|
-
}), onRemove !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4874
|
-
type: "button",
|
|
4875
|
-
className: "dsh-side-chat-quote-remove",
|
|
4876
|
-
"aria-label": messages.removeSelection,
|
|
4877
|
-
onClick: onRemove,
|
|
4878
|
-
children: "×"
|
|
4879
|
-
})]
|
|
4880
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4881
|
-
ref: detailsRef,
|
|
4882
|
-
className: "dsh-side-chat-quote-details",
|
|
4883
|
-
role: "tooltip",
|
|
4884
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4885
|
-
className: "dsh-side-chat-quote-details-header",
|
|
4886
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [
|
|
4887
|
-
"1. ",
|
|
4888
|
-
messages.selectionPreviewLabel,
|
|
4889
|
-
":"
|
|
4890
|
-
] }), onCopy !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4891
|
-
type: "button",
|
|
4892
|
-
onClick: () => {
|
|
4893
|
-
onCopy(selection.text);
|
|
4894
|
-
},
|
|
4895
|
-
children: messages.copy
|
|
4896
|
-
})]
|
|
4897
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: selection.text })]
|
|
4898
|
-
})]
|
|
4899
|
-
});
|
|
4900
|
-
}
|
|
4901
|
-
//#endregion
|
|
4902
5178
|
//#region src/client/panel/SendIcon.tsx
|
|
4903
5179
|
/** Arrow used by DSH's native 34px primary send button. */
|
|
4904
5180
|
function SendIcon() {
|
|
@@ -4977,7 +5253,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4977
5253
|
}
|
|
4978
5254
|
//#endregion
|
|
4979
5255
|
//#region src/client/panel/SideChatPanel.tsx
|
|
4980
|
-
function SideChatPanel({ state, locale = "en", embeddedConversation, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent,
|
|
5256
|
+
function SideChatPanel({ state, locale = "en", embeddedConversation, onDraftChange, onFirstSend, onClose, onRetry, onFocusParent, onRemoveSelection }) {
|
|
4981
5257
|
const messages = SIDE_CHAT_MESSAGES[locale];
|
|
4982
5258
|
const [submitting, setSubmitting] = (0, react.useState)(false);
|
|
4983
5259
|
const draftRef = useAutoGrowingTextarea(state.draft);
|
|
@@ -5023,9 +5299,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5023
5299
|
},
|
|
5024
5300
|
children: [
|
|
5025
5301
|
state.selection !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
5026
|
-
|
|
5302
|
+
selections: [state.selection],
|
|
5027
5303
|
messages,
|
|
5028
|
-
...onCopySelection === void 0 ? {} : { onCopy: onCopySelection },
|
|
5029
5304
|
...onRemoveSelection === void 0 ? {} : { onRemove: onRemoveSelection }
|
|
5030
5305
|
}),
|
|
5031
5306
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
@@ -5172,16 +5447,103 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5172
5447
|
}
|
|
5173
5448
|
//#endregion
|
|
5174
5449
|
//#region src/client/selection/SelectionActions.tsx
|
|
5175
|
-
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);
|
|
5176
5457
|
const center = selection.rect.x + selection.rect.width / 2;
|
|
5177
5458
|
const style = {
|
|
5178
5459
|
left: Math.min(Math.max(8, center), selection.rect.viewportWidth - 8),
|
|
5179
5460
|
top: selection.rect.y < 56 ? selection.rect.y + selection.rect.height + 8 : selection.rect.y - 8,
|
|
5180
5461
|
transform: selection.rect.y < 56 ? "translate(0, 0)" : "translate(0, -100%)"
|
|
5181
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
|
+
};
|
|
5182
5474
|
const keepSelection = (event) => {
|
|
5183
5475
|
event.preventDefault();
|
|
5184
5476
|
};
|
|
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
|
+
})] });
|
|
5185
5547
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5186
5548
|
className: "dsh-side-chat-selection-actions",
|
|
5187
5549
|
role: "toolbar",
|
|
@@ -5191,25 +5553,36 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5191
5553
|
onKeyDown: (event) => {
|
|
5192
5554
|
if (event.key === "Escape") onDismiss();
|
|
5193
5555
|
},
|
|
5194
|
-
children: [
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
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
|
+
]
|
|
5213
5586
|
});
|
|
5214
5587
|
}
|
|
5215
5588
|
//#endregion
|
|
@@ -5481,7 +5854,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5481
5854
|
});
|
|
5482
5855
|
}
|
|
5483
5856
|
/** Functional rc.6 conversation surface bound to a non-current child Session. */
|
|
5484
|
-
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en"
|
|
5857
|
+
function ArchivedConversation({ face, inheritedThroughSeq, controller, selection, locale = "en" }) {
|
|
5485
5858
|
const snapshot = (0, react.useSyncExternalStore)((listener) => face.subscribe(listener), () => face.getSnapshot(), () => face.getSnapshot());
|
|
5486
5859
|
const [draft, setDraft] = (0, react.useState)("");
|
|
5487
5860
|
const [sending, setSending] = (0, react.useState)(false);
|
|
@@ -5528,9 +5901,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5528
5901
|
nodes.map((node) => selection !== void 0 && node === annotatedUserNode ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5529
5902
|
className: "dsh-side-chat-annotated-user-message",
|
|
5530
5903
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionQuote, {
|
|
5531
|
-
selection,
|
|
5532
|
-
messages: SIDE_CHAT_MESSAGES[locale]
|
|
5533
|
-
...onCopySelection === void 0 ? {} : { onCopy: onCopySelection }
|
|
5904
|
+
selections: [selection],
|
|
5905
|
+
messages: SIDE_CHAT_MESSAGES[locale]
|
|
5534
5906
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, { node })]
|
|
5535
5907
|
}, `${node.kind}-${String(node.seq)}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageRow, { node }, `${node.kind}-${String(node.seq)}`)),
|
|
5536
5908
|
snapshot.partial !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
@@ -5769,6 +6141,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5769
6141
|
return node !== void 0 && node.visibility === "visible" && node.kind === fragment.nodeKind && node.anchorSeq === fragment.seq && locationSettled(node.location);
|
|
5770
6142
|
});
|
|
5771
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
|
+
}
|
|
5772
6167
|
async retain(sessionId) {
|
|
5773
6168
|
const binding = await this.waitForBinding(dshSessionId(sessionId));
|
|
5774
6169
|
await binding.session.open();
|
|
@@ -5844,7 +6239,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5844
6239
|
function captureEvent(event) {
|
|
5845
6240
|
if (event instanceof KeyboardEvent && event.key === "Escape") return false;
|
|
5846
6241
|
const target = event.target;
|
|
5847
|
-
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);
|
|
5848
6266
|
}
|
|
5849
6267
|
/** rc.6 compatibility surface: selection toolbar plus a non-current child conversation panel. */
|
|
5850
6268
|
function Rc6SideChatOverlay({ controller, sessions }) {
|
|
@@ -5853,6 +6271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5853
6271
|
const [selection, setSelection] = (0, react.useState)(null);
|
|
5854
6272
|
const captureGeneration = (0, react.useRef)(0);
|
|
5855
6273
|
const mouseDownPoint = (0, react.useRef)(null);
|
|
6274
|
+
const annotationEditing = (0, react.useRef)(false);
|
|
5856
6275
|
const capture = (0, react.useCallback)(async () => {
|
|
5857
6276
|
const generation = ++captureGeneration.current;
|
|
5858
6277
|
const parentSessionId = sessions.currentSessionId();
|
|
@@ -5889,6 +6308,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5889
6308
|
x: event.clientX,
|
|
5890
6309
|
y: event.clientY
|
|
5891
6310
|
};
|
|
6311
|
+
annotationEditing.current = false;
|
|
5892
6312
|
++captureGeneration.current;
|
|
5893
6313
|
setSelection(null);
|
|
5894
6314
|
};
|
|
@@ -5899,6 +6319,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5899
6319
|
if (start === null || Math.abs(event.clientX - start.x) > 2 || Math.abs(event.clientY - start.y) > 2 || event.detail > 1 || event.shiftKey) capture();
|
|
5900
6320
|
};
|
|
5901
6321
|
const onSelectionChange = () => {
|
|
6322
|
+
if (annotationEditing.current) return;
|
|
5902
6323
|
const browserSelection = window.getSelection();
|
|
5903
6324
|
if (browserSelection !== null && !browserSelection.isCollapsed) return;
|
|
5904
6325
|
++captureGeneration.current;
|
|
@@ -5926,25 +6347,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5926
6347
|
}, [capture, controller]);
|
|
5927
6348
|
(0, react.useEffect)(() => {
|
|
5928
6349
|
++captureGeneration.current;
|
|
6350
|
+
annotationEditing.current = false;
|
|
5929
6351
|
setSelection(null);
|
|
5930
6352
|
}, [currentSessionId]);
|
|
5931
6353
|
const askDisabledReason = state.phase === "closed" ? void 0 : "Close the current Side Chat before starting another one.";
|
|
5932
6354
|
const childFace = state.childSessionId === void 0 ? void 0 : sessions.face(state.childSessionId);
|
|
5933
6355
|
const inheritedThroughSeq = state.inheritedThroughSeq;
|
|
5934
6356
|
const locale = navigator.language.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
|
|
5935
|
-
const copySelection = (text) => {
|
|
5936
|
-
navigator.clipboard.writeText(text).catch(() => {
|
|
5937
|
-
sessions.notify({
|
|
5938
|
-
kind: "warning",
|
|
5939
|
-
text: "Could not copy the selected text."
|
|
5940
|
-
});
|
|
5941
|
-
});
|
|
5942
|
-
};
|
|
5943
6357
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5944
6358
|
className: "dsh-side-chat-overlay",
|
|
5945
6359
|
children: [selection !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionActions, {
|
|
5946
6360
|
selection,
|
|
6361
|
+
annotationNumber: sessions.nextConversationAnnotationNumber(),
|
|
5947
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
|
+
},
|
|
5948
6381
|
onMoreDetails: (captured) => {
|
|
5949
6382
|
const opened = controller.openDraft({ selection: captured });
|
|
5950
6383
|
if (!opened.ok) sessions.notify({
|
|
@@ -5963,6 +6396,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5963
6396
|
setSelection(null);
|
|
5964
6397
|
},
|
|
5965
6398
|
onDismiss: () => {
|
|
6399
|
+
annotationEditing.current = false;
|
|
5966
6400
|
setSelection(null);
|
|
5967
6401
|
}
|
|
5968
6402
|
}), state.phase !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SideChatPanel, {
|
|
@@ -5973,8 +6407,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5973
6407
|
inheritedThroughSeq,
|
|
5974
6408
|
controller,
|
|
5975
6409
|
...state.selection === void 0 ? {} : { selection: state.selection },
|
|
5976
|
-
locale
|
|
5977
|
-
onCopySelection: copySelection
|
|
6410
|
+
locale
|
|
5978
6411
|
}) },
|
|
5979
6412
|
onDraftChange: (draft) => {
|
|
5980
6413
|
controller.setDraft(draft);
|
|
@@ -5985,7 +6418,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5985
6418
|
onFocusParent: () => {
|
|
5986
6419
|
if (state.parentSessionId !== void 0) sessions.openSession(state.parentSessionId);
|
|
5987
6420
|
},
|
|
5988
|
-
onCopySelection: copySelection,
|
|
5989
6421
|
onRemoveSelection: () => {
|
|
5990
6422
|
controller.clearSelection();
|
|
5991
6423
|
}
|
|
@@ -5996,6 +6428,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5996
6428
|
//#region src/client/apply.ts
|
|
5997
6429
|
const name = "side-chat-client";
|
|
5998
6430
|
const inject = [
|
|
6431
|
+
"conversation",
|
|
6432
|
+
"inputTriggers",
|
|
5999
6433
|
"remote",
|
|
6000
6434
|
"sessions",
|
|
6001
6435
|
"slots"
|
|
@@ -6008,7 +6442,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6008
6442
|
document.head.append(stylesheet);
|
|
6009
6443
|
const clientCtx = ctx;
|
|
6010
6444
|
const mounted = await mountArchivedRemote(clientCtx);
|
|
6445
|
+
const removeSelectionReferenceSource = clientCtx.inputTriggers.registerSource(selectionReferenceSource);
|
|
6011
6446
|
const sessions = new Rc6SideChatSessions(clientCtx);
|
|
6447
|
+
const removeParentAnnotations = mountParentConversationAnnotations(clientCtx, () => {
|
|
6448
|
+
sessions.removeConversationAnnotations();
|
|
6449
|
+
});
|
|
6012
6450
|
const controller = new SideChatController(mounted.remote, sessions);
|
|
6013
6451
|
const removeOverlay = clientCtx.slots.inject("shell.overlay", () => clientCtx.slots.register({
|
|
6014
6452
|
name: "shell.overlay",
|
|
@@ -6022,6 +6460,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6022
6460
|
try {
|
|
6023
6461
|
await controller.dispose();
|
|
6024
6462
|
} finally {
|
|
6463
|
+
removeParentAnnotations();
|
|
6464
|
+
removeSelectionReferenceSource();
|
|
6025
6465
|
removeOverlay();
|
|
6026
6466
|
await mounted.dispose();
|
|
6027
6467
|
stylesheet.remove();
|