@ahggg/dsh-side-chat 0.7.3 → 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 +15 -12
- package/README.zh-CN.md +15 -12
- package/lib/client/apply.js +48 -32
- package/lib/client/contracts.d.ts +3 -58
- 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 -56
- package/lib/client/{rc6 → dsh}/context.d.ts +4 -6
- 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 -2
- 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 -2
- package/lib/client/panel/SelectionQuote.js +8 -1
- package/lib/client/panel/SideChatErrorState.js +1 -1
- package/lib/client/panel/SideChatModelSelect.js +37 -18
- package/lib/client/panel/SideChatPanel.js +12 -5
- package/lib/client/panel/messages.d.ts +1 -1
- package/lib/client/panel/messages.js +8 -8
- package/lib/client/parent-composer/ParentConversationAnnotations.d.ts +3 -2
- package/lib/client/parent-composer/ParentConversationAnnotations.js +50 -30
- package/lib/client/parent-composer/add-to-conversation.d.ts +14 -28
- package/lib/client/parent-composer/add-to-conversation.js +131 -545
- package/lib/client/parent-composer/annotation-persistence.d.ts +8 -8
- package/lib/client/parent-composer/annotation-persistence.js +106 -102
- package/lib/client/parent-composer/composer-reference.d.ts +17 -55
- package/lib/client/parent-composer/composer-reference.js +20 -72
- package/lib/client/parent-composer/referenced-conversation.d.ts +5 -7
- package/lib/client/parent-composer/referenced-conversation.js +21 -73
- package/lib/client/selection/ConversationAnnotationMarkers.js +5 -1
- package/lib/client/selection/SelectionActions.js +2 -1
- 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 -1
- package/lib/client/selection/selection-controller.js +7 -3
- package/lib/client/selection/selection-normalizer.js +1 -1
- package/lib/client/side-chat-controller.d.ts +28 -41
- package/lib/client/side-chat-controller.js +245 -337
- package/lib/client.js +81 -52
- package/lib/host/index.d.ts +1 -1
- package/lib/host/index.js +1 -1
- 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 -8
- package/lib/index.js +34 -13
- package/lib/remote.d.ts +23 -14
- package/lib/remote.js +2 -5
- package/lib/shared/constants.d.ts +0 -13
- package/lib/shared/constants.js +0 -13
- package/lib/shared/contracts.d.ts +52 -19
- package/lib/shared/contracts.js +2 -3
- package/lib/shared/error-codes.d.ts +1 -1
- package/lib/shared/error-codes.js +2 -2
- package/lib/shared/{archived-wire.d.ts → side-chat-wire.d.ts} +109 -20
- package/lib/shared/side-chat-wire.js +34 -0
- package/lib/typert.d.ts +3 -68
- package/lib/typert.js +60 -4
- package/package.json +76 -56
- package/lib/client/rc6/ArchivedConversation.d.ts +0 -14
- package/lib/client/rc6/ArchivedConversation.js +0 -231
- package/lib/client/rc6/Rc6SideChatOverlay.d.ts +0 -7
- package/lib/client/rc6/SideChatTool.d.ts +0 -22
- package/lib/client/rc6/SideChatTool.js +0 -404
- package/lib/client/rc6/primitive-labels.d.ts +0 -7
- package/lib/client/rc6/primitive-labels.js +0 -60
- package/lib/client/rc6/remote-adapter.js +0 -34
- package/lib/client/rc6/runtime-compat.d.ts +0 -120
- package/lib/client/rc6/runtime-compat.js +0 -187
- package/lib/client/rc6/sessions-adapter.d.ts +0 -64
- package/lib/client/rc6/sessions-adapter.js +0 -387
- package/lib/host/archived-fork-service.d.ts +0 -28
- package/lib/host/archived-fork-service.js +0 -309
- package/lib/shared/archived-wire.js +0 -47
- /package/lib/client/{rc6 → dsh}/context.js +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
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';
|
|
@@ -16,24 +17,49 @@ export function ParentComposerAnnotations({ input, onRemove, locale = currentLoc
|
|
|
16
17
|
const dock = dockRef.current;
|
|
17
18
|
const seat = dock?.closest('[data-composer-seat]');
|
|
18
19
|
const chip = dock?.querySelector('.dsh-side-chat-quote-chip');
|
|
19
|
-
if (seat === undefined || chip === undefined || seat === null || chip === null)
|
|
20
|
+
if (dock === null || seat === undefined || chip === undefined || seat === null || chip === null)
|
|
20
21
|
return;
|
|
21
22
|
// The durable host reference stays in Lexical's document flow. Match its
|
|
22
23
|
// occupied width to this visible overlay so the caret starts at the edge
|
|
23
24
|
// users see instead of after the longer internal serialization label.
|
|
24
|
-
const
|
|
25
|
+
const syncPosition = () => {
|
|
25
26
|
const width = chip.getBoundingClientRect().width;
|
|
26
27
|
if (width > 0)
|
|
27
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
|
+
}
|
|
28
38
|
};
|
|
29
|
-
|
|
30
|
-
const
|
|
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);
|
|
31
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);
|
|
32
53
|
return () => {
|
|
54
|
+
if (frame !== undefined)
|
|
55
|
+
window.cancelAnimationFrame(frame);
|
|
33
56
|
observer?.disconnect();
|
|
57
|
+
mutations.disconnect();
|
|
58
|
+
seat.removeEventListener('scroll', schedule, true);
|
|
59
|
+
window.removeEventListener('resize', schedule);
|
|
34
60
|
seat.style.removeProperty(ANNOTATION_CHIP_WIDTH_PROPERTY);
|
|
35
61
|
};
|
|
36
|
-
}, [
|
|
62
|
+
}, [input, locale]);
|
|
37
63
|
if (annotations.length === 0)
|
|
38
64
|
return null;
|
|
39
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 }) }));
|
|
@@ -46,10 +72,6 @@ function contentText(content) {
|
|
|
46
72
|
return value.type === 'text' && typeof value.text === 'string' ? value.text : '';
|
|
47
73
|
}).join('');
|
|
48
74
|
}
|
|
49
|
-
function visibleMessage(message) {
|
|
50
|
-
const wrapped = /^<user_question>\n?([\s\S]*?)\n?<\/user_question>$/u.exec(message);
|
|
51
|
-
return wrapped?.[1]?.trim() ?? message;
|
|
52
|
-
}
|
|
53
75
|
function replaceTextContent(content, message) {
|
|
54
76
|
let replaced = false;
|
|
55
77
|
const next = content.flatMap((block) => {
|
|
@@ -68,29 +90,25 @@ function replaceTextContent(content, message) {
|
|
|
68
90
|
function parsePluginPrompt(text) {
|
|
69
91
|
let message = text;
|
|
70
92
|
let annotations;
|
|
71
|
-
|
|
72
|
-
|
|
93
|
+
const references = [];
|
|
94
|
+
while (message.length > 0) {
|
|
73
95
|
const annotated = annotations === undefined ? parseAnnotatedConversationPrompt(message) : undefined;
|
|
74
96
|
if (annotated !== undefined) {
|
|
75
97
|
annotations = annotated.annotations;
|
|
76
98
|
message = annotated.message;
|
|
77
99
|
continue;
|
|
78
100
|
}
|
|
79
|
-
const referenced =
|
|
101
|
+
const referenced = parseReferencedConversationPrompt(message);
|
|
80
102
|
if (referenced !== undefined) {
|
|
81
|
-
|
|
103
|
+
references.push(referenced.reference);
|
|
82
104
|
message = referenced.message;
|
|
83
105
|
continue;
|
|
84
106
|
}
|
|
85
107
|
break;
|
|
86
108
|
}
|
|
87
|
-
if (annotations === undefined &&
|
|
109
|
+
if (annotations === undefined && references.length === 0)
|
|
88
110
|
return;
|
|
89
|
-
return {
|
|
90
|
-
...(annotations === undefined ? {} : { annotations }),
|
|
91
|
-
...(reference === undefined ? {} : { reference }),
|
|
92
|
-
message,
|
|
93
|
-
};
|
|
111
|
+
return { ...(annotations === undefined ? {} : { annotations }), references, message };
|
|
94
112
|
}
|
|
95
113
|
/** Wrap DSH's own user renderer only when this plugin's durable prefix exists. */
|
|
96
114
|
export function annotatedUserMessageRenderer(Original) {
|
|
@@ -98,19 +116,16 @@ export function annotatedUserMessageRenderer(Original) {
|
|
|
98
116
|
const parsed = parsePluginPrompt(contentText(props.node.data.content));
|
|
99
117
|
if (parsed === undefined)
|
|
100
118
|
return createElement(Original, props);
|
|
101
|
-
const body =
|
|
102
|
-
const visible = parsed.reference
|
|
103
|
-
|
|
104
|
-
: [`@${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');
|
|
105
122
|
const existingLabels = props.node.data.referenceLabels ?? [];
|
|
106
123
|
const node = {
|
|
107
124
|
...props.node,
|
|
108
125
|
data: {
|
|
109
126
|
...props.node.data,
|
|
110
127
|
content: replaceTextContent(props.node.data.content, visible),
|
|
111
|
-
...(parsed.reference
|
|
112
|
-
? {}
|
|
113
|
-
: { referenceLabels: [...new Set([parsed.reference.title, ...existingLabels])] }),
|
|
128
|
+
referenceLabels: [...new Set([...parsed.references.map(reference => reference.title), ...existingLabels])],
|
|
114
129
|
},
|
|
115
130
|
};
|
|
116
131
|
const original = createElement(Original, { ...props, node });
|
|
@@ -128,8 +143,10 @@ export function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
|
128
143
|
// This zero-height projection must follow Todo (0), Goal (10), and Queue
|
|
129
144
|
// (20), so its absolute child remains anchored to the input card below.
|
|
130
145
|
order: 30,
|
|
131
|
-
}, ({ input }) => (_jsx(ParentComposerAnnotations, { input: input, onRemove: removeAnnotations }))));
|
|
146
|
+
}, ({ input, session }) => (_jsx(ParentComposerAnnotations, { input: input, onRemove: () => removeAnnotations(SessionId(session.sessionId)) }))));
|
|
132
147
|
const shadow = (key) => slots.inject('conversation.chat.node', () => {
|
|
148
|
+
let cachedOriginal;
|
|
149
|
+
let CachedRenderer;
|
|
133
150
|
const ShadowedUserMessage = (props) => {
|
|
134
151
|
// Built-in keyed renderers can register after this declaration callback.
|
|
135
152
|
// Resolve the next-priority renderer at render time so load order does
|
|
@@ -141,8 +158,11 @@ export function mountParentConversationAnnotations(ctx, removeAnnotations) {
|
|
|
141
158
|
?.component;
|
|
142
159
|
if (original === undefined)
|
|
143
160
|
return null;
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
if (original !== cachedOriginal || CachedRenderer === undefined) {
|
|
162
|
+
cachedOriginal = original;
|
|
163
|
+
CachedRenderer = annotatedUserMessageRenderer(cachedOriginal);
|
|
164
|
+
}
|
|
165
|
+
return createElement(CachedRenderer, props);
|
|
146
166
|
};
|
|
147
167
|
return slots.register({
|
|
148
168
|
name: 'conversation.chat.node',
|
|
@@ -1,50 +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[];
|
|
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;
|