@ahggg/dsh-side-chat 0.7.2 → 0.7.3
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 +3 -3
- package/README.zh-CN.md +3 -3
- package/lib/client/apply.d.ts +0 -1
- package/lib/client/apply.js +0 -1
- package/lib/client/contracts.d.ts +0 -1
- package/lib/client/contracts.js +0 -1
- package/lib/client/index.d.ts +0 -1
- 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 +0 -1
- 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 +0 -1
- 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 +0 -1
- package/lib/client/panel/SideChatPanel.d.ts +0 -1
- package/lib/client/panel/SideChatPanel.js +0 -1
- package/lib/client/panel/StopIcon.d.ts +0 -1
- package/lib/client/panel/StopIcon.js +0 -1
- package/lib/client/panel/messages.d.ts +0 -1
- package/lib/client/panel/messages.js +0 -1
- 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 +0 -1
- package/lib/client/parent-composer/ParentConversationAnnotations.js +26 -3
- package/lib/client/parent-composer/add-to-conversation.d.ts +0 -1
- package/lib/client/parent-composer/add-to-conversation.js +99 -8
- package/lib/client/parent-composer/annotation-persistence.d.ts +0 -1
- package/lib/client/parent-composer/annotation-persistence.js +0 -1
- package/lib/client/parent-composer/composer-reference.d.ts +16 -7
- package/lib/client/parent-composer/composer-reference.js +34 -2
- package/lib/client/parent-composer/referenced-conversation.d.ts +1 -2
- package/lib/client/parent-composer/referenced-conversation.js +26 -8
- package/lib/client/rc6/ArchivedConversation.d.ts +2 -3
- package/lib/client/rc6/ArchivedConversation.js +6 -5
- package/lib/client/rc6/Rc6SideChatOverlay.d.ts +0 -1
- package/lib/client/rc6/Rc6SideChatOverlay.js +0 -1
- package/lib/client/rc6/SideChatTool.d.ts +1 -2
- package/lib/client/rc6/SideChatTool.js +18 -9
- package/lib/client/rc6/context.d.ts +9 -3
- package/lib/client/rc6/context.js +0 -1
- package/lib/client/rc6/primitive-labels.d.ts +7 -0
- package/lib/client/rc6/primitive-labels.js +60 -0
- package/lib/client/rc6/remote-adapter.d.ts +0 -1
- package/lib/client/rc6/remote-adapter.js +4 -3
- package/lib/client/rc6/runtime-compat.d.ts +120 -0
- package/lib/client/rc6/runtime-compat.js +187 -0
- package/lib/client/rc6/sessions-adapter.d.ts +7 -4
- package/lib/client/rc6/sessions-adapter.js +62 -45
- package/lib/client/selection/ConversationAnnotationMarkers.d.ts +0 -1
- package/lib/client/selection/ConversationAnnotationMarkers.js +0 -1
- package/lib/client/selection/SelectionActions.d.ts +0 -1
- package/lib/client/selection/SelectionActions.js +0 -1
- package/lib/client/selection/selection-controller.d.ts +0 -1
- package/lib/client/selection/selection-controller.js +0 -1
- 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 +0 -1
- package/lib/client/side-chat-controller.d.ts +0 -1
- package/lib/client/side-chat-controller.js +0 -1
- package/lib/client.js +1173 -8951
- package/lib/host/archived-fork-service.d.ts +0 -1
- package/lib/host/archived-fork-service.js +71 -26
- package/lib/host/index.d.ts +0 -1
- package/lib/host/index.js +0 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/remote.d.ts +0 -1
- package/lib/remote.js +0 -1
- package/lib/shared/archived-wire.d.ts +0 -1
- package/lib/shared/archived-wire.js +0 -1
- package/lib/shared/constants.d.ts +0 -1
- package/lib/shared/constants.js +0 -1
- package/lib/shared/contracts.d.ts +0 -1
- package/lib/shared/contracts.js +0 -1
- package/lib/shared/error-codes.d.ts +0 -1
- package/lib/shared/error-codes.js +0 -1
- package/lib/shared/observable.d.ts +0 -1
- package/lib/shared/observable.js +0 -1
- package/lib/typert.d.ts +0 -1
- package/lib/typert.js +64 -51
- package/package.json +60 -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.map +0 -1
- package/lib/client/rc6/ArchivedConversation.js.map +0 -1
- 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.map +0 -1
- 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.map +0 -1
- package/lib/client/rc6/remote-adapter.d.ts.map +0 -1
- package/lib/client/rc6/remote-adapter.js.map +0 -1
- package/lib/client/rc6/sessions-adapter.d.ts.map +0 -1
- 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.map +0 -1
- 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.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
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const EMPTY_NODES = [];
|
|
2
|
+
const EMPTY_TURN_ENDS = new Map();
|
|
3
|
+
const EMPTY_RUNNING_CALLS = [];
|
|
4
|
+
const EMPTY_PENDING = [];
|
|
5
|
+
const EMPTY_NODE_STORE = { get: () => undefined };
|
|
6
|
+
function isLegacySnapshot(snapshot) {
|
|
7
|
+
return typeof snapshot === 'object'
|
|
8
|
+
&& snapshot !== null
|
|
9
|
+
&& Array.isArray(snapshot.nodes)
|
|
10
|
+
&& Array.isArray(snapshot.pending);
|
|
11
|
+
}
|
|
12
|
+
function currentPending(source, sessionId) {
|
|
13
|
+
const pending = source?.get(sessionId);
|
|
14
|
+
if (typeof pending !== 'object' || pending === null)
|
|
15
|
+
return;
|
|
16
|
+
const candidate = pending;
|
|
17
|
+
if (candidate.kind === 'approval'
|
|
18
|
+
&& typeof candidate.key === 'string'
|
|
19
|
+
&& typeof candidate.toolName === 'string'
|
|
20
|
+
&& typeof candidate.answer === 'function') {
|
|
21
|
+
return pending;
|
|
22
|
+
}
|
|
23
|
+
if ((candidate.kind === 'question' || candidate.kind === 'plan-review')
|
|
24
|
+
&& typeof candidate.key === 'string'
|
|
25
|
+
&& Array.isArray(candidate.questions)
|
|
26
|
+
&& typeof candidate.answer === 'function'
|
|
27
|
+
&& typeof candidate.cancel === 'function') {
|
|
28
|
+
return pending;
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
function normalizeLegacyPending(wait) {
|
|
33
|
+
if (wait.kind === 'approval') {
|
|
34
|
+
return {
|
|
35
|
+
kind: 'approval',
|
|
36
|
+
key: wait.key,
|
|
37
|
+
toolName: wait.payload.toolName,
|
|
38
|
+
...(wait.payload.reason === undefined ? {} : { reason: wait.payload.reason }),
|
|
39
|
+
respond: async (decision) => {
|
|
40
|
+
const receipt = await wait.respond({
|
|
41
|
+
ok: true,
|
|
42
|
+
value: {
|
|
43
|
+
sessionId: wait.sessionId,
|
|
44
|
+
approvalId: wait.payload.approvalId,
|
|
45
|
+
outcome: decision === 'approve' ? 'allowed-once' : 'rejected',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
return receipt.accepted;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
kind: 'question',
|
|
54
|
+
key: wait.key,
|
|
55
|
+
questions: wait.payload.questions,
|
|
56
|
+
respond: async (answer) => {
|
|
57
|
+
const receipt = await wait.respond(answer === null
|
|
58
|
+
? {
|
|
59
|
+
ok: false,
|
|
60
|
+
error: { code: 'cancelled', message: 'Question cancelled.', details: {} },
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
ok: true,
|
|
64
|
+
value: { sessionId: wait.sessionId, answer },
|
|
65
|
+
});
|
|
66
|
+
return receipt.accepted;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function normalizeCurrentPending(wait) {
|
|
71
|
+
if (wait.kind === 'approval') {
|
|
72
|
+
return {
|
|
73
|
+
kind: 'approval',
|
|
74
|
+
key: wait.key,
|
|
75
|
+
toolName: wait.toolName,
|
|
76
|
+
...(wait.reason === undefined ? {} : { reason: wait.reason }),
|
|
77
|
+
respond: async (decision) => {
|
|
78
|
+
await wait.answer(decision === 'approve' ? 'allowed-once' : 'rejected');
|
|
79
|
+
return true;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
kind: 'question',
|
|
85
|
+
key: wait.key,
|
|
86
|
+
questions: wait.questions,
|
|
87
|
+
respond: async (answer) => {
|
|
88
|
+
if (answer === null)
|
|
89
|
+
await wait.cancel();
|
|
90
|
+
else
|
|
91
|
+
await wait.answer(answer);
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Bridge DSH <=0.1.1's combined Session snapshot and 0.1.2's split stores. */
|
|
97
|
+
export class CompatibleConversationFace {
|
|
98
|
+
session;
|
|
99
|
+
chat;
|
|
100
|
+
pending;
|
|
101
|
+
sessionId;
|
|
102
|
+
cache;
|
|
103
|
+
constructor(session, chat, pending) {
|
|
104
|
+
this.session = session;
|
|
105
|
+
this.chat = chat;
|
|
106
|
+
this.pending = pending;
|
|
107
|
+
this.sessionId = session.sessionId;
|
|
108
|
+
}
|
|
109
|
+
subscribe = (listener) => {
|
|
110
|
+
const removers = [this.session.subscribe(listener)];
|
|
111
|
+
if (this.chat !== undefined)
|
|
112
|
+
removers.push(this.chat.subscribe(listener));
|
|
113
|
+
if (this.pending !== undefined)
|
|
114
|
+
removers.push(this.pending.subscribe(listener));
|
|
115
|
+
return () => {
|
|
116
|
+
for (const remove of removers)
|
|
117
|
+
remove();
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
getSnapshot = () => {
|
|
121
|
+
const session = this.session.getSnapshot();
|
|
122
|
+
if (isLegacySnapshot(session)) {
|
|
123
|
+
if (this.cache?.session === session)
|
|
124
|
+
return this.cache.value;
|
|
125
|
+
const value = {
|
|
126
|
+
nodes: session.nodes,
|
|
127
|
+
turnEnds: session.turnEnds,
|
|
128
|
+
partial: session.partial,
|
|
129
|
+
runningCalls: session.runningCalls,
|
|
130
|
+
pending: session.pending.map(normalizeLegacyPending),
|
|
131
|
+
queue: session.queue,
|
|
132
|
+
running: session.running,
|
|
133
|
+
openState: session.openState,
|
|
134
|
+
promptError: session.promptError,
|
|
135
|
+
lastAgentError: session.lastAgentError,
|
|
136
|
+
chatNodes: session.chat.nodes,
|
|
137
|
+
};
|
|
138
|
+
this.cache = { session, chat: undefined, pending: undefined, value };
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
const lifecycle = session;
|
|
142
|
+
const chat = this.chat?.getSnapshot();
|
|
143
|
+
const pending = this.pending?.getSnapshot();
|
|
144
|
+
const cached = this.cache;
|
|
145
|
+
if (cached !== undefined
|
|
146
|
+
&& cached.session === session
|
|
147
|
+
&& cached.chat === chat
|
|
148
|
+
&& cached.pending === pending) {
|
|
149
|
+
return cached.value;
|
|
150
|
+
}
|
|
151
|
+
const legacy = chat?.legacy;
|
|
152
|
+
const wait = currentPending(pending, this.sessionId);
|
|
153
|
+
const value = {
|
|
154
|
+
nodes: legacy?.nodes ?? EMPTY_NODES,
|
|
155
|
+
turnEnds: legacy?.turnEnds ?? EMPTY_TURN_ENDS,
|
|
156
|
+
partial: legacy?.partial ?? null,
|
|
157
|
+
runningCalls: legacy?.runningCalls ?? EMPTY_RUNNING_CALLS,
|
|
158
|
+
pending: wait === undefined ? EMPTY_PENDING : [normalizeCurrentPending(wait)],
|
|
159
|
+
queue: lifecycle.queue,
|
|
160
|
+
running: lifecycle.running,
|
|
161
|
+
openState: lifecycle.openState,
|
|
162
|
+
promptError: lifecycle.promptError,
|
|
163
|
+
lastAgentError: lifecycle.lastAgentError,
|
|
164
|
+
chatNodes: chat?.nodes ?? EMPTY_NODE_STORE,
|
|
165
|
+
};
|
|
166
|
+
this.cache = { session, chat, pending, value };
|
|
167
|
+
return value;
|
|
168
|
+
};
|
|
169
|
+
prompt(content, mode) {
|
|
170
|
+
return this.session.prompt(content, mode);
|
|
171
|
+
}
|
|
172
|
+
updateQueue(itemId, action) {
|
|
173
|
+
return this.session.updateQueue(itemId, action);
|
|
174
|
+
}
|
|
175
|
+
cancel() {
|
|
176
|
+
return this.session.cancel();
|
|
177
|
+
}
|
|
178
|
+
rename(title) {
|
|
179
|
+
return this.session.rename(title);
|
|
180
|
+
}
|
|
181
|
+
async open() {
|
|
182
|
+
await this.session.open?.call(this.session);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export function compatibleConversationFace(session, sources = {}) {
|
|
186
|
+
return new CompatibleConversationFace(session, sources.chat, sources.pending);
|
|
187
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import type { ConversationSnapshot, SessionFace } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
1
|
import type { ModelDirectory } from '@deepseek-ai/dsh-client-ui-model-selection/client';
|
|
3
2
|
import type { SideChatClientSessions, SideChatSessionLease } from '../contracts.js';
|
|
4
3
|
import type { ConversationSelection, SessionId, SideChatModelSelection } from '../../shared/contracts.js';
|
|
5
4
|
import type { ParentComposerInputSnapshot } from '../parent-composer/add-to-conversation.js';
|
|
6
5
|
import { type ReferencedSideChatConversation } from '../parent-composer/referenced-conversation.js';
|
|
7
6
|
import type { Rc6ClientContext } from './context.js';
|
|
7
|
+
import { type SideChatConversationFace, type SideChatConversationSnapshot } from './runtime-compat.js';
|
|
8
8
|
/** Adapter over rc.6's public SessionRuntime and exported concrete Session type. */
|
|
9
9
|
export declare class Rc6SideChatSessions implements SideChatClientSessions {
|
|
10
10
|
private readonly ctx;
|
|
11
11
|
private readonly renamed;
|
|
12
|
+
private readonly faces;
|
|
13
|
+
private readonly parentInputs;
|
|
12
14
|
private readonly annotationPersistence;
|
|
13
15
|
private readonly modelPreferences;
|
|
14
16
|
constructor(ctx: Rc6ClientContext);
|
|
@@ -40,16 +42,18 @@ export declare class Rc6SideChatSessions implements SideChatClientSessions {
|
|
|
40
42
|
readonly kind: 'status' | 'warning';
|
|
41
43
|
readonly text: string;
|
|
42
44
|
}): void;
|
|
43
|
-
face(sessionId: SessionId):
|
|
45
|
+
face(sessionId: SessionId): SideChatConversationFace | undefined;
|
|
44
46
|
title(sessionId: SessionId): string | undefined;
|
|
45
47
|
cwd(sessionId: SessionId): string | undefined;
|
|
46
48
|
modelDirectory(sessionId: SessionId): ModelDirectory | undefined;
|
|
47
49
|
sideChatModelPreference(): SideChatModelSelection | undefined;
|
|
48
50
|
rememberSideChatModelPreference(selection: SideChatModelSelection): void;
|
|
51
|
+
private adaptedFace;
|
|
49
52
|
private currentParentInput;
|
|
53
|
+
private parentInput;
|
|
50
54
|
private waitForBinding;
|
|
51
55
|
}
|
|
52
|
-
export declare function selectionDescriptor(snapshot:
|
|
56
|
+
export declare function selectionDescriptor(snapshot: SideChatConversationSnapshot, anchorKey: string): {
|
|
53
57
|
readonly nodeKey: string;
|
|
54
58
|
readonly nodeKind: string;
|
|
55
59
|
readonly turnKey: string;
|
|
@@ -58,4 +62,3 @@ export declare function selectionDescriptor(snapshot: ConversationSnapshot, anch
|
|
|
58
62
|
readonly modelVisible: boolean;
|
|
59
63
|
readonly settled: boolean;
|
|
60
64
|
} | undefined;
|
|
61
|
-
//# sourceMappingURL=sessions-adapter.d.ts.map
|
|
@@ -3,12 +3,15 @@ import { addSelectionToConversation as addSelectionToParentComposer, conversatio
|
|
|
3
3
|
import { ConversationAnnotationPersistence } from '../parent-composer/annotation-persistence.js';
|
|
4
4
|
import { addReferencedSideChatToConversation as addReferencedSideChatToParentComposer, } from '../parent-composer/referenced-conversation.js';
|
|
5
5
|
import { SideChatModelPreferences } from '../model-preference.js';
|
|
6
|
+
import { compatibleConversationFace, } from './runtime-compat.js';
|
|
6
7
|
const BINDING_WAIT_MS = 8_000;
|
|
7
8
|
function sideChatError(error, fallback) {
|
|
9
|
+
const badRequest = error.code === 'bad-request' || error.code === 'gateway/bad-request';
|
|
10
|
+
const missing = error.code === 'session-not-found' || error.code === 'session/not-found';
|
|
8
11
|
return {
|
|
9
|
-
code:
|
|
12
|
+
code: missing ? 'side_chat_not_found' : fallback,
|
|
10
13
|
message: error.message,
|
|
11
|
-
recoverable:
|
|
14
|
+
recoverable: !badRequest,
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
function operationError(code, message) {
|
|
@@ -83,21 +86,12 @@ class Rc6SessionBinding {
|
|
|
83
86
|
: { ok: false, error: sideChatError(result.error, 'side_chat_interrupt_failed') };
|
|
84
87
|
}
|
|
85
88
|
async respondApproval(interactionId, decision) {
|
|
86
|
-
const wait = this.face.getSnapshot().pending
|
|
87
|
-
.find(item => item.key === interactionId && item.kind === 'approval');
|
|
89
|
+
const wait = this.face.getSnapshot().pending.find((item) => item.key === interactionId && item.kind === 'approval');
|
|
88
90
|
if (wait === undefined) {
|
|
89
91
|
return { ok: false, error: operationError('invalid_request', 'The approval is no longer pending.') };
|
|
90
92
|
}
|
|
91
93
|
try {
|
|
92
|
-
|
|
93
|
-
ok: true,
|
|
94
|
-
value: {
|
|
95
|
-
sessionId: wait.sessionId,
|
|
96
|
-
approvalId: wait.payload.approvalId,
|
|
97
|
-
outcome: decision === 'approve' ? 'allowed-once' : 'rejected',
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
return receipt.accepted
|
|
94
|
+
return await wait.respond(decision)
|
|
101
95
|
? { ok: true }
|
|
102
96
|
: { ok: false, error: operationError('transport_error', 'The approval response arrived too late.') };
|
|
103
97
|
}
|
|
@@ -106,32 +100,21 @@ class Rc6SessionBinding {
|
|
|
106
100
|
}
|
|
107
101
|
}
|
|
108
102
|
async respondQuestion(interactionId, answer) {
|
|
109
|
-
const wait = this.face.getSnapshot().pending
|
|
110
|
-
.find(item => item.key === interactionId && item.kind === 'question');
|
|
103
|
+
const wait = this.face.getSnapshot().pending.find((item) => item.key === interactionId && item.kind === 'question');
|
|
111
104
|
if (wait === undefined) {
|
|
112
105
|
return { ok: false, error: operationError('invalid_request', 'The question is no longer pending.') };
|
|
113
106
|
}
|
|
114
107
|
try {
|
|
115
|
-
const
|
|
116
|
-
?
|
|
117
|
-
ok: false,
|
|
118
|
-
error: { code: 'cancelled', message: 'Question cancelled.', details: {} },
|
|
119
|
-
}
|
|
108
|
+
const normalized = answer === null
|
|
109
|
+
? null
|
|
120
110
|
: {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
id: item.id,
|
|
127
|
-
selected: [...item.selected],
|
|
128
|
-
...(item.custom === undefined ? {} : { custom: item.custom }),
|
|
129
|
-
})),
|
|
130
|
-
},
|
|
131
|
-
},
|
|
111
|
+
answers: answer.answers.map(item => ({
|
|
112
|
+
id: item.id,
|
|
113
|
+
selected: [...item.selected],
|
|
114
|
+
...(item.custom === undefined ? {} : { custom: item.custom }),
|
|
115
|
+
})),
|
|
132
116
|
};
|
|
133
|
-
|
|
134
|
-
return receipt.accepted
|
|
117
|
+
return await wait.respond(normalized)
|
|
135
118
|
? { ok: true }
|
|
136
119
|
: { ok: false, error: operationError('transport_error', 'The question response arrived too late.') };
|
|
137
120
|
}
|
|
@@ -144,6 +127,8 @@ class Rc6SessionBinding {
|
|
|
144
127
|
export class Rc6SideChatSessions {
|
|
145
128
|
ctx;
|
|
146
129
|
renamed = new Set();
|
|
130
|
+
faces = new Map();
|
|
131
|
+
parentInputs = new WeakMap();
|
|
147
132
|
annotationPersistence = new ConversationAnnotationPersistence();
|
|
148
133
|
modelPreferences = new SideChatModelPreferences();
|
|
149
134
|
constructor(ctx) {
|
|
@@ -179,17 +164,17 @@ export class Rc6SideChatSessions {
|
|
|
179
164
|
return current === undefined ? undefined : sideChatSessionId(current);
|
|
180
165
|
}
|
|
181
166
|
lastCompletedSeq(parentSessionId) {
|
|
182
|
-
const snapshot = this.
|
|
167
|
+
const snapshot = this.face(parentSessionId)?.getSnapshot();
|
|
183
168
|
return snapshot === undefined ? undefined : latestCompleted(snapshot);
|
|
184
169
|
}
|
|
185
170
|
selectionIsCurrent(selection) {
|
|
186
171
|
if (this.currentSessionId() !== selection.parentSessionId)
|
|
187
172
|
return false;
|
|
188
|
-
const snapshot = this.
|
|
173
|
+
const snapshot = this.face(selection.parentSessionId)?.getSnapshot();
|
|
189
174
|
if (snapshot === undefined)
|
|
190
175
|
return false;
|
|
191
176
|
return selection.fragments.every((fragment) => {
|
|
192
|
-
const node = snapshot.
|
|
177
|
+
const node = snapshot.chatNodes.get(fragment.nodeKey);
|
|
193
178
|
return node !== undefined
|
|
194
179
|
&& node.visibility === 'visible'
|
|
195
180
|
&& node.kind === fragment.nodeKind
|
|
@@ -210,7 +195,7 @@ export class Rc6SideChatSessions {
|
|
|
210
195
|
/** Add one immutable Side Chat transcript to its parent Session's composer. */
|
|
211
196
|
addSideChatToConversation(parentSessionId, reference) {
|
|
212
197
|
const scope = this.ctx.sessions.scope(dshSessionId(parentSessionId));
|
|
213
|
-
const input = scope === undefined ? undefined : this.
|
|
198
|
+
const input = scope === undefined ? undefined : this.parentInput(scope);
|
|
214
199
|
if (input === undefined || !addReferencedSideChatToParentComposer(input, reference))
|
|
215
200
|
return false;
|
|
216
201
|
this.annotationPersistence.reconcile(parentSessionId, input);
|
|
@@ -264,15 +249,15 @@ export class Rc6SideChatSessions {
|
|
|
264
249
|
}
|
|
265
250
|
async retain(sessionId) {
|
|
266
251
|
const binding = await this.waitForBinding(dshSessionId(sessionId));
|
|
267
|
-
const
|
|
268
|
-
await
|
|
252
|
+
const face = this.adaptedFace(binding.session);
|
|
253
|
+
await face.open();
|
|
269
254
|
if (!this.renamed.has(sessionId)) {
|
|
270
255
|
this.renamed.add(sessionId);
|
|
271
256
|
const parentTitle = this.ctx.sessions.list.getSnapshot().byId[dshSessionId(sessionId)]?.displayTitle;
|
|
272
257
|
const title = parentTitle === undefined ? 'Side Chat' : `Side Chat · ${parentTitle}`;
|
|
273
|
-
await
|
|
258
|
+
await face.rename(title.slice(0, 160)).catch(() => undefined);
|
|
274
259
|
}
|
|
275
|
-
const adapted = new Rc6SessionBinding(
|
|
260
|
+
const adapted = new Rc6SessionBinding(face);
|
|
276
261
|
return { sessionId, binding: adapted, release: () => { } };
|
|
277
262
|
}
|
|
278
263
|
async openSession(sessionId) {
|
|
@@ -283,7 +268,8 @@ export class Rc6SideChatSessions {
|
|
|
283
268
|
console[method](`[dsh-side-chat] ${message.text}`);
|
|
284
269
|
}
|
|
285
270
|
face(sessionId) {
|
|
286
|
-
|
|
271
|
+
const source = this.ctx.sessions.binding(dshSessionId(sessionId))?.session;
|
|
272
|
+
return source === undefined ? undefined : this.adaptedFace(source);
|
|
287
273
|
}
|
|
288
274
|
title(sessionId) {
|
|
289
275
|
return this.ctx.sessions.list.getSnapshot().byId[dshSessionId(sessionId)]?.displayTitle;
|
|
@@ -305,12 +291,44 @@ export class Rc6SideChatSessions {
|
|
|
305
291
|
rememberSideChatModelPreference(selection) {
|
|
306
292
|
this.modelPreferences.set(selection);
|
|
307
293
|
}
|
|
294
|
+
adaptedFace(source) {
|
|
295
|
+
const existing = this.faces.get(source.sessionId);
|
|
296
|
+
if (existing?.source === source)
|
|
297
|
+
return existing.compatible;
|
|
298
|
+
const uiConversation = this.ctx.get('uiConversation');
|
|
299
|
+
const uiSession = this.ctx.get('uiSession');
|
|
300
|
+
const chat = uiConversation?.binding(source.sessionId).target('chat');
|
|
301
|
+
const pending = uiSession?.pendingInteractions;
|
|
302
|
+
const compatible = compatibleConversationFace(source, {
|
|
303
|
+
...(chat === undefined ? {} : { chat }),
|
|
304
|
+
...(pending === undefined ? {} : { pending }),
|
|
305
|
+
});
|
|
306
|
+
this.faces.set(source.sessionId, { source, compatible });
|
|
307
|
+
return compatible;
|
|
308
|
+
}
|
|
308
309
|
currentParentInput() {
|
|
309
310
|
const sessionId = this.currentSessionId();
|
|
310
311
|
if (sessionId === undefined)
|
|
311
312
|
return;
|
|
312
313
|
const scope = this.ctx.sessions.scope(dshSessionId(sessionId));
|
|
313
|
-
return scope === undefined ? undefined : this.
|
|
314
|
+
return scope === undefined ? undefined : this.parentInput(scope);
|
|
315
|
+
}
|
|
316
|
+
parentInput(scope) {
|
|
317
|
+
const source = this.ctx.conversation.input.for(scope);
|
|
318
|
+
if (source === undefined || this.ctx.get('uiConversation') === undefined)
|
|
319
|
+
return source;
|
|
320
|
+
const existing = this.parentInputs.get(source);
|
|
321
|
+
if (existing !== undefined)
|
|
322
|
+
return existing;
|
|
323
|
+
const adapted = {
|
|
324
|
+
referenceMode: 'lexical',
|
|
325
|
+
state: source.state,
|
|
326
|
+
setDraft: text => { source.setDraft(text); },
|
|
327
|
+
insertReference: (reference, span) => source.insertReference(reference, span),
|
|
328
|
+
replaceText: (text, span) => scope.bail(scope, 'slash/input-insert-text', { text, span }) === true,
|
|
329
|
+
};
|
|
330
|
+
this.parentInputs.set(source, adapted);
|
|
331
|
+
return adapted;
|
|
314
332
|
}
|
|
315
333
|
waitForBinding(sessionId) {
|
|
316
334
|
const immediate = this.ctx.sessions.binding(sessionId);
|
|
@@ -342,7 +360,7 @@ export class Rc6SideChatSessions {
|
|
|
342
360
|
}
|
|
343
361
|
}
|
|
344
362
|
export function selectionDescriptor(snapshot, anchorKey) {
|
|
345
|
-
const node = snapshot.
|
|
363
|
+
const node = snapshot.chatNodes.get(anchorKey);
|
|
346
364
|
if (node === undefined || node.visibility !== 'visible')
|
|
347
365
|
return undefined;
|
|
348
366
|
const source = node.kind === 'user' || node.kind === 'steering'
|
|
@@ -367,4 +385,3 @@ export function selectionDescriptor(snapshot, anchorKey) {
|
|
|
367
385
|
settled: locationSettled(node.location),
|
|
368
386
|
};
|
|
369
387
|
}
|
|
370
|
-
//# sourceMappingURL=sessions-adapter.js.map
|
|
@@ -6,4 +6,3 @@ export declare function ConversationAnnotationMarkers({ annotations, activeAnnot
|
|
|
6
6
|
readonly activeAnnotationIndex?: number;
|
|
7
7
|
readonly onEdit: (annotation: ConversationSelectionAnnotation, selection: ConversationSelection) => void;
|
|
8
8
|
}): (import("react/jsx-runtime").JSX.Element | null)[];
|
|
9
|
-
//# sourceMappingURL=ConversationAnnotationMarkers.d.ts.map
|
|
@@ -238,4 +238,3 @@ export function ConversationAnnotationMarkers({ annotations, activeAnnotationInd
|
|
|
238
238
|
}, onClick: activate, children: badge }, `${annotation.selection.parentSessionId}:${annotation.selection.fragments[0]?.nodeKey ?? ''}:${String(annotation.annotationIndex)}`));
|
|
239
239
|
});
|
|
240
240
|
}
|
|
241
|
-
//# sourceMappingURL=ConversationAnnotationMarkers.js.map
|
|
@@ -30,4 +30,3 @@ export declare function calculateSelectionActionsPosition(rect: ConversationSele
|
|
|
30
30
|
readonly top: number;
|
|
31
31
|
};
|
|
32
32
|
export declare function SelectionActions({ selection, touchInteraction, askDisabledReason, annotationNumber, annotationEditor, onAddToChat, onMoreDetails, onAskInSideChat, onAnnotationEditorChange, onRemoveAnnotation, onDismiss, }: SelectionActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
-
//# sourceMappingURL=SelectionActions.d.ts.map
|
|
@@ -199,4 +199,3 @@ export function SelectionActions({ selection, touchInteraction = false, askDisab
|
|
|
199
199
|
onDismiss();
|
|
200
200
|
}, children: [_jsx("button", { type: "button", onPointerDown: (event) => { activateOnTouch(event, openAnnotationEditor); }, onClick: (event) => { activateOnClick(event, openAnnotationEditor); }, children: "Add to chat" }), _jsx("button", { type: "button", disabled: askDisabledReason !== undefined, title: askDisabledReason, onPointerDown: (event) => { activateOnTouch(event, showMoreDetails); }, onClick: (event) => { activateOnClick(event, showMoreDetails); }, children: "More details" }), _jsx("button", { type: "button", disabled: askDisabledReason !== undefined, title: askDisabledReason, onPointerDown: (event) => { activateOnTouch(event, askInSideChat); }, onClick: (event) => { activateOnClick(event, askInSideChat); }, children: "Ask in side chat" })] }));
|
|
201
201
|
}
|
|
202
|
-
//# sourceMappingURL=SelectionActions.js.map
|
|
@@ -4,4 +4,3 @@ export declare function utf8ByteLength(value: string): number;
|
|
|
4
4
|
export declare function selectionFitsLimit(value: string): boolean;
|
|
5
5
|
/** Code-point-safe preview that never cuts a surrogate pair. */
|
|
6
6
|
export declare function summarizeSelection(value: string, maxCodePoints?: number): string;
|
|
7
|
-
//# sourceMappingURL=selection-limits.d.ts.map
|
|
@@ -13,4 +13,3 @@ export interface ConversationSelectionInput {
|
|
|
13
13
|
}
|
|
14
14
|
export declare function finalizeConversationSelection(input: ConversationSelectionInput): ConversationSelection;
|
|
15
15
|
export declare function assertSelectionCurrent(selection: ConversationSelection, currentSessionId: SessionId | undefined): void;
|
|
16
|
-
//# sourceMappingURL=selection-normalizer.d.ts.map
|