@sider-ai/chrome-openclaw-sider 1.0.31

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 (61) hide show
  1. package/README.md +75 -0
  2. package/README.zh_CN.md +108 -0
  3. package/dist/account-cW9SLuNu.d.ts +75 -0
  4. package/dist/index.d.ts +12 -0
  5. package/dist/index.js +87 -0
  6. package/dist/setup-entry.d.ts +6 -0
  7. package/dist/setup-entry.js +11 -0
  8. package/dist/setup-plugin-api.d.ts +7 -0
  9. package/dist/setup-plugin-api.js +4 -0
  10. package/dist/src/account.d.ts +6 -0
  11. package/dist/src/account.js +260 -0
  12. package/dist/src/auth.d.ts +30 -0
  13. package/dist/src/auth.js +225 -0
  14. package/dist/src/channel-auto-title.d.ts +6 -0
  15. package/dist/src/channel-auto-title.js +102 -0
  16. package/dist/src/channel-builders.d.ts +105 -0
  17. package/dist/src/channel-builders.js +238 -0
  18. package/dist/src/channel-hooks.d.ts +30 -0
  19. package/dist/src/channel-hooks.js +380 -0
  20. package/dist/src/channel-monitor.d.ts +34 -0
  21. package/dist/src/channel-monitor.js +335 -0
  22. package/dist/src/channel-parts.d.ts +26 -0
  23. package/dist/src/channel-parts.js +32 -0
  24. package/dist/src/channel-relay.d.ts +117 -0
  25. package/dist/src/channel-relay.js +574 -0
  26. package/dist/src/channel-runtime.d.ts +33 -0
  27. package/dist/src/channel-runtime.js +138 -0
  28. package/dist/src/channel-send-result.d.ts +19 -0
  29. package/dist/src/channel-send-result.js +126 -0
  30. package/dist/src/channel-send.d.ts +73 -0
  31. package/dist/src/channel-send.js +291 -0
  32. package/dist/src/channel-session-model.d.ts +19 -0
  33. package/dist/src/channel-session-model.js +244 -0
  34. package/dist/src/channel-shared.d.ts +153 -0
  35. package/dist/src/channel-shared.js +96 -0
  36. package/dist/src/channel-state.d.ts +93 -0
  37. package/dist/src/channel-state.js +475 -0
  38. package/dist/src/channel-streaming.d.ts +117 -0
  39. package/dist/src/channel-streaming.js +681 -0
  40. package/dist/src/channel-types.d.ts +209 -0
  41. package/dist/src/channel-types.js +40 -0
  42. package/dist/src/channel-typing.d.ts +17 -0
  43. package/dist/src/channel-typing.js +79 -0
  44. package/dist/src/channel-util.d.ts +78 -0
  45. package/dist/src/channel-util.js +604 -0
  46. package/dist/src/channel.d.ts +14 -0
  47. package/dist/src/channel.js +834 -0
  48. package/dist/src/channel.setup.d.ts +10 -0
  49. package/dist/src/channel.setup.js +9 -0
  50. package/dist/src/config.d.ts +18 -0
  51. package/dist/src/config.js +38 -0
  52. package/dist/src/inbound-media.d.ts +37 -0
  53. package/dist/src/inbound-media.js +148 -0
  54. package/dist/src/media-upload.d.ts +87 -0
  55. package/dist/src/media-upload.js +1308 -0
  56. package/dist/src/setup-core.d.ts +72 -0
  57. package/dist/src/setup-core.js +343 -0
  58. package/dist/src/user-agent.d.ts +4 -0
  59. package/dist/src/user-agent.js +6 -0
  60. package/openclaw.plugin.json +96 -0
  61. package/package.json +47 -0
