@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.
Files changed (173) hide show
  1. package/README.md +3 -3
  2. package/README.zh-CN.md +3 -3
  3. package/lib/client/apply.d.ts +0 -1
  4. package/lib/client/apply.js +0 -1
  5. package/lib/client/contracts.d.ts +0 -1
  6. package/lib/client/contracts.js +0 -1
  7. package/lib/client/index.d.ts +0 -1
  8. package/lib/client/index.js +0 -1
  9. package/lib/client/model-preference.d.ts +0 -1
  10. package/lib/client/model-preference.js +0 -1
  11. package/lib/client/panel/SelectionQuote.d.ts +0 -1
  12. package/lib/client/panel/SelectionQuote.js +0 -1
  13. package/lib/client/panel/SendIcon.d.ts +0 -1
  14. package/lib/client/panel/SendIcon.js +0 -1
  15. package/lib/client/panel/SideChatBody.d.ts +0 -1
  16. package/lib/client/panel/SideChatBody.js +0 -1
  17. package/lib/client/panel/SideChatErrorState.d.ts +0 -1
  18. package/lib/client/panel/SideChatErrorState.js +0 -1
  19. package/lib/client/panel/SideChatHeader.d.ts +0 -1
  20. package/lib/client/panel/SideChatHeader.js +0 -1
  21. package/lib/client/panel/SideChatModelSelect.d.ts +0 -1
  22. package/lib/client/panel/SideChatModelSelect.js +0 -1
  23. package/lib/client/panel/SideChatPanel.d.ts +0 -1
  24. package/lib/client/panel/SideChatPanel.js +0 -1
  25. package/lib/client/panel/StopIcon.d.ts +0 -1
  26. package/lib/client/panel/StopIcon.js +0 -1
  27. package/lib/client/panel/messages.d.ts +0 -1
  28. package/lib/client/panel/messages.js +0 -1
  29. package/lib/client/panel/use-auto-growing-textarea.d.ts +0 -1
  30. package/lib/client/panel/use-auto-growing-textarea.js +0 -1
  31. package/lib/client/parent-composer/ParentConversationAnnotations.d.ts +0 -1
  32. package/lib/client/parent-composer/ParentConversationAnnotations.js +26 -3
  33. package/lib/client/parent-composer/add-to-conversation.d.ts +0 -1
  34. package/lib/client/parent-composer/add-to-conversation.js +99 -8
  35. package/lib/client/parent-composer/annotation-persistence.d.ts +0 -1
  36. package/lib/client/parent-composer/annotation-persistence.js +0 -1
  37. package/lib/client/parent-composer/composer-reference.d.ts +16 -7
  38. package/lib/client/parent-composer/composer-reference.js +34 -2
  39. package/lib/client/parent-composer/referenced-conversation.d.ts +1 -2
  40. package/lib/client/parent-composer/referenced-conversation.js +26 -8
  41. package/lib/client/rc6/ArchivedConversation.d.ts +2 -3
  42. package/lib/client/rc6/ArchivedConversation.js +6 -5
  43. package/lib/client/rc6/Rc6SideChatOverlay.d.ts +0 -1
  44. package/lib/client/rc6/Rc6SideChatOverlay.js +0 -1
  45. package/lib/client/rc6/SideChatTool.d.ts +1 -2
  46. package/lib/client/rc6/SideChatTool.js +18 -9
  47. package/lib/client/rc6/context.d.ts +9 -3
  48. package/lib/client/rc6/context.js +0 -1
  49. package/lib/client/rc6/primitive-labels.d.ts +7 -0
  50. package/lib/client/rc6/primitive-labels.js +60 -0
  51. package/lib/client/rc6/remote-adapter.d.ts +0 -1
  52. package/lib/client/rc6/remote-adapter.js +4 -3
  53. package/lib/client/rc6/runtime-compat.d.ts +120 -0
  54. package/lib/client/rc6/runtime-compat.js +187 -0
  55. package/lib/client/rc6/sessions-adapter.d.ts +7 -4
  56. package/lib/client/rc6/sessions-adapter.js +62 -45
  57. package/lib/client/selection/ConversationAnnotationMarkers.d.ts +0 -1
  58. package/lib/client/selection/ConversationAnnotationMarkers.js +0 -1
  59. package/lib/client/selection/SelectionActions.d.ts +0 -1
  60. package/lib/client/selection/SelectionActions.js +0 -1
  61. package/lib/client/selection/selection-controller.d.ts +0 -1
  62. package/lib/client/selection/selection-controller.js +0 -1
  63. package/lib/client/selection/selection-limits.d.ts +0 -1
  64. package/lib/client/selection/selection-limits.js +0 -1
  65. package/lib/client/selection/selection-normalizer.d.ts +0 -1
  66. package/lib/client/selection/selection-normalizer.js +0 -1
  67. package/lib/client/side-chat-controller.d.ts +0 -1
  68. package/lib/client/side-chat-controller.js +0 -1
  69. package/lib/client.js +1173 -8951
  70. package/lib/host/archived-fork-service.d.ts +0 -1
  71. package/lib/host/archived-fork-service.js +71 -26
  72. package/lib/host/index.d.ts +0 -1
  73. package/lib/host/index.js +0 -1
  74. package/lib/index.d.ts +0 -1
  75. package/lib/index.js +0 -1
  76. package/lib/remote.d.ts +0 -1
  77. package/lib/remote.js +0 -1
  78. package/lib/shared/archived-wire.d.ts +0 -1
  79. package/lib/shared/archived-wire.js +0 -1
  80. package/lib/shared/constants.d.ts +0 -1
  81. package/lib/shared/constants.js +0 -1
  82. package/lib/shared/contracts.d.ts +0 -1
  83. package/lib/shared/contracts.js +0 -1
  84. package/lib/shared/error-codes.d.ts +0 -1
  85. package/lib/shared/error-codes.js +0 -1
  86. package/lib/shared/observable.d.ts +0 -1
  87. package/lib/shared/observable.js +0 -1
  88. package/lib/typert.d.ts +0 -1
  89. package/lib/typert.js +64 -51
  90. package/package.json +60 -38
  91. package/lib/client/apply.d.ts.map +0 -1
  92. package/lib/client/apply.js.map +0 -1
  93. package/lib/client/contracts.d.ts.map +0 -1
  94. package/lib/client/contracts.js.map +0 -1
  95. package/lib/client/index.d.ts.map +0 -1
  96. package/lib/client/index.js.map +0 -1
  97. package/lib/client/model-preference.d.ts.map +0 -1
  98. package/lib/client/model-preference.js.map +0 -1
  99. package/lib/client/panel/SelectionQuote.d.ts.map +0 -1
  100. package/lib/client/panel/SelectionQuote.js.map +0 -1
  101. package/lib/client/panel/SendIcon.d.ts.map +0 -1
  102. package/lib/client/panel/SendIcon.js.map +0 -1
  103. package/lib/client/panel/SideChatBody.d.ts.map +0 -1
  104. package/lib/client/panel/SideChatBody.js.map +0 -1
  105. package/lib/client/panel/SideChatErrorState.d.ts.map +0 -1
  106. package/lib/client/panel/SideChatErrorState.js.map +0 -1
  107. package/lib/client/panel/SideChatHeader.d.ts.map +0 -1
  108. package/lib/client/panel/SideChatHeader.js.map +0 -1
  109. package/lib/client/panel/SideChatModelSelect.d.ts.map +0 -1
  110. package/lib/client/panel/SideChatModelSelect.js.map +0 -1
  111. package/lib/client/panel/SideChatPanel.d.ts.map +0 -1
  112. package/lib/client/panel/SideChatPanel.js.map +0 -1
  113. package/lib/client/panel/StopIcon.d.ts.map +0 -1
  114. package/lib/client/panel/StopIcon.js.map +0 -1
  115. package/lib/client/panel/messages.d.ts.map +0 -1
  116. package/lib/client/panel/messages.js.map +0 -1
  117. package/lib/client/panel/use-auto-growing-textarea.d.ts.map +0 -1
  118. package/lib/client/panel/use-auto-growing-textarea.js.map +0 -1
  119. package/lib/client/parent-composer/ParentConversationAnnotations.d.ts.map +0 -1
  120. package/lib/client/parent-composer/ParentConversationAnnotations.js.map +0 -1
  121. package/lib/client/parent-composer/add-to-conversation.d.ts.map +0 -1
  122. package/lib/client/parent-composer/add-to-conversation.js.map +0 -1
  123. package/lib/client/parent-composer/annotation-persistence.d.ts.map +0 -1
  124. package/lib/client/parent-composer/annotation-persistence.js.map +0 -1
  125. package/lib/client/parent-composer/composer-reference.d.ts.map +0 -1
  126. package/lib/client/parent-composer/composer-reference.js.map +0 -1
  127. package/lib/client/parent-composer/referenced-conversation.d.ts.map +0 -1
  128. package/lib/client/parent-composer/referenced-conversation.js.map +0 -1
  129. package/lib/client/rc6/ArchivedConversation.d.ts.map +0 -1
  130. package/lib/client/rc6/ArchivedConversation.js.map +0 -1
  131. package/lib/client/rc6/Rc6SideChatOverlay.d.ts.map +0 -1
  132. package/lib/client/rc6/Rc6SideChatOverlay.js.map +0 -1
  133. package/lib/client/rc6/SideChatTool.d.ts.map +0 -1
  134. package/lib/client/rc6/SideChatTool.js.map +0 -1
  135. package/lib/client/rc6/context.d.ts.map +0 -1
  136. package/lib/client/rc6/context.js.map +0 -1
  137. package/lib/client/rc6/remote-adapter.d.ts.map +0 -1
  138. package/lib/client/rc6/remote-adapter.js.map +0 -1
  139. package/lib/client/rc6/sessions-adapter.d.ts.map +0 -1
  140. package/lib/client/rc6/sessions-adapter.js.map +0 -1
  141. package/lib/client/selection/ConversationAnnotationMarkers.d.ts.map +0 -1
  142. package/lib/client/selection/ConversationAnnotationMarkers.js.map +0 -1
  143. package/lib/client/selection/SelectionActions.d.ts.map +0 -1
  144. package/lib/client/selection/SelectionActions.js.map +0 -1
  145. package/lib/client/selection/selection-controller.d.ts.map +0 -1
  146. package/lib/client/selection/selection-controller.js.map +0 -1
  147. package/lib/client/selection/selection-limits.d.ts.map +0 -1
  148. package/lib/client/selection/selection-limits.js.map +0 -1
  149. package/lib/client/selection/selection-normalizer.d.ts.map +0 -1
  150. package/lib/client/selection/selection-normalizer.js.map +0 -1
  151. package/lib/client/side-chat-controller.d.ts.map +0 -1
  152. package/lib/client/side-chat-controller.js.map +0 -1
  153. package/lib/client.js.map +0 -1
  154. package/lib/host/archived-fork-service.d.ts.map +0 -1
  155. package/lib/host/archived-fork-service.js.map +0 -1
  156. package/lib/host/index.d.ts.map +0 -1
  157. package/lib/host/index.js.map +0 -1
  158. package/lib/index.d.ts.map +0 -1
  159. package/lib/index.js.map +0 -1
  160. package/lib/remote.d.ts.map +0 -1
  161. package/lib/remote.js.map +0 -1
  162. package/lib/shared/archived-wire.d.ts.map +0 -1
  163. package/lib/shared/archived-wire.js.map +0 -1
  164. package/lib/shared/constants.d.ts.map +0 -1
  165. package/lib/shared/constants.js.map +0 -1
  166. package/lib/shared/contracts.d.ts.map +0 -1
  167. package/lib/shared/contracts.js.map +0 -1
  168. package/lib/shared/error-codes.d.ts.map +0 -1
  169. package/lib/shared/error-codes.js.map +0 -1
  170. package/lib/shared/observable.d.ts.map +0 -1
  171. package/lib/shared/observable.js.map +0 -1
  172. package/lib/typert.d.ts.map +0 -1
  173. 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): SessionFace | undefined;
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: ConversationSnapshot, anchorKey: string): {
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: error.code === 'session-not-found' ? 'side_chat_not_found' : fallback,
12
+ code: missing ? 'side_chat_not_found' : fallback,
10
13
  message: error.message,
11
- recoverable: error.code !== 'bad-request',
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
- const receipt = await wait.respond({
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 result = answer === null
116
- ? {
117
- ok: false,
118
- error: { code: 'cancelled', message: 'Question cancelled.', details: {} },
119
- }
108
+ const normalized = answer === null
109
+ ? null
120
110
  : {
121
- ok: true,
122
- value: {
123
- sessionId: wait.sessionId,
124
- answer: {
125
- answers: answer.answers.map(item => ({
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
- const receipt = await wait.respond(result);
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.ctx.sessions.binding(dshSessionId(parentSessionId))?.session.getSnapshot();
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.ctx.sessions.binding(dshSessionId(selection.parentSessionId))?.session.getSnapshot();
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.chat.nodes.get(fragment.nodeKey);
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.ctx.conversation.input.for(scope);
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 concrete = binding.session;
268
- await concrete.open();
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 binding.session.rename(title.slice(0, 160)).catch(() => undefined);
258
+ await face.rename(title.slice(0, 160)).catch(() => undefined);
274
259
  }
275
- const adapted = new Rc6SessionBinding(binding.session);
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
- return this.ctx.sessions.binding(dshSessionId(sessionId))?.session;
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.ctx.conversation.input.for(scope);
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.chat.nodes.get(anchorKey);
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
@@ -34,4 +34,3 @@ export declare function restoreDomConversationSelection(input: {
34
34
  readonly selection: ConversationSelection;
35
35
  readonly conversationRoot: HTMLElement;
36
36
  }): RestoredConversationSelection | undefined;
37
- //# sourceMappingURL=selection-controller.d.ts.map
@@ -162,4 +162,3 @@ export function restoreDomConversationSelection(input) {
162
162
  browserRange.setEnd(last.endContainer, last.endOffset);
163
163
  return { ranges, browserRange };
164
164
  }
165
- //# sourceMappingURL=selection-controller.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
@@ -16,4 +16,3 @@ export function summarizeSelection(value, maxCodePoints = 240) {
16
16
  const tailLength = maxCodePoints - headLength;
17
17
  return `${points.slice(0, headLength).join('')}…${points.slice(-tailLength).join('')}`;
18
18
  }
19
- //# sourceMappingURL=selection-limits.js.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
@@ -45,4 +45,3 @@ export function assertSelectionCurrent(selection, currentSessionId) {
45
45
  throw new SelectionValidationError('selection_stale', 'The parent conversation changed after selection.');
46
46
  }
47
47
  }
48
- //# sourceMappingURL=selection-normalizer.js.map
@@ -54,4 +54,3 @@ export declare class SideChatController implements HostObservable<SideChatState>
54
54
  private reset;
55
55
  private publish;
56
56
  }
57
- //# sourceMappingURL=side-chat-controller.d.ts.map
@@ -420,4 +420,3 @@ export class SideChatController {
420
420
  this.observable.publish(Object.freeze(state));
421
421
  }
422
422
  }
423
- //# sourceMappingURL=side-chat-controller.js.map