@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,604 @@
1
+ import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
2
+ import { formatAuthorizationHeader, resolveSiderApiUrl } from "./auth.js";
3
+ import {
4
+ DEFAULT_MEDIA_SAVE_MAX_BYTES,
5
+ DEFAULT_STRUCTURED_PAYLOAD_MAX_CHARS
6
+ } from "./channel-types.js";
7
+ import { getSiderRuntime } from "./channel-runtime.js";
8
+ import { SIDER_CHANNEL_ID } from "./config.js";
9
+ import { SIDER_PLUGIN_VERSION, SIDER_USER_AGENT } from "./user-agent.js";
10
+ function hasFiniteNumber(value) {
11
+ return typeof value === "number" && Number.isFinite(value);
12
+ }
13
+ function addUsageTotals(target, next) {
14
+ if (!next) {
15
+ return;
16
+ }
17
+ for (const field of ["input", "output", "cacheRead", "cacheWrite", "total"]) {
18
+ const value = next[field];
19
+ if (typeof value === "number" && Number.isFinite(value)) {
20
+ target[field] = (target[field] ?? 0) + value;
21
+ }
22
+ }
23
+ }
24
+ function hasUsageTotals(usage) {
25
+ if (!usage) {
26
+ return false;
27
+ }
28
+ return hasFiniteNumber(usage.input) || hasFiniteNumber(usage.output) || hasFiniteNumber(usage.cacheRead) || hasFiniteNumber(usage.cacheWrite) || hasFiniteNumber(usage.total);
29
+ }
30
+ function firstUsageCount(...values) {
31
+ for (const v of values) {
32
+ if (typeof v === "number" && Number.isFinite(v)) {
33
+ return Math.max(0, v);
34
+ }
35
+ }
36
+ return void 0;
37
+ }
38
+ function toJsonSafeValue(value) {
39
+ if (value === void 0) {
40
+ return void 0;
41
+ }
42
+ try {
43
+ return JSON.parse(JSON.stringify(value));
44
+ } catch {
45
+ return String(value);
46
+ }
47
+ }
48
+ function clipText(text, maxChars = DEFAULT_STRUCTURED_PAYLOAD_MAX_CHARS) {
49
+ if (text.length <= maxChars) {
50
+ return text;
51
+ }
52
+ return `${text.slice(0, maxChars)}...`;
53
+ }
54
+ function appendStructuredPayloadField(payload, fieldName, value, maxChars = DEFAULT_STRUCTURED_PAYLOAD_MAX_CHARS) {
55
+ const safeValue = toJsonSafeValue(value);
56
+ if (safeValue === void 0) {
57
+ return;
58
+ }
59
+ let serialized = "";
60
+ try {
61
+ serialized = JSON.stringify(safeValue);
62
+ } catch {
63
+ serialized = String(safeValue);
64
+ }
65
+ if (!serialized) {
66
+ return;
67
+ }
68
+ if (serialized.length <= maxChars) {
69
+ payload[fieldName] = safeValue;
70
+ return;
71
+ }
72
+ payload[`${fieldName}_preview`] = clipText(serialized, maxChars);
73
+ payload[`${fieldName}_truncated`] = true;
74
+ }
75
+ function extractToolResultText(result) {
76
+ const record = toRecord(result);
77
+ const fromPartRecord = (part) => {
78
+ const candidateKeys = ["text", "content", "message", "output", "stdout"];
79
+ for (const key of candidateKeys) {
80
+ const value = part[key];
81
+ if (typeof value === "string" && value.trim()) {
82
+ return clipText(value.trim(), 4e3);
83
+ }
84
+ }
85
+ const nestedText = typeof part.text === "string" ? part.text : typeof part.value === "string" ? part.value : typeof part.output_text === "string" ? part.output_text : void 0;
86
+ if (nestedText?.trim()) {
87
+ return clipText(nestedText.trim(), 4e3);
88
+ }
89
+ return "";
90
+ };
91
+ const fromContentArray = (value) => {
92
+ if (!Array.isArray(value)) {
93
+ return "";
94
+ }
95
+ const chunks = [];
96
+ for (const item of value) {
97
+ if (typeof item === "string" && item.trim()) {
98
+ chunks.push(item.trim());
99
+ continue;
100
+ }
101
+ const part = toRecord(item);
102
+ if (!part) {
103
+ continue;
104
+ }
105
+ const text = fromPartRecord(part);
106
+ if (text) {
107
+ chunks.push(text);
108
+ }
109
+ }
110
+ return chunks.length > 0 ? clipText(chunks.join("\n\n"), 4e3) : "";
111
+ };
112
+ if (!record) {
113
+ return fromContentArray(result);
114
+ }
115
+ const direct = fromPartRecord(record);
116
+ if (direct) {
117
+ return direct;
118
+ }
119
+ const contentText = fromContentArray(record.content) || fromContentArray(record.message) || fromContentArray(record.output);
120
+ if (contentText) {
121
+ return contentText;
122
+ }
123
+ return "";
124
+ }
125
+ function collectMediaUrlStrings(value, sink, seen) {
126
+ if (!value) {
127
+ return;
128
+ }
129
+ if (typeof value === "string") {
130
+ const trimmed = value.trim();
131
+ if (trimmed && !seen.has(trimmed)) {
132
+ seen.add(trimmed);
133
+ sink.push(trimmed);
134
+ }
135
+ return;
136
+ }
137
+ if (Array.isArray(value)) {
138
+ for (const item of value) {
139
+ collectMediaUrlStrings(item, sink, seen);
140
+ }
141
+ }
142
+ }
143
+ function extractToolResultMediaUrls(result) {
144
+ const visited = [];
145
+ const seen = /* @__PURE__ */ new Set();
146
+ const record = toRecord(result);
147
+ if (!record) {
148
+ return visited;
149
+ }
150
+ const pools = [record];
151
+ const detailsCandidate = toRecord(record.details);
152
+ if (detailsCandidate) {
153
+ pools.push(detailsCandidate);
154
+ }
155
+ for (const pool of pools) {
156
+ const entry = pool;
157
+ collectMediaUrlStrings(entry.source, visited, seen);
158
+ collectMediaUrlStrings(entry.source_url, visited, seen);
159
+ collectMediaUrlStrings(entry.sourceUrl, visited, seen);
160
+ collectMediaUrlStrings(entry.source_path, visited, seen);
161
+ collectMediaUrlStrings(entry.sourcePath, visited, seen);
162
+ collectMediaUrlStrings(entry.download_url, visited, seen);
163
+ collectMediaUrlStrings(entry.downloadUrl, visited, seen);
164
+ collectMediaUrlStrings(entry.path, visited, seen);
165
+ const files = entry.files;
166
+ if (Array.isArray(files)) {
167
+ for (const file of files) {
168
+ const fileRecord = toRecord(file);
169
+ if (!fileRecord) {
170
+ continue;
171
+ }
172
+ collectMediaUrlStrings(fileRecord.source, visited, seen);
173
+ collectMediaUrlStrings(fileRecord.source_url, visited, seen);
174
+ collectMediaUrlStrings(fileRecord.sourceUrl, visited, seen);
175
+ collectMediaUrlStrings(fileRecord.source_path, visited, seen);
176
+ collectMediaUrlStrings(fileRecord.sourcePath, visited, seen);
177
+ collectMediaUrlStrings(fileRecord.download_url, visited, seen);
178
+ collectMediaUrlStrings(fileRecord.downloadUrl, visited, seen);
179
+ collectMediaUrlStrings(fileRecord.path, visited, seen);
180
+ }
181
+ }
182
+ }
183
+ return visited;
184
+ }
185
+ function toRecord(value) {
186
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
187
+ return null;
188
+ }
189
+ return value;
190
+ }
191
+ function getSocketCloseInfo(closeInfo) {
192
+ if (!closeInfo || typeof closeInfo !== "object") {
193
+ return {};
194
+ }
195
+ return {
196
+ code: typeof closeInfo.code === "number" ? closeInfo.code : void 0,
197
+ reason: typeof closeInfo.reason === "string" ? closeInfo.reason : Buffer.isBuffer(closeInfo.reason) ? closeInfo.reason.toString("utf8") : void 0,
198
+ wasClean: typeof closeInfo.wasClean === "boolean" ? closeInfo.wasClean : void 0
199
+ };
200
+ }
201
+ function describeSocketClose(closeInfo) {
202
+ const { code, reason, wasClean } = getSocketCloseInfo(closeInfo);
203
+ const parts = [];
204
+ if (typeof code === "number") {
205
+ parts.push(`code=${code}`);
206
+ }
207
+ if (typeof reason === "string" && reason) {
208
+ parts.push(`reason=${reason}`);
209
+ }
210
+ if (typeof wasClean === "boolean") {
211
+ parts.push(`clean=${wasClean}`);
212
+ }
213
+ return parts.length > 0 ? ` (${parts.join(", ")})` : "";
214
+ }
215
+ function decodeBase64AttachmentBuffer(raw) {
216
+ const normalized = raw.trim();
217
+ if (!normalized) {
218
+ throw new Error("sider sendAttachment requires non-empty buffer");
219
+ }
220
+ const buffer = Buffer.from(normalized, "base64");
221
+ if (buffer.length === 0) {
222
+ throw new Error("sider sendAttachment requires valid non-empty base64 buffer");
223
+ }
224
+ return buffer;
225
+ }
226
+ async function updateSiderSessionTitle(params) {
227
+ const sessionId = params.sessionId.trim();
228
+ if (!sessionId) {
229
+ throw new Error("sider updateSessionTitle requires non-empty sessionId");
230
+ }
231
+ const title = params.title.trim();
232
+ if (!title) {
233
+ throw new Error("sider updateSessionTitle requires non-empty title");
234
+ }
235
+ const url = resolveSiderApiUrl(`/v1/sessions/${encodeURIComponent(sessionId)}`);
236
+ const response = await fetch(url, {
237
+ method: "PATCH",
238
+ headers: {
239
+ Authorization: formatAuthorizationHeader(params.authorization),
240
+ "Content-Type": "application/json",
241
+ "User-Agent": SIDER_USER_AGENT
242
+ },
243
+ body: JSON.stringify({ title })
244
+ });
245
+ if (!response.ok) {
246
+ let detail = "";
247
+ try {
248
+ const text = (await response.text()).trim();
249
+ if (text) {
250
+ detail = `: ${text}`;
251
+ }
252
+ } catch {
253
+ }
254
+ throw new Error(
255
+ `sider updateSessionTitle failed (${response.status} ${response.statusText})${detail}`
256
+ );
257
+ }
258
+ }
259
+ async function persistInlineAttachmentBuffer(params) {
260
+ const configuredMaxBytes = resolveChannelMediaMaxBytes({
261
+ cfg: params.cfg,
262
+ accountId: params.accountId,
263
+ resolveChannelLimitMb: () => void 0
264
+ });
265
+ const maxBytes = Math.max(
266
+ params.buffer.length,
267
+ configuredMaxBytes ?? 0,
268
+ DEFAULT_MEDIA_SAVE_MAX_BYTES
269
+ );
270
+ return await getSiderRuntime().channel.media.saveMediaBuffer(
271
+ params.buffer,
272
+ params.contentType,
273
+ "outbound",
274
+ maxBytes,
275
+ params.fileName
276
+ );
277
+ }
278
+ function parseTextFromPart(part) {
279
+ if (part.type !== "core.text") {
280
+ return null;
281
+ }
282
+ const payload = toRecord(part.payload);
283
+ if (payload?.text && typeof payload.text === "string") {
284
+ const text = payload.text.trim();
285
+ return text || null;
286
+ }
287
+ if (typeof part.payload === "string") {
288
+ const text = part.payload.trim();
289
+ return text || null;
290
+ }
291
+ return null;
292
+ }
293
+ function collectTextPartValues(parts) {
294
+ const seen = /* @__PURE__ */ new Set();
295
+ for (const part of parts) {
296
+ const text = parseTextFromPart(part);
297
+ if (text) {
298
+ seen.add(text);
299
+ }
300
+ }
301
+ return seen;
302
+ }
303
+ function filterDuplicateTextParts(params) {
304
+ const seenTexts = params.seenTexts ?? /* @__PURE__ */ new Set();
305
+ const duplicateTexts = [];
306
+ const parts = [];
307
+ for (const part of params.parts) {
308
+ const text = parseTextFromPart(part);
309
+ if (!text) {
310
+ parts.push(part);
311
+ continue;
312
+ }
313
+ if (seenTexts.has(text)) {
314
+ duplicateTexts.push(text);
315
+ continue;
316
+ }
317
+ seenTexts.add(text);
318
+ parts.push(part);
319
+ }
320
+ return {
321
+ parts,
322
+ duplicateTexts,
323
+ seenTexts
324
+ };
325
+ }
326
+ function parseMediaFromPart(part) {
327
+ if (part.type !== "core.media" && part.type !== "core.file") {
328
+ return null;
329
+ }
330
+ const payload = toRecord(part.payload);
331
+ if (!payload) {
332
+ return null;
333
+ }
334
+ const readString = (value) => {
335
+ if (typeof value !== "string") {
336
+ return void 0;
337
+ }
338
+ const trimmed = value.trim();
339
+ return trimmed || void 0;
340
+ };
341
+ const url = readString(payload.download_url) ?? readString(payload.downloadUrl) ?? readString(payload.url) ?? readString(payload.resource_url) ?? readString(payload.resourceUrl) ?? readString(payload.media_url) ?? readString(payload.mediaUrl);
342
+ const objectKey = readString(payload.object_key) ?? readString(payload.objectKey);
343
+ const fileId = readString(payload.file_id) ?? readString(payload.fileId);
344
+ if (!url && !objectKey && !fileId) {
345
+ return null;
346
+ }
347
+ const mimeType = readString(payload.mime) ?? readString(payload.mime_type) ?? readString(payload.mimeType) ?? readString(payload.content_type) ?? readString(payload.contentType);
348
+ const fileName = readString(payload.name) ?? readString(payload.file_name) ?? readString(payload.fileName);
349
+ return {
350
+ ...url ? { url } : {},
351
+ ...objectKey ? { objectKey } : {},
352
+ ...fileId ? { fileId } : {},
353
+ ...mimeType ? { mimeType } : {},
354
+ ...fileName ? { fileName } : {}
355
+ };
356
+ }
357
+ function describeInboundMediaReference(item) {
358
+ if (item.url?.trim()) {
359
+ return item.url.trim();
360
+ }
361
+ if (item.objectKey?.trim()) {
362
+ return `sider-object-key:${item.objectKey.trim()}`;
363
+ }
364
+ if (item.fileId?.trim()) {
365
+ return `sider-file-id:${item.fileId.trim()}`;
366
+ }
367
+ return void 0;
368
+ }
369
+ function buildEventMeta(params) {
370
+ return {
371
+ channel: SIDER_CHANNEL_ID,
372
+ account_id: params.accountId,
373
+ plugin_version: SIDER_PLUGIN_VERSION,
374
+ schema_version: 1
375
+ };
376
+ }
377
+ function formatUsageForMessageMeta(usage) {
378
+ if (!hasUsageTotals(usage)) {
379
+ return void 0;
380
+ }
381
+ const result = {};
382
+ if (usage.input !== void 0) result.input = usage.input;
383
+ if (usage.output !== void 0) result.output = usage.output;
384
+ if (usage.cacheRead !== void 0) result.cache_read = usage.cacheRead;
385
+ if (usage.cacheWrite !== void 0) result.cache_write = usage.cacheWrite;
386
+ if (usage.total !== void 0) result.total = usage.total;
387
+ return result;
388
+ }
389
+ function parseUsageTotals(value) {
390
+ const record = toRecord(value);
391
+ if (!record) {
392
+ return void 0;
393
+ }
394
+ const cacheDetails = toRecord(record.prompt_tokens_details) ?? toRecord(record.promptTokensDetails);
395
+ const input = firstUsageCount(record.input, record.input_tokens, record.inputTokens);
396
+ const output = firstUsageCount(record.output, record.output_tokens, record.outputTokens);
397
+ const cacheRead = firstUsageCount(
398
+ record.cacheRead,
399
+ record.cache_read,
400
+ record.cache_read_input_tokens,
401
+ cacheDetails?.cached_tokens
402
+ );
403
+ const cacheWrite = firstUsageCount(
404
+ record.cacheWrite,
405
+ record.cache_write,
406
+ record.cache_creation_input_tokens
407
+ );
408
+ const total = firstUsageCount(record.total, record.total_tokens, record.totalTokens);
409
+ const usage = {};
410
+ if (input !== void 0) usage.input = input;
411
+ if (output !== void 0) usage.output = output;
412
+ if (cacheRead !== void 0) usage.cacheRead = cacheRead;
413
+ if (cacheWrite !== void 0) usage.cacheWrite = cacheWrite;
414
+ if (total !== void 0) {
415
+ usage.total = total;
416
+ } else if (hasUsageTotals(usage)) {
417
+ usage.total = (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
418
+ }
419
+ return hasUsageTotals(usage) ? usage : void 0;
420
+ }
421
+ function choosePreferredUsageTotals(...candidates) {
422
+ return candidates.find((c) => c && hasUsageTotals(c));
423
+ }
424
+ function parseUsageFromAssistantLike(value) {
425
+ const record = toRecord(value);
426
+ if (!record) {
427
+ return void 0;
428
+ }
429
+ const meta = toRecord(record.meta);
430
+ const agentMeta = toRecord(meta?.agentMeta) ?? toRecord(meta?.agent_meta) ?? toRecord(record.agentMeta) ?? toRecord(record.agent_meta);
431
+ return choosePreferredUsageTotals(
432
+ parseUsageTotals(record.usage),
433
+ parseUsageTotals(meta?.usage),
434
+ parseUsageTotals(meta?.lastCallUsage),
435
+ parseUsageTotals(meta?.last_call_usage),
436
+ parseUsageTotals(agentMeta?.usage),
437
+ parseUsageTotals(agentMeta?.lastCallUsage),
438
+ parseUsageTotals(agentMeta?.last_call_usage)
439
+ );
440
+ }
441
+ function buildMessageMeta(params) {
442
+ const meta = buildEventMeta({ accountId: params.accountId });
443
+ if (params.runState?.runId) {
444
+ meta.run_id = params.runState.runId;
445
+ }
446
+ if (params.runState?.provider) {
447
+ meta.provider = params.runState.provider;
448
+ }
449
+ if (params.runState?.model) {
450
+ meta.model = params.runState.model;
451
+ }
452
+ if (params.stopReason) {
453
+ meta.stop_reason = params.stopReason;
454
+ }
455
+ const usage = formatUsageForMessageMeta(params.runState?.usage);
456
+ if (usage) {
457
+ meta.usage = usage;
458
+ }
459
+ return meta;
460
+ }
461
+ function isAbortedAssistantStopReason(stopReason) {
462
+ return stopReason?.trim().toLowerCase() === "aborted";
463
+ }
464
+ function parseAssistantOutput(lastAssistant) {
465
+ const assistant = toRecord(lastAssistant);
466
+ if (!assistant) {
467
+ return null;
468
+ }
469
+ const content = Array.isArray(assistant.content) ? assistant.content : [];
470
+ const thinkingChunks = [];
471
+ const toolCalls = [];
472
+ const seenToolCalls = /* @__PURE__ */ new Set();
473
+ const pushToolCall = (candidate) => {
474
+ const dedupeKey = `${candidate.toolCallId?.trim() || ""}::${candidate.toolName?.trim() || ""}`;
475
+ if (seenToolCalls.has(dedupeKey)) {
476
+ return;
477
+ }
478
+ seenToolCalls.add(dedupeKey);
479
+ toolCalls.push({
480
+ toolName: candidate.toolName?.trim() || void 0,
481
+ toolCallId: candidate.toolCallId?.trim() || void 0,
482
+ toolArgs: candidate.toolArgs
483
+ });
484
+ };
485
+ for (const item of content) {
486
+ const part = toRecord(item);
487
+ if (!part) {
488
+ continue;
489
+ }
490
+ const partType = typeof part.type === "string" ? part.type.trim() : "";
491
+ if (partType === "thinking" || partType === "reasoning" || partType === "reasoning_text") {
492
+ const thinking = typeof part.thinking === "string" ? part.thinking.trim() : "";
493
+ const fallbackText = typeof part.text === "string" ? part.text.trim() : "";
494
+ const resolvedThinking = thinking || fallbackText;
495
+ if (resolvedThinking) {
496
+ thinkingChunks.push(resolvedThinking);
497
+ }
498
+ continue;
499
+ }
500
+ if (partType !== "toolCall" && partType !== "toolUse" && partType !== "tool_call" && partType !== "tool_use" && partType !== "tool-call" && partType !== "tool-use" && partType !== "functionCall" && partType !== "function_call" && partType !== "function-call" && partType !== "output_tool_call") {
501
+ continue;
502
+ }
503
+ const fn = toRecord(part.function);
504
+ const toolName = typeof part.toolName === "string" ? part.toolName.trim() : typeof part.name === "string" ? part.name.trim() : typeof fn?.name === "string" ? fn.name.trim() : "";
505
+ const toolCallId = typeof part.toolCallId === "string" ? part.toolCallId.trim() : typeof part.toolUseId === "string" ? part.toolUseId.trim() : typeof part.callId === "string" ? part.callId.trim() : typeof part.id === "string" ? part.id.trim() : void 0;
506
+ const rawArguments = typeof fn?.arguments === "string" ? (() => {
507
+ try {
508
+ return JSON.parse(fn.arguments);
509
+ } catch {
510
+ return fn.arguments;
511
+ }
512
+ })() : fn?.arguments;
513
+ pushToolCall({
514
+ toolName: toolName || void 0,
515
+ toolCallId: toolCallId || void 0,
516
+ toolArgs: rawArguments ?? part.arguments ?? part.input ?? part.args ?? part.parameters
517
+ });
518
+ }
519
+ const topLevelToolCalls = Array.isArray(assistant.tool_calls) ? assistant.tool_calls : [];
520
+ for (const item of topLevelToolCalls) {
521
+ const part = toRecord(item);
522
+ if (!part) {
523
+ continue;
524
+ }
525
+ const fn = toRecord(part.function);
526
+ const rawArguments = typeof fn?.arguments === "string" ? (() => {
527
+ try {
528
+ return JSON.parse(fn.arguments);
529
+ } catch {
530
+ return fn.arguments;
531
+ }
532
+ })() : fn?.arguments;
533
+ pushToolCall({
534
+ toolName: typeof fn?.name === "string" ? fn.name : typeof part.toolName === "string" ? part.toolName : void 0,
535
+ toolCallId: typeof part.id === "string" ? part.id : typeof part.toolCallId === "string" ? part.toolCallId : typeof part.toolUseId === "string" ? part.toolUseId : void 0,
536
+ toolArgs: rawArguments ?? part.arguments ?? part.input ?? part.args ?? part.parameters
537
+ });
538
+ }
539
+ const stopReason = typeof assistant.stopReason === "string" ? assistant.stopReason.trim() : "";
540
+ const fallbackThinking = typeof assistant.reasoning_content === "string" ? assistant.reasoning_content.trim() : "";
541
+ return {
542
+ stopReason: stopReason || void 0,
543
+ thinkingText: thinkingChunks.join("\n\n").trim() || fallbackThinking || void 0,
544
+ toolCalls
545
+ };
546
+ }
547
+ function mergeTextSegments(previous, next) {
548
+ if (!next) {
549
+ return previous;
550
+ }
551
+ if (!previous) {
552
+ return next;
553
+ }
554
+ if (next === previous) {
555
+ return previous;
556
+ }
557
+ if (next.startsWith(previous)) {
558
+ return next;
559
+ }
560
+ if (previous.startsWith(next) || previous.includes(next)) {
561
+ return previous;
562
+ }
563
+ if (next.includes(previous)) {
564
+ return next;
565
+ }
566
+ const maxOverlap = Math.min(previous.length, next.length);
567
+ for (let overlap = maxOverlap; overlap > 0; overlap -= 1) {
568
+ if (previous.endsWith(next.slice(0, overlap))) {
569
+ return previous + next.slice(overlap);
570
+ }
571
+ }
572
+ return previous + next;
573
+ }
574
+ export {
575
+ addUsageTotals,
576
+ appendStructuredPayloadField,
577
+ buildEventMeta,
578
+ buildMessageMeta,
579
+ choosePreferredUsageTotals,
580
+ clipText,
581
+ collectTextPartValues,
582
+ decodeBase64AttachmentBuffer,
583
+ describeInboundMediaReference,
584
+ describeSocketClose,
585
+ extractToolResultMediaUrls,
586
+ extractToolResultText,
587
+ filterDuplicateTextParts,
588
+ firstUsageCount,
589
+ formatUsageForMessageMeta,
590
+ getSocketCloseInfo,
591
+ hasFiniteNumber,
592
+ hasUsageTotals,
593
+ isAbortedAssistantStopReason,
594
+ mergeTextSegments,
595
+ parseAssistantOutput,
596
+ parseMediaFromPart,
597
+ parseTextFromPart,
598
+ parseUsageFromAssistantLike,
599
+ parseUsageTotals,
600
+ persistInlineAttachmentBuffer,
601
+ toJsonSafeValue,
602
+ toRecord,
603
+ updateSiderSessionTitle
604
+ };
@@ -0,0 +1,14 @@
1
+ import { ChannelPlugin } from 'openclaw/plugin-sdk';
2
+ import { R as ResolvedSiderAccount } from '../account-cW9SLuNu.js';
3
+ export { setSiderRuntime } from './channel-runtime.js';
4
+ export { emitSiderToolHookEvent, recordSiderAgentEnd, recordSiderLlmOutputUsage, recordSiderPersistedAgentMessage } from './channel-hooks.js';
5
+ import 'openclaw/plugin-sdk/setup';
6
+ import './auth.js';
7
+ import 'openclaw/plugin-sdk/plugin-entry';
8
+ import 'openclaw/plugin-sdk/config-runtime';
9
+ import 'ws';
10
+ import './channel-types.js';
11
+
12
+ declare const siderPlugin: ChannelPlugin<ResolvedSiderAccount>;
13
+
14
+ export { siderPlugin };