@ahggg/dsh-side-chat 0.7.2 → 1.0.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 +16 -13
- package/README.zh-CN.md +16 -13
- package/lib/client/apply.d.ts +0 -1
- package/lib/client/apply.js +48 -33
- package/lib/client/contracts.d.ts +3 -59
- package/lib/client/contracts.js +0 -1
- package/lib/client/dsh/ReadOnlyConversation.d.ts +10 -0
- package/lib/client/dsh/ReadOnlyConversation.js +91 -0
- package/lib/client/dsh/SideChatOverlay.d.ts +7 -0
- package/lib/client/{rc6/Rc6SideChatOverlay.js → dsh/SideChatOverlay.js} +26 -57
- package/lib/client/{rc6 → dsh}/context.d.ts +7 -3
- package/lib/client/dsh/context.js +1 -0
- package/lib/client/dsh/conversation-store.d.ts +22 -0
- package/lib/client/dsh/conversation-store.js +19 -0
- package/lib/client/dsh/primitive-labels.d.ts +2 -0
- package/lib/client/dsh/primitive-labels.js +4 -0
- package/lib/client/{rc6 → dsh}/remote-adapter.d.ts +2 -3
- package/lib/client/dsh/remote-adapter.js +22 -0
- package/lib/client/dsh/sessions-adapter.d.ts +56 -0
- package/lib/client/dsh/sessions-adapter.js +185 -0
- package/lib/client/index.d.ts +2 -3
- package/lib/client/index.js +0 -1
- package/lib/client/model-preference.d.ts +0 -1
- package/lib/client/model-preference.js +0 -1
- package/lib/client/panel/SelectionQuote.d.ts +0 -1
- package/lib/client/panel/SelectionQuote.js +8 -2
- package/lib/client/panel/SendIcon.d.ts +0 -1
- package/lib/client/panel/SendIcon.js +0 -1
- package/lib/client/panel/SideChatBody.d.ts +0 -1
- package/lib/client/panel/SideChatBody.js +0 -1
- package/lib/client/panel/SideChatErrorState.d.ts +0 -1
- package/lib/client/panel/SideChatErrorState.js +1 -2
- package/lib/client/panel/SideChatHeader.d.ts +0 -1
- package/lib/client/panel/SideChatHeader.js +0 -1
- package/lib/client/panel/SideChatModelSelect.d.ts +0 -1
- package/lib/client/panel/SideChatModelSelect.js +37 -19
- package/lib/client/panel/SideChatPanel.d.ts +0 -1
- package/lib/client/panel/SideChatPanel.js +12 -6
- package/lib/client/panel/StopIcon.d.ts +0 -1
- package/lib/client/panel/StopIcon.js +0 -1
- package/lib/client/panel/messages.d.ts +1 -2
- package/lib/client/panel/messages.js +8 -9
- package/lib/client/panel/use-auto-growing-textarea.d.ts +0 -1
- package/lib/client/panel/use-auto-growing-textarea.js +0 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts +3 -3
- package/lib/client/parent-composer/ParentConversationAnnotations.js +71 -28
- package/lib/client/parent-composer/add-to-conversation.d.ts +14 -29
- package/lib/client/parent-composer/add-to-conversation.js +134 -457
- package/lib/client/parent-composer/annotation-persistence.d.ts +8 -9
- package/lib/client/parent-composer/annotation-persistence.js +106 -103
- package/lib/client/parent-composer/composer-reference.d.ts +19 -48
- package/lib/client/parent-composer/composer-reference.js +26 -46
- package/lib/client/parent-composer/referenced-conversation.d.ts +5 -8
- package/lib/client/parent-composer/referenced-conversation.js +27 -61
- package/lib/client/selection/ConversationAnnotationMarkers.d.ts +0 -1
- package/lib/client/selection/ConversationAnnotationMarkers.js +5 -2
- package/lib/client/selection/SelectionActions.d.ts +0 -1
- package/lib/client/selection/SelectionActions.js +2 -2
- package/lib/client/selection/conversation-dom.d.ts +5 -0
- package/lib/client/selection/conversation-dom.js +24 -0
- package/lib/client/selection/selection-controller.d.ts +1 -2
- package/lib/client/selection/selection-controller.js +7 -4
- package/lib/client/selection/selection-limits.d.ts +0 -1
- package/lib/client/selection/selection-limits.js +0 -1
- package/lib/client/selection/selection-normalizer.d.ts +0 -1
- package/lib/client/selection/selection-normalizer.js +1 -2
- package/lib/client/side-chat-controller.d.ts +28 -42
- package/lib/client/side-chat-controller.js +245 -338
- package/lib/client.js +1202 -8951
- package/lib/host/index.d.ts +1 -2
- package/lib/host/index.js +1 -2
- package/lib/host/read-only-chat-service.d.ts +30 -0
- package/lib/host/read-only-chat-service.js +314 -0
- package/lib/index.d.ts +16 -9
- package/lib/index.js +34 -14
- package/lib/remote.d.ts +23 -15
- package/lib/remote.js +2 -6
- package/lib/shared/constants.d.ts +0 -14
- package/lib/shared/constants.js +0 -14
- package/lib/shared/contracts.d.ts +52 -20
- package/lib/shared/contracts.js +2 -4
- package/lib/shared/error-codes.d.ts +1 -2
- package/lib/shared/error-codes.js +2 -3
- package/lib/shared/observable.d.ts +0 -1
- package/lib/shared/observable.js +0 -1
- package/lib/shared/{archived-wire.d.ts → side-chat-wire.d.ts} +109 -21
- package/lib/shared/side-chat-wire.js +34 -0
- package/lib/typert.d.ts +3 -69
- package/lib/typert.js +120 -51
- package/package.json +80 -38
- package/lib/client/apply.d.ts.map +0 -1
- package/lib/client/apply.js.map +0 -1
- package/lib/client/contracts.d.ts.map +0 -1
- package/lib/client/contracts.js.map +0 -1
- package/lib/client/index.d.ts.map +0 -1
- package/lib/client/index.js.map +0 -1
- package/lib/client/model-preference.d.ts.map +0 -1
- package/lib/client/model-preference.js.map +0 -1
- package/lib/client/panel/SelectionQuote.d.ts.map +0 -1
- package/lib/client/panel/SelectionQuote.js.map +0 -1
- package/lib/client/panel/SendIcon.d.ts.map +0 -1
- package/lib/client/panel/SendIcon.js.map +0 -1
- package/lib/client/panel/SideChatBody.d.ts.map +0 -1
- package/lib/client/panel/SideChatBody.js.map +0 -1
- package/lib/client/panel/SideChatErrorState.d.ts.map +0 -1
- package/lib/client/panel/SideChatErrorState.js.map +0 -1
- package/lib/client/panel/SideChatHeader.d.ts.map +0 -1
- package/lib/client/panel/SideChatHeader.js.map +0 -1
- package/lib/client/panel/SideChatModelSelect.d.ts.map +0 -1
- package/lib/client/panel/SideChatModelSelect.js.map +0 -1
- package/lib/client/panel/SideChatPanel.d.ts.map +0 -1
- package/lib/client/panel/SideChatPanel.js.map +0 -1
- package/lib/client/panel/StopIcon.d.ts.map +0 -1
- package/lib/client/panel/StopIcon.js.map +0 -1
- package/lib/client/panel/messages.d.ts.map +0 -1
- package/lib/client/panel/messages.js.map +0 -1
- package/lib/client/panel/use-auto-growing-textarea.d.ts.map +0 -1
- package/lib/client/panel/use-auto-growing-textarea.js.map +0 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts.map +0 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.js.map +0 -1
- package/lib/client/parent-composer/add-to-conversation.d.ts.map +0 -1
- package/lib/client/parent-composer/add-to-conversation.js.map +0 -1
- package/lib/client/parent-composer/annotation-persistence.d.ts.map +0 -1
- package/lib/client/parent-composer/annotation-persistence.js.map +0 -1
- package/lib/client/parent-composer/composer-reference.d.ts.map +0 -1
- package/lib/client/parent-composer/composer-reference.js.map +0 -1
- package/lib/client/parent-composer/referenced-conversation.d.ts.map +0 -1
- package/lib/client/parent-composer/referenced-conversation.js.map +0 -1
- package/lib/client/rc6/ArchivedConversation.d.ts +0 -15
- package/lib/client/rc6/ArchivedConversation.d.ts.map +0 -1
- package/lib/client/rc6/ArchivedConversation.js +0 -230
- package/lib/client/rc6/ArchivedConversation.js.map +0 -1
- package/lib/client/rc6/Rc6SideChatOverlay.d.ts +0 -8
- package/lib/client/rc6/Rc6SideChatOverlay.d.ts.map +0 -1
- package/lib/client/rc6/Rc6SideChatOverlay.js.map +0 -1
- package/lib/client/rc6/SideChatTool.d.ts +0 -23
- package/lib/client/rc6/SideChatTool.d.ts.map +0 -1
- package/lib/client/rc6/SideChatTool.js +0 -395
- package/lib/client/rc6/SideChatTool.js.map +0 -1
- package/lib/client/rc6/context.d.ts.map +0 -1
- package/lib/client/rc6/context.js +0 -2
- package/lib/client/rc6/context.js.map +0 -1
- package/lib/client/rc6/remote-adapter.d.ts.map +0 -1
- package/lib/client/rc6/remote-adapter.js +0 -33
- package/lib/client/rc6/remote-adapter.js.map +0 -1
- package/lib/client/rc6/sessions-adapter.d.ts +0 -61
- package/lib/client/rc6/sessions-adapter.d.ts.map +0 -1
- package/lib/client/rc6/sessions-adapter.js +0 -370
- package/lib/client/rc6/sessions-adapter.js.map +0 -1
- package/lib/client/selection/ConversationAnnotationMarkers.d.ts.map +0 -1
- package/lib/client/selection/ConversationAnnotationMarkers.js.map +0 -1
- package/lib/client/selection/SelectionActions.d.ts.map +0 -1
- package/lib/client/selection/SelectionActions.js.map +0 -1
- package/lib/client/selection/selection-controller.d.ts.map +0 -1
- package/lib/client/selection/selection-controller.js.map +0 -1
- package/lib/client/selection/selection-limits.d.ts.map +0 -1
- package/lib/client/selection/selection-limits.js.map +0 -1
- package/lib/client/selection/selection-normalizer.d.ts.map +0 -1
- package/lib/client/selection/selection-normalizer.js.map +0 -1
- package/lib/client/side-chat-controller.d.ts.map +0 -1
- package/lib/client/side-chat-controller.js.map +0 -1
- package/lib/client.js.map +0 -1
- package/lib/host/archived-fork-service.d.ts +0 -29
- package/lib/host/archived-fork-service.d.ts.map +0 -1
- package/lib/host/archived-fork-service.js +0 -264
- package/lib/host/archived-fork-service.js.map +0 -1
- package/lib/host/index.d.ts.map +0 -1
- package/lib/host/index.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/remote.d.ts.map +0 -1
- package/lib/remote.js.map +0 -1
- package/lib/shared/archived-wire.d.ts.map +0 -1
- package/lib/shared/archived-wire.js +0 -48
- package/lib/shared/archived-wire.js.map +0 -1
- package/lib/shared/constants.d.ts.map +0 -1
- package/lib/shared/constants.js.map +0 -1
- package/lib/shared/contracts.d.ts.map +0 -1
- package/lib/shared/contracts.js.map +0 -1
- package/lib/shared/error-codes.d.ts.map +0 -1
- package/lib/shared/error-codes.js.map +0 -1
- package/lib/shared/observable.d.ts.map +0 -1
- package/lib/shared/observable.js.map +0 -1
- package/lib/typert.d.ts.map +0 -1
- package/lib/typert.js.map +0 -1
|
@@ -13,7 +13,7 @@ export function SideChatPanel({ state, locale = 'en', embeddedConversation, mode
|
|
|
13
13
|
const draftRef = useAutoGrowingTextarea(state.draft);
|
|
14
14
|
const submit = async (event) => {
|
|
15
15
|
event.preventDefault();
|
|
16
|
-
if (submitting)
|
|
16
|
+
if (submitting || ['creating', 'running', 'closing'].includes(state.phase))
|
|
17
17
|
return;
|
|
18
18
|
setSubmitting(true);
|
|
19
19
|
try {
|
|
@@ -23,13 +23,19 @@ export function SideChatPanel({ state, locale = 'en', embeddedConversation, mode
|
|
|
23
23
|
setSubmitting(false);
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
-
return (_jsxs("aside", { className: "dsh-side-chat-panel", "data-side-chat-panel": "", "aria-label": messages.title, "aria-busy": ['creating', '
|
|
26
|
+
return (_jsxs("aside", { className: "dsh-side-chat-panel", "data-side-chat-panel": "", "aria-label": messages.title, "aria-busy": ['creating', 'closing'].includes(state.phase) || undefined, onKeyDown: (event) => {
|
|
27
|
+
if (event.key === 'Escape' && !event.defaultPrevented && !event.nativeEvent.isComposing) {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
event.stopPropagation();
|
|
30
|
+
void onClose();
|
|
31
|
+
}
|
|
32
|
+
}, children: [_jsx(SideChatHeader, { phase: state.phase, messages: messages, ...onAddToConversation === undefined ? {} : { onAddToConversation }, ...addToConversationDisabled === undefined ? {} : { addToConversationDisabled }, onFocusParent: onFocusParent, onClose: () => { void onClose(); } }), state.error !== undefined && (_jsx(SideChatErrorState, { error: state.error, messages: messages, onRetry: () => { void onRetry(); } })), state.messages.length > 0 && embeddedConversation !== undefined
|
|
27
33
|
? _jsx(SideChatBody, { children: embeddedConversation })
|
|
28
|
-
: (_jsxs("form", { className: "dsh-side-chat-draft", "data-composer-card": "", onSubmit: (event) => { void submit(event); }, children: [state.selection !== undefined && (_jsx(SelectionQuote, { selections: [state.selection], messages: messages, ...onRemoveSelection === undefined ? {} : { onRemove: onRemoveSelection } })), _jsx("label", { htmlFor: "dsh-side-chat-draft-input", children: messages.placeholder }), _jsx("textarea", { id: "dsh-side-chat-draft-input", ref: draftRef, autoFocus: true, rows: 1, value: state.draft, disabled: ['creating', '
|
|
29
|
-
if (event.key === 'Enter' && !event.shiftKey
|
|
34
|
+
: (_jsxs("form", { className: "dsh-side-chat-draft", "data-composer-card": "", onSubmit: (event) => { void submit(event); }, children: [state.selection !== undefined && (_jsx(SelectionQuote, { selections: [state.selection], messages: messages, ...onRemoveSelection === undefined ? {} : { onRemove: onRemoveSelection } })), _jsx("label", { htmlFor: "dsh-side-chat-draft-input", children: messages.placeholder }), _jsx("textarea", { id: "dsh-side-chat-draft-input", ref: draftRef, autoFocus: true, rows: 1, value: state.draft, disabled: ['creating', 'running', 'closing'].includes(state.phase), placeholder: messages.placeholder, onChange: (event) => { onDraftChange(event.target.value); }, onKeyDown: (event) => {
|
|
35
|
+
if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing
|
|
36
|
+
&& event.keyCode !== 229) {
|
|
30
37
|
event.preventDefault();
|
|
31
38
|
event.currentTarget.form?.requestSubmit();
|
|
32
39
|
}
|
|
33
|
-
} }), _jsxs("div", { className: "dsh-side-chat-draft-actions", children: [modelControl, _jsx("button", { type: "submit", className: "dsh-side-chat-send-button", "aria-label": messages.send, disabled: submitting || state.draft.trim().length === 0, children: _jsx(SendIcon, {}) })] })] })), _jsxs("footer", { className: "dsh-side-chat-footer", children: [_jsx("span", { children: messages.temporary }), _jsx("span", { children: messages.referenceOnly }), _jsx("span", { children: messages.cannotReopen }), _jsx("span", { children: messages.
|
|
40
|
+
} }), _jsxs("div", { className: "dsh-side-chat-draft-actions", children: [modelControl, _jsx("button", { type: "submit", className: "dsh-side-chat-send-button", "aria-label": messages.send, disabled: submitting || ['creating', 'running', 'closing'].includes(state.phase) || state.draft.trim().length === 0, children: _jsx(SendIcon, {}) })] })] })), _jsxs("footer", { className: "dsh-side-chat-footer", children: [_jsx("span", { children: messages.temporary }), _jsx("span", { children: messages.referenceOnly }), _jsx("span", { children: messages.cannotReopen }), _jsx("span", { children: messages.readOnly })] }), _jsx("div", { className: "dsh-side-chat-announcer", "aria-live": "polite", children: state.phase === 'running' ? 'Side Chat running' : `Side Chat ${state.phase}` })] }));
|
|
34
41
|
}
|
|
35
|
-
//# sourceMappingURL=SideChatPanel.js.map
|
|
@@ -3,4 +3,3 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
export function StopIcon() {
|
|
4
4
|
return (_jsx("svg", { viewBox: "0 0 16 16", width: "16", height: "16", "aria-hidden": "true", children: _jsx("rect", { x: "3", y: "3", width: "10", height: "10", rx: "3", fill: "currentColor" }) }));
|
|
5
5
|
}
|
|
6
|
-
//# sourceMappingURL=StopIcon.js.map
|
|
@@ -14,10 +14,9 @@ export interface SideChatMessages {
|
|
|
14
14
|
readonly temporary: string;
|
|
15
15
|
readonly referenceOnly: string;
|
|
16
16
|
readonly cannotReopen: string;
|
|
17
|
-
readonly
|
|
17
|
+
readonly readOnly: string;
|
|
18
18
|
readonly retry: string;
|
|
19
19
|
readonly genericError: string;
|
|
20
20
|
readonly closeError: string;
|
|
21
21
|
}
|
|
22
22
|
export declare const SIDE_CHAT_MESSAGES: Readonly<Record<'en' | 'zh-CN', SideChatMessages>>;
|
|
23
|
-
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -12,10 +12,10 @@ export const SIDE_CHAT_MESSAGES = Object.freeze({
|
|
|
12
12
|
removeSelection: 'Remove annotation',
|
|
13
13
|
expand: 'Expand',
|
|
14
14
|
collapse: 'Collapse',
|
|
15
|
-
temporary: '
|
|
16
|
-
referenceOnly: '
|
|
17
|
-
cannotReopen: '
|
|
18
|
-
|
|
15
|
+
temporary: 'Temporary; discarded when closed or reloaded',
|
|
16
|
+
referenceOnly: 'Read-only parent context; no Session copy',
|
|
17
|
+
cannotReopen: 'Add to conversation to keep this discussion',
|
|
18
|
+
readOnly: 'No tools or file changes',
|
|
19
19
|
retry: 'Retry',
|
|
20
20
|
genericError: 'Side Chat error',
|
|
21
21
|
closeError: 'Could not close the Side Chat',
|
|
@@ -33,13 +33,12 @@ export const SIDE_CHAT_MESSAGES = Object.freeze({
|
|
|
33
33
|
removeSelection: '移除引用',
|
|
34
34
|
expand: '展开',
|
|
35
35
|
collapse: '收起',
|
|
36
|
-
temporary: '
|
|
37
|
-
referenceOnly: '
|
|
38
|
-
cannotReopen: '
|
|
39
|
-
|
|
36
|
+
temporary: '临时对话;关闭或刷新后丢弃',
|
|
37
|
+
referenceOnly: '只读父会话上下文;不复制 Session',
|
|
38
|
+
cannotReopen: '添加到主对话以保留讨论内容',
|
|
39
|
+
readOnly: '不使用工具,不修改文件',
|
|
40
40
|
retry: '重试',
|
|
41
41
|
genericError: '侧边对话错误',
|
|
42
42
|
closeError: '无法关闭侧边对话',
|
|
43
43
|
}),
|
|
44
44
|
});
|
|
45
|
-
//# sourceMappingURL=messages.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ElementType, type ReactNode } from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { DshClientContext } from '../dsh/context.js';
|
|
3
|
+
import { SessionId } from '../../shared/contracts.js';
|
|
3
4
|
import { SIDE_CHAT_MESSAGES } from '../panel/messages.js';
|
|
4
5
|
import { type ParentComposerInputSnapshot } from './add-to-conversation.js';
|
|
5
6
|
type Locale = keyof typeof SIDE_CHAT_MESSAGES;
|
|
@@ -24,6 +25,5 @@ export declare function ParentComposerAnnotations({ input, onRemove, locale, }:
|
|
|
24
25
|
/** Wrap DSH's own user renderer only when this plugin's durable prefix exists. */
|
|
25
26
|
export declare function annotatedUserMessageRenderer(Original: UserNodeRenderer): (props: UserNodeProps) => ReactNode;
|
|
26
27
|
/** Mount the composer capsule and a thin wrapper around DSH's user renderers. */
|
|
27
|
-
export declare function mountParentConversationAnnotations(ctx:
|
|
28
|
+
export declare function mountParentConversationAnnotations(ctx: DshClientContext, removeAnnotations: (sessionId: SessionId) => void): () => void;
|
|
28
29
|
export {};
|
|
29
|
-
//# sourceMappingURL=ParentConversationAnnotations.d.ts.map
|
|
@@ -1,18 +1,68 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { createElement } from 'react';
|
|
2
|
+
import { createElement, useLayoutEffect, useRef } from 'react';
|
|
3
|
+
import { SessionId } from '../../shared/contracts.js';
|
|
3
4
|
import { SIDE_CHAT_MESSAGES } from '../panel/messages.js';
|
|
4
5
|
import { SelectionQuote } from '../panel/SelectionQuote.js';
|
|
5
|
-
import { conversationAnnotations, parseAnnotatedConversationPrompt, } from './add-to-conversation.js';
|
|
6
|
+
import { annotationMessageText, conversationAnnotations, parseAnnotatedConversationPrompt, } from './add-to-conversation.js';
|
|
6
7
|
import { parseReferencedConversationPrompt, } from './referenced-conversation.js';
|
|
7
8
|
function currentLocale() {
|
|
8
9
|
return navigator.language.toLowerCase().startsWith('zh') ? 'zh-CN' : 'en';
|
|
9
10
|
}
|
|
11
|
+
const ANNOTATION_CHIP_WIDTH_PROPERTY = '--dsh-side-chat-parent-annotation-width';
|
|
10
12
|
/** The interactive annotation capsule occupying the reserved first composer row. */
|
|
11
13
|
export function ParentComposerAnnotations({ input, onRemove, locale = currentLocale(), }) {
|
|
12
14
|
const annotations = conversationAnnotations(input);
|
|
15
|
+
const dockRef = useRef(null);
|
|
16
|
+
useLayoutEffect(() => {
|
|
17
|
+
const dock = dockRef.current;
|
|
18
|
+
const seat = dock?.closest('[data-composer-seat]');
|
|
19
|
+
const chip = dock?.querySelector('.dsh-side-chat-quote-chip');
|
|
20
|
+
if (dock === null || seat === undefined || chip === undefined || seat === null || chip === null)
|
|
21
|
+
return;
|
|
22
|
+
// The durable host reference stays in Lexical's document flow. Match its
|
|
23
|
+
// occupied width to this visible overlay so the caret starts at the edge
|
|
24
|
+
// users see instead of after the longer internal serialization label.
|
|
25
|
+
const syncPosition = () => {
|
|
26
|
+
const width = chip.getBoundingClientRect().width;
|
|
27
|
+
if (width > 0)
|
|
28
|
+
seat.style.setProperty(ANNOTATION_CHIP_WIDTH_PROPERTY, `${String(width)}px`);
|
|
29
|
+
const reference = seat.querySelector('[data-composer-chip="dsh-side-chat-selection"]');
|
|
30
|
+
if (reference === null)
|
|
31
|
+
return;
|
|
32
|
+
const referenceRect = reference.getBoundingClientRect();
|
|
33
|
+
const dockRect = dock.getBoundingClientRect();
|
|
34
|
+
if (Number.isFinite(referenceRect.left) && Number.isFinite(dockRect.left)) {
|
|
35
|
+
dock.style.setProperty('--annotation-left', `${referenceRect.left - dockRect.left}px`);
|
|
36
|
+
dock.style.setProperty('--annotation-top', `${referenceRect.top - dockRect.top}px`);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
let frame;
|
|
40
|
+
const schedule = () => {
|
|
41
|
+
if (frame !== undefined)
|
|
42
|
+
return;
|
|
43
|
+
frame = window.requestAnimationFrame(() => { frame = undefined; syncPosition(); });
|
|
44
|
+
};
|
|
45
|
+
syncPosition();
|
|
46
|
+
const observer = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(schedule);
|
|
47
|
+
observer?.observe(chip);
|
|
48
|
+
observer?.observe(seat);
|
|
49
|
+
const mutations = new MutationObserver(schedule);
|
|
50
|
+
mutations.observe(seat, { childList: true, characterData: true, subtree: true });
|
|
51
|
+
seat.addEventListener('scroll', schedule, true);
|
|
52
|
+
window.addEventListener('resize', schedule);
|
|
53
|
+
return () => {
|
|
54
|
+
if (frame !== undefined)
|
|
55
|
+
window.cancelAnimationFrame(frame);
|
|
56
|
+
observer?.disconnect();
|
|
57
|
+
mutations.disconnect();
|
|
58
|
+
seat.removeEventListener('scroll', schedule, true);
|
|
59
|
+
window.removeEventListener('resize', schedule);
|
|
60
|
+
seat.style.removeProperty(ANNOTATION_CHIP_WIDTH_PROPERTY);
|
|
61
|
+
};
|
|
62
|
+
}, [input, locale]);
|
|
13
63
|
if (annotations.length === 0)
|
|
14
64
|
return null;
|
|
15
|
-
return (_jsx("div", { className: "dsh-side-chat-parent-annotation-dock", children: _jsx(SelectionQuote, { selections: annotations, messages: SIDE_CHAT_MESSAGES[locale], onRemove: onRemove }) }));
|
|
65
|
+
return (_jsx("div", { ref: dockRef, className: "dsh-side-chat-parent-annotation-dock", children: _jsx(SelectionQuote, { selections: annotations, messages: SIDE_CHAT_MESSAGES[locale], onRemove: onRemove }) }));
|
|
16
66
|
}
|
|
17
67
|
function contentText(content) {
|
|
18
68
|
return content.map((block) => {
|
|
@@ -22,10 +72,6 @@ function contentText(content) {
|
|
|
22
72
|
return value.type === 'text' && typeof value.text === 'string' ? value.text : '';
|
|
23
73
|
}).join('');
|
|
24
74
|
}
|
|
25
|
-
function visibleMessage(message) {
|
|
26
|
-
const wrapped = /^<user_question>\n?([\s\S]*?)\n?<\/user_question>$/u.exec(message);
|
|
27
|
-
return wrapped?.[1]?.trim() ?? message;
|
|
28
|
-
}
|
|
29
75
|
function replaceTextContent(content, message) {
|
|
30
76
|
let replaced = false;
|
|
31
77
|
const next = content.flatMap((block) => {
|
|
@@ -44,29 +90,25 @@ function replaceTextContent(content, message) {
|
|
|
44
90
|
function parsePluginPrompt(text) {
|
|
45
91
|
let message = text;
|
|
46
92
|
let annotations;
|
|
47
|
-
|
|
48
|
-
|
|
93
|
+
const references = [];
|
|
94
|
+
while (message.length > 0) {
|
|
49
95
|
const annotated = annotations === undefined ? parseAnnotatedConversationPrompt(message) : undefined;
|
|
50
96
|
if (annotated !== undefined) {
|
|
51
97
|
annotations = annotated.annotations;
|
|
52
98
|
message = annotated.message;
|
|
53
99
|
continue;
|
|
54
100
|
}
|
|
55
|
-
const referenced =
|
|
101
|
+
const referenced = parseReferencedConversationPrompt(message);
|
|
56
102
|
if (referenced !== undefined) {
|
|
57
|
-
|
|
103
|
+
references.push(referenced.reference);
|
|
58
104
|
message = referenced.message;
|
|
59
105
|
continue;
|
|
60
106
|
}
|
|
61
107
|
break;
|
|
62
108
|
}
|
|
63
|
-
if (annotations === undefined &&
|
|
109
|
+
if (annotations === undefined && references.length === 0)
|
|
64
110
|
return;
|
|
65
|
-
return {
|
|
66
|
-
...(annotations === undefined ? {} : { annotations }),
|
|
67
|
-
...(reference === undefined ? {} : { reference }),
|
|
68
|
-
message,
|
|
69
|
-
};
|
|
111
|
+
return { ...(annotations === undefined ? {} : { annotations }), references, message };
|
|
70
112
|
}
|
|
71
113
|
/** Wrap DSH's own user renderer only when this plugin's durable prefix exists. */
|
|
72
114
|
export function annotatedUserMessageRenderer(Original) {
|
|
@@ -74,19 +116,16 @@ export function annotatedUserMessageRenderer(Original) {
|
|
|
74
116
|
const parsed = parsePluginPrompt(contentText(props.node.data.content));
|
|
75
117
|
if (parsed === undefined)
|
|
76
118
|
return createElement(Original, props);
|
|
77
|
-
const body =
|
|
78
|
-
const visible = parsed.reference
|
|
79
|
-
|
|
80
|
-
: [`@${parsed.reference.title}`, body].filter(part => part.length > 0).join('\n\n');
|
|
119
|
+
const body = parsed.annotations === undefined ? parsed.message : annotationMessageText(parsed.message);
|
|
120
|
+
const visible = [...parsed.references.map(reference => `@${reference.title}`), body]
|
|
121
|
+
.filter(part => part.length > 0).join('\n\n');
|
|
81
122
|
const existingLabels = props.node.data.referenceLabels ?? [];
|
|
82
123
|
const node = {
|
|
83
124
|
...props.node,
|
|
84
125
|
data: {
|
|
85
126
|
...props.node.data,
|
|
86
127
|
content: replaceTextContent(props.node.data.content, visible),
|
|
87
|
-
...(parsed.reference
|
|
88
|
-
? {}
|
|
89
|
-
: { referenceLabels: [...new Set([parsed.reference.title, ...existingLabels])] }),
|
|
128
|
+
referenceLabels: [...new Set([...parsed.references.map(reference => reference.title), ...existingLabels])],
|
|
90
129
|
},
|
|
91
130
|
};
|
|
92
131
|
const original = createElement(Original, { ...props, node });
|
|
@@ -104,8 +143,10 @@ export function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
|
104
143
|
// This zero-height projection must follow Todo (0), Goal (10), and Queue
|
|
105
144
|
// (20), so its absolute child remains anchored to the input card below.
|
|
106
145
|
order: 30,
|
|
107
|
-
}, ({ input }) => (_jsx(ParentComposerAnnotations, { input: input, onRemove: removeAnnotations }))));
|
|
146
|
+
}, ({ input, session }) => (_jsx(ParentComposerAnnotations, { input: input, onRemove: () => removeAnnotations(SessionId(session.sessionId)) }))));
|
|
108
147
|
const shadow = (key) => slots.inject('conversation.chat.node', () => {
|
|
148
|
+
let cachedOriginal;
|
|
149
|
+
let CachedRenderer;
|
|
109
150
|
const ShadowedUserMessage = (props) => {
|
|
110
151
|
// Built-in keyed renderers can register after this declaration callback.
|
|
111
152
|
// Resolve the next-priority renderer at render time so load order does
|
|
@@ -117,8 +158,11 @@ export function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
|
117
158
|
?.component;
|
|
118
159
|
if (original === undefined)
|
|
119
160
|
return null;
|
|
120
|
-
|
|
121
|
-
|
|
161
|
+
if (original !== cachedOriginal || CachedRenderer === undefined) {
|
|
162
|
+
cachedOriginal = original;
|
|
163
|
+
CachedRenderer = annotatedUserMessageRenderer(cachedOriginal);
|
|
164
|
+
}
|
|
165
|
+
return createElement(CachedRenderer, props);
|
|
122
166
|
};
|
|
123
167
|
return slots.register({
|
|
124
168
|
name: 'conversation.chat.node',
|
|
@@ -135,4 +179,3 @@ export function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
|
135
179
|
removeDock();
|
|
136
180
|
};
|
|
137
181
|
}
|
|
138
|
-
//# sourceMappingURL=ParentConversationAnnotations.js.map
|
|
@@ -1,51 +1,36 @@
|
|
|
1
1
|
import type { ConversationSelection, SideChatPromptPart } from '../../shared/contracts.js';
|
|
2
2
|
import type { ParentComposerInput, ParentComposerInputSnapshot, SelectionReferenceSource } from './composer-reference.js';
|
|
3
3
|
export type { ParentComposerInput, ParentComposerInputSnapshot, ParentComposerOccurrence, ParentConversationService, SelectionReferenceSource, } from './composer-reference.js';
|
|
4
|
+
export declare const SELECTION_REFERENCE_SOURCE = "dsh-side-chat-selection";
|
|
4
5
|
export declare const SELECTION_REFERENCE_LABEL = "__dsh_side_chat_annotations__";
|
|
5
6
|
export interface ConversationAnnotation {
|
|
6
7
|
readonly text: string;
|
|
7
8
|
readonly comment?: string;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
-
/** Zero-based position in the aggregated composer annotation list. */
|
|
11
|
-
readonly annotationIndex: number;
|
|
10
|
+
interface StoredConversationAnnotation extends ConversationAnnotation {
|
|
12
11
|
readonly selection: ConversationSelection;
|
|
13
12
|
}
|
|
13
|
+
export interface ConversationSelectionAnnotation extends StoredConversationAnnotation {
|
|
14
|
+
readonly annotationIndex: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function unescapeXmlText(value: string): string;
|
|
14
17
|
export declare function decodeSelectionReference(ref: string): readonly ConversationAnnotation[];
|
|
15
|
-
/** Read all plugin annotations represented by the current DSH input occurrence. */
|
|
16
18
|
export declare function conversationAnnotations(snapshot: ParentComposerInputSnapshot): readonly ConversationAnnotation[];
|
|
17
|
-
/** Read annotations that retain an exact source-selection anchor. */
|
|
18
19
|
export declare function conversationSelectionAnnotations(snapshot: ParentComposerInputSnapshot): readonly ConversationSelectionAnnotation[];
|
|
19
|
-
/** Remove every unsent plugin annotation while preserving the user's draft. */
|
|
20
|
-
export declare function removeConversationAnnotations(input: ParentComposerInput): boolean;
|
|
21
|
-
/** Reference codec used by DSH's native composer chip and submit pipeline. */
|
|
22
|
-
export declare const selectionReferenceSource: SelectionReferenceSource;
|
|
23
|
-
/** Add one passage to the parent composer's aggregated annotation occurrence. */
|
|
24
20
|
export declare function addSelectionToConversation(input: ParentComposerInput, selection: ConversationSelection, comment?: string): boolean;
|
|
25
|
-
|
|
21
|
+
export declare function removeConversationAnnotations(input: ParentComposerInput): boolean;
|
|
26
22
|
export declare function removeConversationAnnotation(input: ParentComposerInput, annotationIndex: number): boolean;
|
|
27
|
-
/** Replace the optional comment on one unsent selected-passage annotation. */
|
|
28
23
|
export declare function updateConversationAnnotation(input: ParentComposerInput, annotationIndex: number, comment?: string): boolean;
|
|
29
|
-
export
|
|
30
|
-
readonly ref: string;
|
|
31
|
-
readonly displayDraft: string;
|
|
32
|
-
readonly mirrorDraft: string;
|
|
33
|
-
readonly baseDraft: string;
|
|
34
|
-
}
|
|
35
|
-
/** Describe both the display draft and DSH's persisted clipboard projection. */
|
|
36
|
-
export declare function conversationAnnotationRecoveryRecord(snapshot: ParentComposerInputSnapshot): ConversationAnnotationRecoveryRecord | undefined;
|
|
37
|
-
/** Return the valid aggregated reference currently occupying the leading draft slot. */
|
|
38
|
-
export declare function conversationAnnotationReference(snapshot: ParentComposerInputSnapshot): string | undefined;
|
|
39
|
-
/** Remove the plugin-owned prefix when rc.6 restored its draft without occurrences. */
|
|
40
|
-
export declare function removeOrphanedConversationAnnotationPlaceholder(input: ParentComposerInput): boolean;
|
|
41
|
-
/** Rehydrate a lost occurrence over either its display draft or exact mirror projection. */
|
|
42
|
-
export declare function restoreConversationAnnotationReference(input: ParentComposerInput, ref: string, expectedMirrorDraft?: string, expectedBaseDraft?: string): boolean;
|
|
24
|
+
export declare const selectionReferenceSource: SelectionReferenceSource;
|
|
43
25
|
export interface AnnotatedConversationPrompt {
|
|
44
26
|
readonly annotations: readonly ConversationAnnotation[];
|
|
45
27
|
readonly message: string;
|
|
46
28
|
}
|
|
47
|
-
/** Parse the durable model form back into the user-facing annotation capsule. */
|
|
48
29
|
export declare function parseAnnotatedConversationPrompt(text: string): AnnotatedConversationPrompt | undefined;
|
|
49
|
-
/**
|
|
30
|
+
/** The first prompt uses the same durable annotation format as the main composer. */
|
|
50
31
|
export declare function buildSideChatPrompt(selection: ConversationSelection | undefined, question: string): readonly SideChatPromptPart[];
|
|
51
|
-
|
|
32
|
+
/** Decode a question only after recognizing this plugin's annotation prefix. */
|
|
33
|
+
export declare function annotationMessageText(message: string): string;
|
|
34
|
+
/** One projection supplies both the annotation capsule and the visible question. */
|
|
35
|
+
export declare function parseSideChatPrompt(text: string): AnnotatedConversationPrompt | undefined;
|
|
36
|
+
export declare function sideChatQuestionText(text: string): string;
|