chrome-openclaw-sider 1.0.2 → 1.0.26
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 +11 -1
- package/README.zh_CN.md +8 -6
- package/dist/index.d.ts +12 -0
- package/{index.ts → dist/index.js} +24 -17
- package/dist/setup-entry.d.ts +18 -0
- package/dist/setup-entry.js +8 -0
- package/dist/src/account.d.ts +54 -0
- package/{src/account.ts → dist/src/account.js} +70 -160
- package/dist/src/auth.d.ts +30 -0
- package/{src/auth.ts → dist/src/auth.js} +61 -128
- package/dist/src/auto-title.d.ts +20 -0
- package/dist/src/auto-title.js +22 -0
- package/dist/src/channel-auto-title.d.ts +23 -0
- package/dist/src/channel-auto-title.js +77 -0
- package/dist/src/channel-builders.d.ts +105 -0
- package/dist/src/channel-builders.js +238 -0
- package/dist/src/channel-hooks.d.ts +30 -0
- package/dist/src/channel-hooks.js +331 -0
- package/dist/src/channel-monitor.d.ts +34 -0
- package/dist/src/channel-monitor.js +341 -0
- package/dist/src/channel-relay.d.ts +117 -0
- package/dist/src/channel-relay.js +573 -0
- package/dist/src/channel-runtime.d.ts +32 -0
- package/dist/src/channel-runtime.js +85 -0
- package/dist/src/channel-send-result.d.ts +19 -0
- package/dist/src/channel-send-result.js +126 -0
- package/dist/src/channel-session-model.d.ts +19 -0
- package/dist/src/channel-session-model.js +244 -0
- package/dist/src/channel-state.d.ts +92 -0
- package/dist/src/channel-state.js +471 -0
- package/dist/src/channel-streaming.d.ts +117 -0
- package/dist/src/channel-streaming.js +645 -0
- package/dist/src/channel-types.d.ts +207 -0
- package/dist/src/channel-types.js +40 -0
- package/dist/src/channel-typing.d.ts +17 -0
- package/dist/src/channel-typing.js +79 -0
- package/dist/src/channel-util.d.ts +78 -0
- package/dist/src/channel-util.js +524 -0
- package/dist/src/channel.d.ts +14 -0
- package/dist/src/channel.js +1023 -0
- package/dist/src/config.d.ts +18 -0
- package/dist/src/config.js +38 -0
- package/dist/src/inbound-media.d.ts +37 -0
- package/{src/inbound-media.ts → dist/src/inbound-media.js} +33 -81
- package/dist/src/media-upload.d.ts +86 -0
- package/dist/src/media-upload.js +1222 -0
- package/dist/src/setup-core.d.ts +72 -0
- package/{src/setup-core.ts → dist/src/setup-core.js} +106 -194
- package/dist/src/user-agent.d.ts +4 -0
- package/dist/src/user-agent.js +6 -0
- package/openclaw.plugin.json +86 -0
- package/package.json +9 -13
- package/setup-entry.ts +0 -6
- package/src/channel.ts +0 -3862
- package/src/config.ts +0 -29
- package/src/media-upload.ts +0 -983
- package/src/remote-browser-support.ts +0 -64
- package/src/user-agent.ts +0 -17
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SIDER_RUN_STATE_MAX,
|
|
3
|
+
SIDER_RUN_STATE_TTL_MS,
|
|
4
|
+
SIDER_SESSION_BINDING_MAX,
|
|
5
|
+
SIDER_SESSION_BINDING_TTL_MS
|
|
6
|
+
} from "./channel-types.js";
|
|
7
|
+
import { buildThinkingPart } from "./channel-builders.js";
|
|
8
|
+
import { sendMessageToSider, sendSiderMessageBestEffort } from "./channel-relay.js";
|
|
9
|
+
import { logWarn, siderRunStates, siderSessionBindings } from "./channel-runtime.js";
|
|
10
|
+
import { buildEventMeta, buildMessageMeta, parseTextFromPart } from "./channel-util.js";
|
|
11
|
+
function normalizeSessionBindingKey(raw) {
|
|
12
|
+
const key = raw?.trim().toLowerCase();
|
|
13
|
+
return key || void 0;
|
|
14
|
+
}
|
|
15
|
+
function pruneSiderSessionBindings(now = Date.now()) {
|
|
16
|
+
for (const [key, binding] of siderSessionBindings) {
|
|
17
|
+
if (now - binding.lastSeenAt > SIDER_SESSION_BINDING_TTL_MS) {
|
|
18
|
+
siderSessionBindings.delete(key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (siderSessionBindings.size <= SIDER_SESSION_BINDING_MAX) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const sorted = [...siderSessionBindings.entries()].sort(
|
|
25
|
+
(a, b) => a[1].lastSeenAt - b[1].lastSeenAt
|
|
26
|
+
);
|
|
27
|
+
const overflow = siderSessionBindings.size - SIDER_SESSION_BINDING_MAX;
|
|
28
|
+
for (let index = 0; index < overflow; index += 1) {
|
|
29
|
+
const key = sorted[index]?.[0];
|
|
30
|
+
if (key) {
|
|
31
|
+
siderSessionBindings.delete(key);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function rememberSiderSessionBinding(params) {
|
|
36
|
+
const key = normalizeSessionBindingKey(params.sessionKey);
|
|
37
|
+
if (!key) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
const existing = siderSessionBindings.get(key);
|
|
42
|
+
if (existing) {
|
|
43
|
+
existing.account = params.account;
|
|
44
|
+
existing.sessionId = params.sessionId;
|
|
45
|
+
existing.lastSeenAt = now;
|
|
46
|
+
existing.currentRunId = void 0;
|
|
47
|
+
pruneSiderSessionBindings(now);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
siderSessionBindings.set(key, {
|
|
51
|
+
account: params.account,
|
|
52
|
+
sessionId: params.sessionId,
|
|
53
|
+
lastSeenAt: now,
|
|
54
|
+
toolSeq: 0,
|
|
55
|
+
currentRunId: void 0,
|
|
56
|
+
currentToolCallId: void 0,
|
|
57
|
+
callIdByToolCallId: /* @__PURE__ */ new Map()
|
|
58
|
+
});
|
|
59
|
+
pruneSiderSessionBindings(now);
|
|
60
|
+
}
|
|
61
|
+
function resolveSiderSessionBinding(sessionKey) {
|
|
62
|
+
const key = normalizeSessionBindingKey(sessionKey);
|
|
63
|
+
if (!key) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
const binding = siderSessionBindings.get(key);
|
|
67
|
+
if (!binding) {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
binding.lastSeenAt = Date.now();
|
|
71
|
+
return binding;
|
|
72
|
+
}
|
|
73
|
+
function resolveSiderBindingByTarget(params) {
|
|
74
|
+
const accountId = params.accountId.trim();
|
|
75
|
+
const sessionId = params.sessionId.trim();
|
|
76
|
+
if (!accountId || !sessionId) {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
for (const [sessionKey, binding] of siderSessionBindings) {
|
|
80
|
+
if (binding.account.accountId === accountId && binding.sessionId === sessionId) {
|
|
81
|
+
binding.lastSeenAt = Date.now();
|
|
82
|
+
return { sessionKey, binding };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
function pruneSiderRunStates(now = Date.now()) {
|
|
88
|
+
for (const [runId, state] of siderRunStates) {
|
|
89
|
+
if (now - state.updatedAt > SIDER_RUN_STATE_TTL_MS) {
|
|
90
|
+
siderRunStates.delete(runId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (siderRunStates.size <= SIDER_RUN_STATE_MAX) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const sorted = [...siderRunStates.entries()].sort((a, b) => a[1].updatedAt - b[1].updatedAt);
|
|
97
|
+
const overflow = siderRunStates.size - SIDER_RUN_STATE_MAX;
|
|
98
|
+
for (let index = 0; index < overflow; index += 1) {
|
|
99
|
+
const runId = sorted[index]?.[0];
|
|
100
|
+
if (runId) {
|
|
101
|
+
siderRunStates.delete(runId);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function touchRunState(runState) {
|
|
106
|
+
runState.updatedAt = Date.now();
|
|
107
|
+
pruneSiderRunStates(runState.updatedAt);
|
|
108
|
+
}
|
|
109
|
+
function appendRunFlushTask(runState, task) {
|
|
110
|
+
const taskPromise = runState.messageFlushChain.then(task);
|
|
111
|
+
runState.messageFlushChain = taskPromise.then(
|
|
112
|
+
() => void 0,
|
|
113
|
+
(error) => {
|
|
114
|
+
logWarn("sider queued message flush failed", {
|
|
115
|
+
runId: runState.runId,
|
|
116
|
+
error: String(error)
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
return taskPromise;
|
|
121
|
+
}
|
|
122
|
+
function buildBaseMessageMetaForRun(params) {
|
|
123
|
+
const meta = buildEventMeta({ accountId: params.accountId });
|
|
124
|
+
if (params.runState.runId) {
|
|
125
|
+
meta.run_id = params.runState.runId;
|
|
126
|
+
}
|
|
127
|
+
if (params.runState.provider) {
|
|
128
|
+
meta.provider = params.runState.provider;
|
|
129
|
+
}
|
|
130
|
+
if (params.runState.model) {
|
|
131
|
+
meta.model = params.runState.model;
|
|
132
|
+
}
|
|
133
|
+
return meta;
|
|
134
|
+
}
|
|
135
|
+
function nextAggregationForRun(runState, final) {
|
|
136
|
+
const aggregation = {
|
|
137
|
+
id: runState.aggregationId,
|
|
138
|
+
index: runState.nextAggregationIndex,
|
|
139
|
+
final
|
|
140
|
+
};
|
|
141
|
+
runState.nextAggregationIndex += 1;
|
|
142
|
+
return aggregation;
|
|
143
|
+
}
|
|
144
|
+
function takeQueuedPartsExceptTail(runState) {
|
|
145
|
+
if (runState.queuedMessageParts.length <= 1) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
const parts = runState.queuedMessageParts.slice(0, -1);
|
|
149
|
+
runState.queuedMessageParts = runState.queuedMessageParts.slice(-1);
|
|
150
|
+
return parts;
|
|
151
|
+
}
|
|
152
|
+
function resolveRunFlushTarget(runState) {
|
|
153
|
+
const binding = resolveSiderSessionBinding(runState.sessionKey);
|
|
154
|
+
const account = binding?.account;
|
|
155
|
+
const sessionId = (runState.sessionId ?? binding?.sessionId)?.trim();
|
|
156
|
+
const accountId = (runState.accountId ?? binding?.account.accountId)?.trim();
|
|
157
|
+
if (!account || !sessionId || !accountId) {
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
runState.sessionId = sessionId;
|
|
161
|
+
runState.accountId = accountId;
|
|
162
|
+
return { account, sessionId, accountId };
|
|
163
|
+
}
|
|
164
|
+
async function flushQueuedPartsExceptTailBestEffort(params) {
|
|
165
|
+
while (true) {
|
|
166
|
+
const runState = resolveSiderRunState(params.runId);
|
|
167
|
+
if (!runState) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const target = resolveRunFlushTarget(runState);
|
|
171
|
+
if (!target) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const parts = takeQueuedPartsExceptTail(runState);
|
|
175
|
+
if (parts.length === 0) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
touchRunState(runState);
|
|
179
|
+
for (const part of parts) {
|
|
180
|
+
const latestRunState = resolveSiderRunState(params.runId);
|
|
181
|
+
if (!latestRunState) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
await sendSiderMessageBestEffort({
|
|
185
|
+
account: target.account,
|
|
186
|
+
sessionId: target.sessionId,
|
|
187
|
+
parts: [part],
|
|
188
|
+
aggregation: nextAggregationForRun(latestRunState, false),
|
|
189
|
+
meta: buildBaseMessageMetaForRun({
|
|
190
|
+
accountId: target.accountId,
|
|
191
|
+
runState: latestRunState
|
|
192
|
+
}),
|
|
193
|
+
context: params.context
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function getOrCreateSiderRunState(runId) {
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
const existing = siderRunStates.get(runId);
|
|
201
|
+
if (existing) {
|
|
202
|
+
existing.updatedAt = now;
|
|
203
|
+
pruneSiderRunStates(now);
|
|
204
|
+
return existing;
|
|
205
|
+
}
|
|
206
|
+
const created = {
|
|
207
|
+
runId,
|
|
208
|
+
aggregationId: crypto.randomUUID(),
|
|
209
|
+
nextAggregationIndex: 0,
|
|
210
|
+
usage: {},
|
|
211
|
+
queuedMessageParts: [],
|
|
212
|
+
messageFlushChain: Promise.resolve(),
|
|
213
|
+
flushScheduled: false,
|
|
214
|
+
updatedAt: now
|
|
215
|
+
};
|
|
216
|
+
siderRunStates.set(runId, created);
|
|
217
|
+
pruneSiderRunStates(now);
|
|
218
|
+
return created;
|
|
219
|
+
}
|
|
220
|
+
function resolveSiderRunState(runId) {
|
|
221
|
+
if (!runId) {
|
|
222
|
+
return void 0;
|
|
223
|
+
}
|
|
224
|
+
const state = siderRunStates.get(runId);
|
|
225
|
+
if (!state) {
|
|
226
|
+
return void 0;
|
|
227
|
+
}
|
|
228
|
+
touchRunState(state);
|
|
229
|
+
return state;
|
|
230
|
+
}
|
|
231
|
+
function discardSiderRunState(runId) {
|
|
232
|
+
if (!runId) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
siderRunStates.delete(runId);
|
|
236
|
+
}
|
|
237
|
+
function updateSiderRunStateContext(params) {
|
|
238
|
+
const runState = getOrCreateSiderRunState(params.runId);
|
|
239
|
+
runState.sessionKey = normalizeSessionBindingKey(params.sessionKey) ?? runState.sessionKey;
|
|
240
|
+
if (params.sessionId?.trim()) {
|
|
241
|
+
runState.sessionId = params.sessionId.trim();
|
|
242
|
+
}
|
|
243
|
+
if (params.accountId?.trim()) {
|
|
244
|
+
runState.accountId = params.accountId.trim();
|
|
245
|
+
}
|
|
246
|
+
if (typeof params.provider === "string" && params.provider.trim()) {
|
|
247
|
+
runState.provider = params.provider.trim();
|
|
248
|
+
}
|
|
249
|
+
if (typeof params.model === "string" && params.model.trim()) {
|
|
250
|
+
runState.model = params.model.trim();
|
|
251
|
+
}
|
|
252
|
+
touchRunState(runState);
|
|
253
|
+
return runState;
|
|
254
|
+
}
|
|
255
|
+
function resolveRelayCallIdForToolEvent(params) {
|
|
256
|
+
if (params.toolCallId) {
|
|
257
|
+
const existing = params.binding.callIdByToolCallId.get(params.toolCallId);
|
|
258
|
+
if (existing) {
|
|
259
|
+
params.binding.currentToolCallId = existing;
|
|
260
|
+
return existing;
|
|
261
|
+
}
|
|
262
|
+
const created = crypto.randomUUID();
|
|
263
|
+
params.binding.callIdByToolCallId.set(params.toolCallId, created);
|
|
264
|
+
params.binding.currentToolCallId = created;
|
|
265
|
+
return created;
|
|
266
|
+
}
|
|
267
|
+
if (params.phase === "start" || !params.binding.currentToolCallId) {
|
|
268
|
+
params.binding.currentToolCallId = crypto.randomUUID();
|
|
269
|
+
}
|
|
270
|
+
return params.binding.currentToolCallId;
|
|
271
|
+
}
|
|
272
|
+
function clearRelayCallIdForToolEvent(params) {
|
|
273
|
+
if (params.toolCallId) {
|
|
274
|
+
params.binding.callIdByToolCallId.delete(params.toolCallId);
|
|
275
|
+
}
|
|
276
|
+
if (params.binding.currentToolCallId === params.callId) {
|
|
277
|
+
params.binding.currentToolCallId = void 0;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function hasTextParts(parts) {
|
|
281
|
+
return parts.some((part) => parseTextFromPart(part) !== null);
|
|
282
|
+
}
|
|
283
|
+
function enqueueCompletedParts(params) {
|
|
284
|
+
if (!params.runId || params.parts.length === 0) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const runState = updateSiderRunStateContext({
|
|
288
|
+
runId: params.runId,
|
|
289
|
+
sessionKey: params.sessionKey,
|
|
290
|
+
sessionId: params.sessionId,
|
|
291
|
+
accountId: params.accountId,
|
|
292
|
+
provider: params.provider,
|
|
293
|
+
model: params.model
|
|
294
|
+
});
|
|
295
|
+
runState.queuedMessageParts.push(...params.parts);
|
|
296
|
+
touchRunState(runState);
|
|
297
|
+
}
|
|
298
|
+
function resolvePendingFinalTextForRun(runId) {
|
|
299
|
+
return resolveSiderRunState(runId)?.pendingFinalText?.trim() ?? "";
|
|
300
|
+
}
|
|
301
|
+
function buildPendingMessageContextForRun(params) {
|
|
302
|
+
const runState = resolveSiderRunState(params.runId);
|
|
303
|
+
const parts = [];
|
|
304
|
+
if (params.includeFinalThinking && runState?.pendingFinalThinking) {
|
|
305
|
+
parts.push(buildThinkingPart(runState.pendingFinalThinking));
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
parts,
|
|
309
|
+
meta: runState ? buildMessageMeta({
|
|
310
|
+
accountId: params.accountId,
|
|
311
|
+
runState,
|
|
312
|
+
stopReason: params.includeFinalThinking ? runState.pendingFinalStopReason : void 0
|
|
313
|
+
}) : void 0,
|
|
314
|
+
runId: runState?.runId,
|
|
315
|
+
stopReason: params.includeFinalThinking ? runState?.pendingFinalStopReason : void 0
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function consumePendingMessageContextForRun(params) {
|
|
319
|
+
const runState = resolveSiderRunState(params.runId);
|
|
320
|
+
if (!runState || !params.consumeFinalThinking) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
runState.pendingFinalText = void 0;
|
|
324
|
+
runState.pendingFinalThinking = void 0;
|
|
325
|
+
runState.pendingFinalStopReason = void 0;
|
|
326
|
+
touchRunState(runState);
|
|
327
|
+
}
|
|
328
|
+
function scheduleQueuedPartFlush(params) {
|
|
329
|
+
const runState = resolveSiderRunState(params.runId);
|
|
330
|
+
if (!runState) {
|
|
331
|
+
return Promise.resolve();
|
|
332
|
+
}
|
|
333
|
+
if (runState.flushScheduled) {
|
|
334
|
+
return runState.messageFlushChain;
|
|
335
|
+
}
|
|
336
|
+
runState.flushScheduled = true;
|
|
337
|
+
return appendRunFlushTask(runState, async () => {
|
|
338
|
+
try {
|
|
339
|
+
await flushQueuedPartsExceptTailBestEffort({
|
|
340
|
+
runId: runState.runId,
|
|
341
|
+
context: params.context
|
|
342
|
+
});
|
|
343
|
+
} finally {
|
|
344
|
+
const latestRunState = resolveSiderRunState(runState.runId);
|
|
345
|
+
if (latestRunState) {
|
|
346
|
+
latestRunState.flushScheduled = false;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
function flushQueuedPartsExceptTailForRun(params) {
|
|
352
|
+
const runState = resolveSiderRunState(params.runId);
|
|
353
|
+
if (!runState) {
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
}
|
|
356
|
+
return appendRunFlushTask(runState, async () => {
|
|
357
|
+
const parts = takeQueuedPartsExceptTail(runState);
|
|
358
|
+
if (parts.length === 0) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
touchRunState(runState);
|
|
362
|
+
for (const part of parts) {
|
|
363
|
+
const latestRunState = resolveSiderRunState(runState.runId);
|
|
364
|
+
if (!latestRunState) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
await sendMessageToSider({
|
|
368
|
+
account: params.account,
|
|
369
|
+
sessionId: params.sessionId,
|
|
370
|
+
parts: [part],
|
|
371
|
+
aggregation: nextAggregationForRun(latestRunState, false),
|
|
372
|
+
meta: buildBaseMessageMetaForRun({
|
|
373
|
+
accountId: params.account.accountId,
|
|
374
|
+
runState: latestRunState
|
|
375
|
+
})
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
function flushFinalQueuedPartForRun(params) {
|
|
381
|
+
const runState = resolveSiderRunState(params.runId);
|
|
382
|
+
if (!runState) {
|
|
383
|
+
return Promise.resolve(false);
|
|
384
|
+
}
|
|
385
|
+
return appendRunFlushTask(runState, async () => {
|
|
386
|
+
const earlyParts = takeQueuedPartsExceptTail(runState);
|
|
387
|
+
for (const part of earlyParts) {
|
|
388
|
+
const latestRunState2 = resolveSiderRunState(runState.runId);
|
|
389
|
+
if (!latestRunState2) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
await sendMessageToSider({
|
|
393
|
+
account: params.account,
|
|
394
|
+
sessionId: params.sessionId,
|
|
395
|
+
parts: [part],
|
|
396
|
+
aggregation: nextAggregationForRun(latestRunState2, false),
|
|
397
|
+
meta: buildBaseMessageMetaForRun({
|
|
398
|
+
accountId: params.account.accountId,
|
|
399
|
+
runState: latestRunState2
|
|
400
|
+
})
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
const latestRunState = resolveSiderRunState(runState.runId);
|
|
404
|
+
if (!latestRunState) {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
const finalPart = latestRunState.queuedMessageParts.shift();
|
|
408
|
+
if (!finalPart) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
latestRunState.queuedMessageParts = [];
|
|
412
|
+
await sendMessageToSider({
|
|
413
|
+
account: params.account,
|
|
414
|
+
sessionId: params.sessionId,
|
|
415
|
+
parts: [finalPart],
|
|
416
|
+
aggregation: nextAggregationForRun(latestRunState, true),
|
|
417
|
+
meta: buildMessageMeta({
|
|
418
|
+
accountId: params.account.accountId,
|
|
419
|
+
runState: latestRunState,
|
|
420
|
+
stopReason: params.stopReason
|
|
421
|
+
})
|
|
422
|
+
});
|
|
423
|
+
touchRunState(latestRunState);
|
|
424
|
+
return true;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
function dropQueuedTailOnAbort(runId) {
|
|
428
|
+
const runState = resolveSiderRunState(runId);
|
|
429
|
+
if (!runState) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
runState.queuedMessageParts = [];
|
|
433
|
+
runState.flushScheduled = false;
|
|
434
|
+
touchRunState(runState);
|
|
435
|
+
}
|
|
436
|
+
function clearBindingRunId(sessionKey, runId) {
|
|
437
|
+
if (!sessionKey || !runId) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const binding = resolveSiderSessionBinding(sessionKey);
|
|
441
|
+
if (!binding) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
if (binding.currentRunId === runId) {
|
|
445
|
+
binding.currentRunId = void 0;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
export {
|
|
449
|
+
buildPendingMessageContextForRun,
|
|
450
|
+
clearBindingRunId,
|
|
451
|
+
clearRelayCallIdForToolEvent,
|
|
452
|
+
consumePendingMessageContextForRun,
|
|
453
|
+
discardSiderRunState,
|
|
454
|
+
dropQueuedTailOnAbort,
|
|
455
|
+
enqueueCompletedParts,
|
|
456
|
+
flushFinalQueuedPartForRun,
|
|
457
|
+
flushQueuedPartsExceptTailForRun,
|
|
458
|
+
getOrCreateSiderRunState,
|
|
459
|
+
hasTextParts,
|
|
460
|
+
normalizeSessionBindingKey,
|
|
461
|
+
pruneSiderRunStates,
|
|
462
|
+
pruneSiderSessionBindings,
|
|
463
|
+
rememberSiderSessionBinding,
|
|
464
|
+
resolvePendingFinalTextForRun,
|
|
465
|
+
resolveRelayCallIdForToolEvent,
|
|
466
|
+
resolveSiderBindingByTarget,
|
|
467
|
+
resolveSiderRunState,
|
|
468
|
+
resolveSiderSessionBinding,
|
|
469
|
+
scheduleQueuedPartFlush,
|
|
470
|
+
updateSiderRunStateContext
|
|
471
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { SiderStreamState, SiderPart, SiderRealtimeLaneState } from './channel-types.js';
|
|
2
|
+
import { ResolvedSiderAccount } from './account.js';
|
|
3
|
+
import { ReplyPayload } from 'openclaw/plugin-sdk';
|
|
4
|
+
import 'ws';
|
|
5
|
+
import 'openclaw/plugin-sdk/setup';
|
|
6
|
+
import './auth.js';
|
|
7
|
+
import 'openclaw/plugin-sdk/plugin-entry';
|
|
8
|
+
import './auto-title.js';
|
|
9
|
+
|
|
10
|
+
declare function cleanupSiderRunAfterReply(params: {
|
|
11
|
+
streamState: SiderStreamState;
|
|
12
|
+
runId?: string;
|
|
13
|
+
resetFallbackText?: boolean;
|
|
14
|
+
}): void;
|
|
15
|
+
declare function openStreamingSessionIfNeeded(params: {
|
|
16
|
+
account: ResolvedSiderAccount;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
laneState: SiderRealtimeLaneState;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
declare function openReasoningSessionIfNeeded(params: {
|
|
21
|
+
account: ResolvedSiderAccount;
|
|
22
|
+
sessionId: string;
|
|
23
|
+
laneState: SiderRealtimeLaneState;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
declare function sendStreamingDeltaEvent(params: {
|
|
26
|
+
account: ResolvedSiderAccount;
|
|
27
|
+
sessionId: string;
|
|
28
|
+
streamState: SiderStreamState;
|
|
29
|
+
delta: string;
|
|
30
|
+
text: string;
|
|
31
|
+
context: string;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
declare function sendReasoningDeltaEvent(params: {
|
|
34
|
+
account: ResolvedSiderAccount;
|
|
35
|
+
sessionId: string;
|
|
36
|
+
streamState: SiderStreamState;
|
|
37
|
+
delta: string;
|
|
38
|
+
text: string;
|
|
39
|
+
context: string;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
declare function closeStreamingSessionIfActive(params: {
|
|
42
|
+
account: ResolvedSiderAccount;
|
|
43
|
+
sessionId: string;
|
|
44
|
+
streamState: SiderStreamState;
|
|
45
|
+
reason: "final" | "interrupted";
|
|
46
|
+
context: string;
|
|
47
|
+
}): Promise<void>;
|
|
48
|
+
declare function closeReasoningSessionIfActive(params: {
|
|
49
|
+
account: ResolvedSiderAccount;
|
|
50
|
+
sessionId: string;
|
|
51
|
+
streamState: SiderStreamState;
|
|
52
|
+
reason: "final" | "interrupted";
|
|
53
|
+
context: string;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
declare function enqueueStreamEventTask(params: {
|
|
56
|
+
streamState: SiderStreamState;
|
|
57
|
+
task: () => Promise<void>;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
declare function flushStreamEventQueue(streamState: SiderStreamState): Promise<void>;
|
|
60
|
+
declare function derivePartialDelta(params: {
|
|
61
|
+
previous: string;
|
|
62
|
+
next: string;
|
|
63
|
+
}): string;
|
|
64
|
+
declare function mergeBlockTextIntoStreamState(params: {
|
|
65
|
+
streamState: SiderStreamState;
|
|
66
|
+
text: string;
|
|
67
|
+
}): void;
|
|
68
|
+
declare function resolveCurrentStreamVisibleText(streamState: SiderStreamState): string;
|
|
69
|
+
declare function resolveFallbackFinalText(streamState: SiderStreamState): string;
|
|
70
|
+
declare function commitCurrentStreamTextToFallbackPrefix(streamState: SiderStreamState): void;
|
|
71
|
+
declare function rotateAssistantMessageFallbackState(streamState: SiderStreamState): void;
|
|
72
|
+
declare function resetCurrentStreamTextState(streamState: SiderStreamState): void;
|
|
73
|
+
declare function resetAllFallbackTextState(streamState: SiderStreamState): void;
|
|
74
|
+
declare function resetReasoningStreamState(streamState: SiderStreamState): void;
|
|
75
|
+
declare function handleStreamingPartialSnapshot(params: {
|
|
76
|
+
account: ResolvedSiderAccount;
|
|
77
|
+
sessionId: string;
|
|
78
|
+
streamState: SiderStreamState;
|
|
79
|
+
snapshot: string;
|
|
80
|
+
}): Promise<void>;
|
|
81
|
+
declare function handleReasoningSnapshot(params: {
|
|
82
|
+
account: ResolvedSiderAccount;
|
|
83
|
+
sessionId: string;
|
|
84
|
+
streamState: SiderStreamState;
|
|
85
|
+
snapshot: string;
|
|
86
|
+
}): Promise<void>;
|
|
87
|
+
declare function finalizeQueuedRunMessages(params: {
|
|
88
|
+
account: ResolvedSiderAccount;
|
|
89
|
+
sessionId: string;
|
|
90
|
+
streamState: SiderStreamState;
|
|
91
|
+
parts: SiderPart[];
|
|
92
|
+
stopReason?: string;
|
|
93
|
+
context: string;
|
|
94
|
+
}): Promise<boolean>;
|
|
95
|
+
declare function deliverReplyPayloadToSider(params: {
|
|
96
|
+
account: ResolvedSiderAccount;
|
|
97
|
+
sessionId: string;
|
|
98
|
+
streamState: SiderStreamState;
|
|
99
|
+
payload: ReplyPayload;
|
|
100
|
+
kind: "tool" | "block" | "final";
|
|
101
|
+
mediaLocalRoots?: readonly string[];
|
|
102
|
+
}): Promise<void>;
|
|
103
|
+
declare function persistDeferredFinalReplyPayloadToSider(params: {
|
|
104
|
+
account: ResolvedSiderAccount;
|
|
105
|
+
sessionId: string;
|
|
106
|
+
streamState: SiderStreamState;
|
|
107
|
+
payload: ReplyPayload;
|
|
108
|
+
mediaLocalRoots?: readonly string[];
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
declare function persistStandaloneReplyPayloadToSider(params: {
|
|
111
|
+
account: ResolvedSiderAccount;
|
|
112
|
+
sessionId: string;
|
|
113
|
+
payload: ReplyPayload;
|
|
114
|
+
mediaLocalRoots?: readonly string[];
|
|
115
|
+
}): Promise<void>;
|
|
116
|
+
|
|
117
|
+
export { cleanupSiderRunAfterReply, closeReasoningSessionIfActive, closeStreamingSessionIfActive, commitCurrentStreamTextToFallbackPrefix, deliverReplyPayloadToSider, derivePartialDelta, enqueueStreamEventTask, finalizeQueuedRunMessages, flushStreamEventQueue, handleReasoningSnapshot, handleStreamingPartialSnapshot, mergeBlockTextIntoStreamState, openReasoningSessionIfNeeded, openStreamingSessionIfNeeded, persistDeferredFinalReplyPayloadToSider, persistStandaloneReplyPayloadToSider, resetAllFallbackTextState, resetCurrentStreamTextState, resetReasoningStreamState, resolveCurrentStreamVisibleText, resolveFallbackFinalText, rotateAssistantMessageFallbackState, sendReasoningDeltaEvent, sendStreamingDeltaEvent };
|