@@ -0,0 +1,681 @@
1
+ import { resolveOutboundMediaUrls } from "openclaw/plugin-sdk/reply-payload";
2
+ import { logDebug, logWarn } from "./channel-runtime.js";
3
+ import {
4
+ buildPendingMessageContextForRun,
5
+ clearBindingRunId,
6
+ discardSiderRunState,
7
+ consumePendingMessageContextForRun,
8
+ enqueueCompletedParts,
9
+ flushFinalQueuedPartForRun,
10
+ flushQueuedPartsExceptTailForRun,
11
+ resolvePendingFinalTextForRun,
12
+ hasTextParts
13
+ } from "./channel-state.js";
14
+ import { mergeTextSegments } from "./channel-util.js";
15
+ import {
16
+ buildStreamingStartEvent,
17
+ buildStreamingDeltaEvent,
18
+ buildStreamingDoneEvent,
19
+ buildReasoningStartEvent,
20
+ buildReasoningDeltaEvent,
21
+ buildReasoningDoneEvent,
22
+ buildTextPart
23
+ } from "./channel-builders.js";
24
+ import {
25
+ sendSiderEventBestEffort,
26
+ sendMessageToSider
27
+ } from "./channel-relay.js";
28
+ import { prepareSiderReplyPayloadParts } from "./channel-parts.js";
29
+ import { startDeferredSiderUploads } from "./media-upload.js";
30
+ function cleanupSiderRunAfterReply(params) {
31
+ clearBindingRunId(params.streamState.sessionKey, params.runId);
32
+ discardSiderRunState(params.runId);
33
+ params.streamState.currentRunId = void 0;
34
+ if (params.resetFallbackText !== false) {
35
+ resetAllFallbackTextState(params.streamState);
36
+ }
37
+ }
38
+ async function openStreamingSessionIfNeeded(params) {
39
+ if (params.laneState.active && params.laneState.streamId) {
40
+ return;
41
+ }
42
+ params.laneState.active = true;
43
+ params.laneState.streamId = crypto.randomUUID();
44
+ params.laneState.seq = 0;
45
+ const streamStartEvent = buildStreamingStartEvent({
46
+ sessionId: params.sessionId,
47
+ streamId: params.laneState.streamId,
48
+ accountId: params.account.accountId
49
+ });
50
+ await sendSiderEventBestEffort({
51
+ account: params.account,
52
+ sessionId: params.sessionId,
53
+ event: streamStartEvent,
54
+ context: "stream.start"
55
+ });
56
+ }
57
+ async function openReasoningSessionIfNeeded(params) {
58
+ if (params.laneState.active && params.laneState.streamId) {
59
+ return;
60
+ }
61
+ params.laneState.active = true;
62
+ params.laneState.streamId = crypto.randomUUID();
63
+ params.laneState.seq = 0;
64
+ const reasoningStartEvent = buildReasoningStartEvent({
65
+ sessionId: params.sessionId,
66
+ streamId: params.laneState.streamId,
67
+ accountId: params.account.accountId
68
+ });
69
+ logDebug("sending reasoning start event", {
70
+ accountId: params.account.accountId,
71
+ sessionId: params.sessionId,
72
+ eventType: reasoningStartEvent.eventType,
73
+ streamId: params.laneState.streamId,
74
+ context: "reasoning.start"
75
+ });
76
+ await sendSiderEventBestEffort({
77
+ account: params.account,
78
+ sessionId: params.sessionId,
79
+ event: reasoningStartEvent,
80
+ context: "reasoning.start"
81
+ });
82
+ }
83
+ async function sendStreamingDeltaEvent(params) {
84
+ if (!params.delta) {
85
+ return;
86
+ }
87
+ await openStreamingSessionIfNeeded({
88
+ account: params.account,
89
+ sessionId: params.sessionId,
90
+ laneState: params.streamState.answer
91
+ });
92
+ params.streamState.answer.seq += 1;
93
+ const streamDeltaEvent = buildStreamingDeltaEvent({
94
+ sessionId: params.sessionId,
95
+ streamId: params.streamState.answer.streamId,
96
+ seq: params.streamState.answer.seq,
97
+ delta: params.delta,
98
+ text: params.text,
99
+ accountId: params.account.accountId
100
+ });
101
+ logDebug("sending stream delta event", {
102
+ accountId: params.account.accountId,
103
+ sessionId: params.sessionId,
104
+ eventType: streamDeltaEvent.eventType,
105
+ streamId: params.streamState.answer.streamId,
106
+ seq: params.streamState.answer.seq,
107
+ deltaLength: params.delta.length,
108
+ textLength: params.text.length,
109
+ context: params.context
110
+ });
111
+ await sendSiderEventBestEffort({
112
+ account: params.account,
113
+ sessionId: params.sessionId,
114
+ event: streamDeltaEvent,
115
+ context: params.context
116
+ });
117
+ }
118
+ async function sendReasoningDeltaEvent(params) {
119
+ if (!params.delta) {
120
+ return;
121
+ }
122
+ await openReasoningSessionIfNeeded({
123
+ account: params.account,
124
+ sessionId: params.sessionId,
125
+ laneState: params.streamState.reasoning
126
+ });
127
+ params.streamState.reasoning.seq += 1;
128
+ const reasoningDeltaEvent = buildReasoningDeltaEvent({
129
+ sessionId: params.sessionId,
130
+ streamId: params.streamState.reasoning.streamId,
131
+ seq: params.streamState.reasoning.seq,
132
+ delta: params.delta,
133
+ text: params.text,
134
+ accountId: params.account.accountId
135
+ });
136
+ logDebug("sending reasoning delta event", {
137
+ accountId: params.account.accountId,
138
+ sessionId: params.sessionId,
139
+ eventType: reasoningDeltaEvent.eventType,
140
+ streamId: params.streamState.reasoning.streamId,
141
+ seq: params.streamState.reasoning.seq,
142
+ deltaLength: params.delta.length,
143
+ textLength: params.text.length,
144
+ context: params.context
145
+ });
146
+ await sendSiderEventBestEffort({
147
+ account: params.account,
148
+ sessionId: params.sessionId,
149
+ event: reasoningDeltaEvent,
150
+ context: params.context
151
+ });
152
+ }
153
+ async function closeStreamingSessionIfActive(params) {
154
+ if (!params.streamState.answer.active || !params.streamState.answer.streamId) {
155
+ return;
156
+ }
157
+ params.streamState.answer.seq += 1;
158
+ const streamDoneEvent = buildStreamingDoneEvent({
159
+ sessionId: params.sessionId,
160
+ streamId: params.streamState.answer.streamId,
161
+ seq: params.streamState.answer.seq,
162
+ accountId: params.account.accountId,
163
+ reason: params.reason
164
+ });
165
+ await sendSiderEventBestEffort({
166
+ account: params.account,
167
+ sessionId: params.sessionId,
168
+ event: streamDoneEvent,
169
+ context: params.context
170
+ });
171
+ params.streamState.answer.active = false;
172
+ params.streamState.answer.streamId = void 0;
173
+ params.streamState.answer.seq = 0;
174
+ }
175
+ async function closeReasoningSessionIfActive(params) {
176
+ if (!params.streamState.reasoning.active || !params.streamState.reasoning.streamId) {
177
+ return;
178
+ }
179
+ params.streamState.reasoning.seq += 1;
180
+ const reasoningDoneEvent = buildReasoningDoneEvent({
181
+ sessionId: params.sessionId,
182
+ streamId: params.streamState.reasoning.streamId,
183
+ seq: params.streamState.reasoning.seq,
184
+ accountId: params.account.accountId,
185
+ reason: params.reason
186
+ });
187
+ logDebug("sending reasoning done event", {
188
+ accountId: params.account.accountId,
189
+ sessionId: params.sessionId,
190
+ eventType: reasoningDoneEvent.eventType,
191
+ streamId: params.streamState.reasoning.streamId,
192
+ seq: params.streamState.reasoning.seq,
193
+ reason: params.reason,
194
+ context: params.context
195
+ });
196
+ await sendSiderEventBestEffort({
197
+ account: params.account,
198
+ sessionId: params.sessionId,
199
+ event: reasoningDoneEvent,
200
+ context: params.context
201
+ });
202
+ params.streamState.reasoning.active = false;
203
+ params.streamState.reasoning.streamId = void 0;
204
+ params.streamState.reasoning.seq = 0;
205
+ }
206
+ function enqueueStreamEventTask(params) {
207
+ const next = params.streamState.streamEventQueue.then(params.task).catch((err) => {
208
+ logWarn("sider stream event queue task failed", {
209
+ error: String(err)
210
+ });
211
+ });
212
+ params.streamState.streamEventQueue = next;
213
+ return next;
214
+ }
215
+ async function flushStreamEventQueue(streamState) {
216
+ await streamState.streamEventQueue;
217
+ }
218
+ function derivePartialDelta(params) {
219
+ const prev = params.previous;
220
+ const next = params.next;
221
+ if (!next) {
222
+ return "";
223
+ }
224
+ if (!prev) {
225
+ return next;
226
+ }
227
+ if (next === prev) {
228
+ return "";
229
+ }
230
+ if (next.startsWith(prev)) {
231
+ return next.slice(prev.length);
232
+ }
233
+ if (prev.startsWith(next)) {
234
+ return "";
235
+ }
236
+ const maxOverlap = Math.min(prev.length, next.length);
237
+ for (let overlap = maxOverlap; overlap > 0; overlap -= 1) {
238
+ if (prev.endsWith(next.slice(0, overlap))) {
239
+ return next.slice(overlap);
240
+ }
241
+ }
242
+ return next;
243
+ }
244
+ function mergeBlockTextIntoStreamState(params) {
245
+ params.streamState.answer.accumulatedBlockText = mergeTextSegments(
246
+ params.streamState.answer.accumulatedBlockText,
247
+ params.text
248
+ );
249
+ if (params.text) {
250
+ if (params.streamState.answer.assistantSeq <= 0) {
251
+ params.streamState.answer.assistantSeq = 1;
252
+ }
253
+ params.streamState.answer.fallbackAssistantSeq = params.streamState.answer.assistantSeq;
254
+ params.streamState.answer.fallbackTextSource = "stream";
255
+ params.streamState.answer.fallbackCurrentText = mergeTextSegments(
256
+ params.streamState.answer.fallbackCurrentText,
257
+ params.text
258
+ );
259
+ }
260
+ }
261
+ function resolveCurrentStreamVisibleText(streamState) {
262
+ if (streamState.answer.streamDeltaMode === "partial" && streamState.answer.partialSnapshot) {
263
+ return streamState.answer.partialSnapshot;
264
+ }
265
+ return streamState.answer.accumulatedBlockText;
266
+ }
267
+ function resolveFallbackFinalText(streamState) {
268
+ if (streamState.answer.assistantSeq <= 0 || streamState.answer.fallbackAssistantSeq !== streamState.answer.assistantSeq) {
269
+ return "";
270
+ }
271
+ return mergeTextSegments(
272
+ streamState.answer.fallbackTextPrefix,
273
+ streamState.answer.fallbackCurrentText
274
+ ).trim();
275
+ }
276
+ function commitCurrentStreamTextToFallbackPrefix(streamState) {
277
+ if (streamState.answer.assistantSeq <= 0) {
278
+ streamState.answer.assistantSeq = 1;
279
+ }
280
+ streamState.answer.fallbackAssistantSeq = streamState.answer.assistantSeq;
281
+ streamState.answer.fallbackTextPrefix = mergeTextSegments(
282
+ streamState.answer.fallbackTextPrefix,
283
+ streamState.answer.fallbackCurrentText
284
+ );
285
+ streamState.answer.fallbackCurrentText = "";
286
+ }
287
+ function rotateAssistantMessageFallbackState(streamState) {
288
+ streamState.answer.assistantSeq += 1;
289
+ streamState.answer.fallbackAssistantSeq = streamState.answer.assistantSeq;
290
+ streamState.answer.fallbackTextSource = "none";
291
+ streamState.answer.fallbackCurrentText = "";
292
+ streamState.answer.fallbackTextPrefix = "";
293
+ }
294
+ function resetCurrentStreamTextState(streamState) {
295
+ streamState.answer.blockDeltaCount = 0;
296
+ streamState.answer.partialDeltaCount = 0;
297
+ streamState.answer.streamDeltaMode = "undecided";
298
+ streamState.answer.partialSnapshot = "";
299
+ streamState.answer.accumulatedBlockText = "";
300
+ }
301
+ function resetAllFallbackTextState(streamState) {
302
+ streamState.answer.assistantSeq = 0;
303
+ streamState.answer.fallbackAssistantSeq = 0;
304
+ streamState.answer.fallbackTextSource = "none";
305
+ streamState.answer.fallbackCurrentText = "";
306
+ streamState.answer.fallbackTextPrefix = "";
307
+ resetCurrentStreamTextState(streamState);
308
+ }
309
+ function resetReasoningStreamState(streamState) {
310
+ streamState.reasoning.snapshot = "";
311
+ streamState.reasoning.deltaCount = 0;
312
+ }
313
+ async function handleStreamingPartialSnapshot(params) {
314
+ if (params.streamState.answer.streamDeltaMode === "block") {
315
+ return;
316
+ }
317
+ if (params.streamState.answer.streamDeltaMode === "undecided") {
318
+ params.streamState.answer.streamDeltaMode = "partial";
319
+ }
320
+ if (!params.snapshot) {
321
+ return;
322
+ }
323
+ const delta = derivePartialDelta({
324
+ previous: params.streamState.answer.partialSnapshot,
325
+ next: params.snapshot
326
+ });
327
+ if (params.streamState.answer.assistantSeq <= 0) {
328
+ params.streamState.answer.assistantSeq = 1;
329
+ }
330
+ params.streamState.answer.fallbackAssistantSeq = params.streamState.answer.assistantSeq;
331
+ params.streamState.answer.fallbackTextSource = "stream";
332
+ params.streamState.answer.partialSnapshot = params.snapshot;
333
+ params.streamState.answer.fallbackCurrentText = params.snapshot;
334
+ if (!delta) {
335
+ return;
336
+ }
337
+ await sendStreamingDeltaEvent({
338
+ account: params.account,
339
+ sessionId: params.sessionId,
340
+ streamState: params.streamState,
341
+ delta,
342
+ text: params.snapshot,
343
+ context: "stream.delta.partial"
344
+ });
345
+ params.streamState.answer.partialDeltaCount += 1;
346
+ }
347
+ async function handleReasoningSnapshot(params) {
348
+ if (!params.snapshot.trim()) {
349
+ return;
350
+ }
351
+ const delta = derivePartialDelta({
352
+ previous: params.streamState.reasoning.snapshot,
353
+ next: params.snapshot
354
+ });
355
+ params.streamState.reasoning.snapshot = params.snapshot;
356
+ if (!delta) {
357
+ return;
358
+ }
359
+ await sendReasoningDeltaEvent({
360
+ account: params.account,
361
+ sessionId: params.sessionId,
362
+ streamState: params.streamState,
363
+ delta,
364
+ text: params.snapshot,
365
+ context: "reasoning.delta"
366
+ });
367
+ params.streamState.reasoning.deltaCount += 1;
368
+ }
369
+ async function persistQueuedCompletedParts(params) {
370
+ if (params.parts.length === 0) {
371
+ return;
372
+ }
373
+ const runId = params.streamState.currentRunId;
374
+ if (!runId) {
375
+ for (const part of params.parts) {
376
+ await sendMessageToSider({
377
+ account: params.account,
378
+ sessionId: params.sessionId,
379
+ parts: [part]
380
+ });
381
+ }
382
+ return;
383
+ }
384
+ enqueueCompletedParts({
385
+ runId,
386
+ parts: params.parts,
387
+ sessionKey: params.streamState.sessionKey,
388
+ sessionId: params.sessionId,
389
+ accountId: params.account.accountId
390
+ });
391
+ await flushQueuedPartsExceptTailForRun({
392
+ runId,
393
+ account: params.account,
394
+ sessionId: params.sessionId,
395
+ context: params.context
396
+ });
397
+ }
398
+ function resolvePreferredDeferredFinalText(params) {
399
+ const fallbackText = (resolvePendingFinalTextForRun(params.runId) || resolveFallbackFinalText(params.streamState)).trim();
400
+ if (!hasTextParts(params.baseParts)) {
401
+ return fallbackText;
402
+ }
403
+ return "";
404
+ }
405
+ async function finalizeQueuedRunMessages(params) {
406
+ const runId = params.streamState.currentRunId;
407
+ if (!runId) {
408
+ if (params.parts.length === 0) {
409
+ return false;
410
+ }
411
+ for (let index = 0; index < params.parts.length; index += 1) {
412
+ const part = params.parts[index];
413
+ await sendMessageToSider({
414
+ account: params.account,
415
+ sessionId: params.sessionId,
416
+ parts: [part]
417
+ });
418
+ }
419
+ params.streamState.persistedFinalText = true;
420
+ return true;
421
+ }
422
+ if (params.parts.length > 0) {
423
+ enqueueCompletedParts({
424
+ runId,
425
+ parts: params.parts,
426
+ sessionKey: params.streamState.sessionKey,
427
+ sessionId: params.sessionId,
428
+ accountId: params.account.accountId
429
+ });
430
+ }
431
+ await flushQueuedPartsExceptTailForRun({
432
+ runId,
433
+ account: params.account,
434
+ sessionId: params.sessionId,
435
+ context: `${params.context}.except_tail`
436
+ });
437
+ const persisted = await flushFinalQueuedPartForRun({
438
+ runId,
439
+ account: params.account,
440
+ sessionId: params.sessionId,
441
+ stopReason: params.stopReason,
442
+ context: `${params.context}.final_tail`
443
+ });
444
+ if (persisted) {
445
+ params.streamState.persistedFinalText = true;
446
+ }
447
+ return persisted;
448
+ }
449
+ async function deliverReplyPayloadToSider(params) {
450
+ const payloadText = typeof params.payload.text === "string" ? params.payload.text : "";
451
+ const payloadMediaUrls = resolveOutboundMediaUrls(params.payload);
452
+ if (params.kind === "block") {
453
+ const delta = payloadText;
454
+ if (delta.length > 0) {
455
+ params.streamState.answer.blockDeltaCount += 1;
456
+ if (params.streamState.answer.streamDeltaMode !== "partial") {
457
+ if (params.streamState.answer.streamDeltaMode === "undecided") {
458
+ params.streamState.answer.streamDeltaMode = "block";
459
+ }
460
+ mergeBlockTextIntoStreamState({
461
+ streamState: params.streamState,
462
+ text: delta
463
+ });
464
+ await sendStreamingDeltaEvent({
465
+ account: params.account,
466
+ sessionId: params.sessionId,
467
+ streamState: params.streamState,
468
+ delta,
469
+ text: params.streamState.answer.accumulatedBlockText,
470
+ context: "stream.delta.block"
471
+ });
472
+ } else {
473
+ logDebug("skip block stream delta because partial streaming mode is active", {
474
+ accountId: params.account.accountId,
475
+ sessionId: params.sessionId,
476
+ deltaLength: delta.length,
477
+ partialDeltaCount: params.streamState.answer.partialDeltaCount,
478
+ streamDeltaMode: params.streamState.answer.streamDeltaMode
479
+ });
480
+ }
481
+ }
482
+ if (payloadMediaUrls.length === 0) {
483
+ return;
484
+ }
485
+ logDebug("block payload contains media; sending persisted sider message", {
486
+ accountId: params.account.accountId,
487
+ sessionId: params.sessionId,
488
+ mediaCount: payloadMediaUrls.length,
489
+ hasText: delta.length > 0
490
+ });
491
+ }
492
+ if (params.kind === "final") {
493
+ await flushStreamEventQueue(params.streamState);
494
+ if (!params.streamState.answer.active && params.streamState.answer.blockDeltaCount === 0) {
495
+ const finalText = payloadText;
496
+ if (finalText.length > 0) {
497
+ logDebug("no block delta observed; sending synthetic stream events from final payload", {
498
+ accountId: params.account.accountId,
499
+ sessionId: params.sessionId,
500
+ textLength: finalText.length
501
+ });
502
+ params.streamState.answer.accumulatedBlockText = finalText;
503
+ if (params.streamState.answer.assistantSeq <= 0) {
504
+ params.streamState.answer.assistantSeq = 1;
505
+ }
506
+ params.streamState.answer.fallbackAssistantSeq = params.streamState.answer.assistantSeq;
507
+ params.streamState.answer.fallbackTextSource = "final_payload";
508
+ params.streamState.answer.fallbackCurrentText = finalText;
509
+ await sendStreamingDeltaEvent({
510
+ account: params.account,
511
+ sessionId: params.sessionId,
512
+ streamState: params.streamState,
513
+ delta: finalText,
514
+ text: finalText,
515
+ context: "stream.delta.final-fallback"
516
+ });
517
+ }
518
+ }
519
+ await closeStreamingSessionIfActive({
520
+ account: params.account,
521
+ sessionId: params.sessionId,
522
+ streamState: params.streamState,
523
+ reason: "final",
524
+ context: "stream.done"
525
+ });
526
+ params.streamState.pendingFinalPayloads.push(params.payload);
527
+ return;
528
+ }
529
+ const { parts: baseParts, deferredUploads } = await prepareSiderReplyPayloadParts({
530
+ account: params.account,
531
+ sessionId: params.sessionId,
532
+ payload: params.payload,
533
+ mediaLocalRoots: params.mediaLocalRoots,
534
+ deferUploads: true,
535
+ allowEmpty: true
536
+ });
537
+ if (baseParts.length === 0) {
538
+ return;
539
+ }
540
+ const completedParts = params.kind === "block" ? baseParts.filter((part) => part.type !== "core.text") : baseParts;
541
+ if (completedParts.length === 0) {
542
+ return;
543
+ }
544
+ logDebug("queueing sider outbound message parts from payload", {
545
+ accountId: params.account.accountId,
546
+ sessionId: params.sessionId,
547
+ kind: params.kind,
548
+ partTypes: completedParts.map((part) => part.type),
549
+ mediaCount: payloadMediaUrls.length
550
+ });
551
+ await persistQueuedCompletedParts({
552
+ account: params.account,
553
+ sessionId: params.sessionId,
554
+ streamState: params.streamState,
555
+ parts: completedParts,
556
+ context: `payload.${params.kind}`
557
+ });
558
+ if (deferredUploads.length > 0) {
559
+ startDeferredSiderUploads({
560
+ account: params.account,
561
+ sessionId: params.sessionId,
562
+ uploads: deferredUploads,
563
+ context: `payload.${params.kind}`
564
+ });
565
+ }
566
+ }
567
+ async function persistDeferredFinalReplyPayloadToSider(params) {
568
+ const { parts: baseParts, deferredUploads } = await prepareSiderReplyPayloadParts({
569
+ account: params.account,
570
+ sessionId: params.sessionId,
571
+ payload: params.payload,
572
+ mediaLocalRoots: params.mediaLocalRoots,
573
+ deferUploads: true,
574
+ allowEmpty: true
575
+ });
576
+ const selectedFinalText = resolvePreferredDeferredFinalText({
577
+ streamState: params.streamState,
578
+ runId: params.streamState.currentRunId,
579
+ baseParts
580
+ });
581
+ const messageContext = buildPendingMessageContextForRun({
582
+ accountId: params.account.accountId,
583
+ runId: params.streamState.currentRunId,
584
+ includeFinalThinking: true
585
+ });
586
+ const parts = hasTextParts(baseParts) ? [...messageContext.parts, ...baseParts] : [
587
+ ...messageContext.parts,
588
+ ...selectedFinalText ? [buildTextPart(selectedFinalText)] : [],
589
+ ...baseParts
590
+ ];
591
+ logDebug("finalizing deferred sider outbound message parts from payload", {
592
+ accountId: params.account.accountId,
593
+ sessionId: params.sessionId,
594
+ runId: params.streamState.currentRunId,
595
+ partTypes: parts.map((part) => part.type),
596
+ selectedFinalTextLength: selectedFinalText.length
597
+ });
598
+ const cleanupRunId = messageContext.runId ?? params.streamState.currentRunId;
599
+ await finalizeQueuedRunMessages({
600
+ account: params.account,
601
+ sessionId: params.sessionId,
602
+ parts,
603
+ streamState: params.streamState,
604
+ stopReason: messageContext.stopReason,
605
+ context: "final.payload"
606
+ });
607
+ if (deferredUploads.length > 0) {
608
+ startDeferredSiderUploads({
609
+ account: params.account,
610
+ sessionId: params.sessionId,
611
+ uploads: deferredUploads,
612
+ context: "final.payload"
613
+ });
614
+ }
615
+ consumePendingMessageContextForRun({
616
+ runId: cleanupRunId,
617
+ consumeFinalThinking: true
618
+ });
619
+ cleanupSiderRunAfterReply({
620
+ streamState: params.streamState,
621
+ runId: cleanupRunId
622
+ });
623
+ }
624
+ async function persistStandaloneReplyPayloadToSider(params) {
625
+ const { parts, deferredUploads } = await prepareSiderReplyPayloadParts({
626
+ account: params.account,
627
+ sessionId: params.sessionId,
628
+ payload: params.payload,
629
+ mediaLocalRoots: params.mediaLocalRoots,
630
+ deferUploads: true,
631
+ allowEmpty: true
632
+ });
633
+ if (parts.length === 0) {
634
+ return;
635
+ }
636
+ logDebug("sending standalone deferred final payload to sider", {
637
+ accountId: params.account.accountId,
638
+ sessionId: params.sessionId,
639
+ partTypes: parts.map((part) => part.type),
640
+ isError: params.payload.isError === true
641
+ });
642
+ await sendMessageToSider({
643
+ account: params.account,
644
+ sessionId: params.sessionId,
645
+ parts
646
+ });
647
+ if (deferredUploads.length > 0) {
648
+ startDeferredSiderUploads({
649
+ account: params.account,
650
+ sessionId: params.sessionId,
651
+ uploads: deferredUploads,
652
+ context: "final.payload.standalone"
653
+ });
654
+ }
655
+ }
656
+ export {
657
+ cleanupSiderRunAfterReply,
658
+ closeReasoningSessionIfActive,
659
+ closeStreamingSessionIfActive,
660
+ commitCurrentStreamTextToFallbackPrefix,
661
+ deliverReplyPayloadToSider,
662
+ derivePartialDelta,
663
+ enqueueStreamEventTask,
664
+ finalizeQueuedRunMessages,
665
+ flushStreamEventQueue,
666
+ handleReasoningSnapshot,
667
+ handleStreamingPartialSnapshot,
668
+ mergeBlockTextIntoStreamState,
669
+ openReasoningSessionIfNeeded,
670
+ openStreamingSessionIfNeeded,
671
+ persistDeferredFinalReplyPayloadToSider,
672
+ persistStandaloneReplyPayloadToSider,
673
+ resetAllFallbackTextState,
674
+ resetCurrentStreamTextState,
675
+ resetReasoningStreamState,
676
+ resolveCurrentStreamVisibleText,
677
+ resolveFallbackFinalText,
678
+ rotateAssistantMessageFallbackState,
679
+ sendReasoningDeltaEvent,
680
+ sendStreamingDeltaEvent
681
+ };