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.
Files changed (58) hide show
  1. package/README.md +11 -1
  2. package/README.zh_CN.md +8 -6
  3. package/dist/index.d.ts +12 -0
  4. package/{index.ts → dist/index.js} +24 -17
  5. package/dist/setup-entry.d.ts +18 -0
  6. package/dist/setup-entry.js +8 -0
  7. package/dist/src/account.d.ts +54 -0
  8. package/{src/account.ts → dist/src/account.js} +70 -160
  9. package/dist/src/auth.d.ts +30 -0
  10. package/{src/auth.ts → dist/src/auth.js} +61 -128
  11. package/dist/src/auto-title.d.ts +20 -0
  12. package/dist/src/auto-title.js +22 -0
  13. package/dist/src/channel-auto-title.d.ts +23 -0
  14. package/dist/src/channel-auto-title.js +77 -0
  15. package/dist/src/channel-builders.d.ts +105 -0
  16. package/dist/src/channel-builders.js +238 -0
  17. package/dist/src/channel-hooks.d.ts +30 -0
  18. package/dist/src/channel-hooks.js +331 -0
  19. package/dist/src/channel-monitor.d.ts +34 -0
  20. package/dist/src/channel-monitor.js +341 -0
  21. package/dist/src/channel-relay.d.ts +117 -0
  22. package/dist/src/channel-relay.js +573 -0
  23. package/dist/src/channel-runtime.d.ts +32 -0
  24. package/dist/src/channel-runtime.js +85 -0
  25. package/dist/src/channel-send-result.d.ts +19 -0
  26. package/dist/src/channel-send-result.js +126 -0
  27. package/dist/src/channel-session-model.d.ts +19 -0
  28. package/dist/src/channel-session-model.js +244 -0
  29. package/dist/src/channel-state.d.ts +92 -0
  30. package/dist/src/channel-state.js +471 -0
  31. package/dist/src/channel-streaming.d.ts +117 -0
  32. package/dist/src/channel-streaming.js +645 -0
  33. package/dist/src/channel-types.d.ts +207 -0
  34. package/dist/src/channel-types.js +40 -0
  35. package/dist/src/channel-typing.d.ts +17 -0
  36. package/dist/src/channel-typing.js +79 -0
  37. package/dist/src/channel-util.d.ts +78 -0
  38. package/dist/src/channel-util.js +524 -0
  39. package/dist/src/channel.d.ts +14 -0
  40. package/dist/src/channel.js +1023 -0
  41. package/dist/src/config.d.ts +18 -0
  42. package/dist/src/config.js +38 -0
  43. package/dist/src/inbound-media.d.ts +37 -0
  44. package/{src/inbound-media.ts → dist/src/inbound-media.js} +33 -81
  45. package/dist/src/media-upload.d.ts +86 -0
  46. package/dist/src/media-upload.js +1222 -0
  47. package/dist/src/setup-core.d.ts +72 -0
  48. package/{src/setup-core.ts → dist/src/setup-core.js} +106 -194
  49. package/dist/src/user-agent.d.ts +4 -0
  50. package/dist/src/user-agent.js +6 -0
  51. package/openclaw.plugin.json +86 -0
  52. package/package.json +9 -13
  53. package/setup-entry.ts +0 -6
  54. package/src/channel.ts +0 -3862
  55. package/src/config.ts +0 -29
  56. package/src/media-upload.ts +0 -983
  57. package/src/remote-browser-support.ts +0 -64
  58. package/src/user-agent.ts +0 -17
@@ -0,0 +1,238 @@
1
+ import {
2
+ hasFiniteNumber,
3
+ appendStructuredPayloadField,
4
+ extractToolResultMediaUrls,
5
+ extractToolResultText,
6
+ buildEventMeta,
7
+ toJsonSafeValue
8
+ } from "./channel-util.js";
9
+ const SOURCE_PATH_PREFIX_RE = /^(\/|\.\/|\.\.\/|~\/|[A-Za-z]:[\\/]|\\\\)/;
10
+ const SOURCE_SCHEME_RE = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
11
+ function isPathLikeSource(value) {
12
+ const trimmed = value.trim();
13
+ if (!trimmed) {
14
+ return false;
15
+ }
16
+ return SOURCE_PATH_PREFIX_RE.test(trimmed) || !SOURCE_SCHEME_RE.test(trimmed);
17
+ }
18
+ function buildSourceFields(source) {
19
+ const trimmed = source?.trim();
20
+ if (!trimmed) {
21
+ return {};
22
+ }
23
+ return {
24
+ media_url: trimmed,
25
+ ...isPathLikeSource(trimmed) ? { source_path: trimmed } : { source_url: trimmed }
26
+ };
27
+ }
28
+ function buildThinkingPart(text) {
29
+ return {
30
+ type: "thinking",
31
+ spec_version: 1,
32
+ payload: { text }
33
+ };
34
+ }
35
+ function buildTextPart(text) {
36
+ return {
37
+ type: "core.text",
38
+ spec_version: 1,
39
+ payload: { text }
40
+ };
41
+ }
42
+ function buildToolCallPart(params) {
43
+ const payload = {
44
+ call_id: params.callId,
45
+ ...params.toolName ? { tool_name: params.toolName } : {},
46
+ ...params.toolCallId ? { tool_call_id: params.toolCallId } : {},
47
+ ...params.runId ? { run_id: params.runId } : {}
48
+ };
49
+ appendStructuredPayloadField(payload, "tool_args", params.toolArgs);
50
+ return {
51
+ type: "tool.call",
52
+ spec_version: 1,
53
+ payload
54
+ };
55
+ }
56
+ function buildToolResultPart(params) {
57
+ const text = extractToolResultText(params.result);
58
+ const safeToolArgs = toJsonSafeValue(params.toolArgs);
59
+ const safeResult = toJsonSafeValue(params.result);
60
+ const payload = {
61
+ call_id: params.callId,
62
+ ...params.toolName ? { tool_name: params.toolName } : {},
63
+ ...params.toolCallId ? { tool_call_id: params.toolCallId } : {},
64
+ ...params.runId ? { run_id: params.runId } : {},
65
+ ...params.error ? { error: params.error } : {},
66
+ ...hasFiniteNumber(params.durationMs) ? { duration_ms: params.durationMs } : {},
67
+ ...text ? { text } : {},
68
+ ...safeToolArgs !== void 0 ? { tool_args: safeToolArgs } : {},
69
+ ...safeResult !== void 0 ? { result: safeResult } : {},
70
+ has_text: text.length > 0,
71
+ is_error: Boolean(params.error)
72
+ };
73
+ return {
74
+ type: "tool.result",
75
+ spec_version: 1,
76
+ payload
77
+ };
78
+ }
79
+ function buildTypingEvent(params) {
80
+ return {
81
+ eventType: "typing",
82
+ payload: {
83
+ on: params.state === "typing",
84
+ state: params.state,
85
+ session_id: params.sessionId,
86
+ ts: Date.now()
87
+ },
88
+ meta: buildEventMeta({ accountId: params.accountId })
89
+ };
90
+ }
91
+ function buildStreamingStartEvent(params) {
92
+ return {
93
+ eventType: "stream.start",
94
+ payload: {
95
+ session_id: params.sessionId,
96
+ stream_id: params.streamId,
97
+ ts: Date.now()
98
+ },
99
+ meta: buildEventMeta({ accountId: params.accountId })
100
+ };
101
+ }
102
+ function buildStreamingDeltaEvent(params) {
103
+ return {
104
+ eventType: "stream.delta",
105
+ payload: {
106
+ session_id: params.sessionId,
107
+ stream_id: params.streamId,
108
+ seq: params.seq,
109
+ delta: params.delta,
110
+ text: params.text,
111
+ done: false,
112
+ chunk_chars: params.delta.length,
113
+ ts: Date.now()
114
+ },
115
+ meta: buildEventMeta({ accountId: params.accountId })
116
+ };
117
+ }
118
+ function buildStreamingDoneEvent(params) {
119
+ return {
120
+ eventType: "stream.done",
121
+ payload: {
122
+ session_id: params.sessionId,
123
+ stream_id: params.streamId,
124
+ seq: params.seq,
125
+ done: true,
126
+ reason: params.reason,
127
+ ts: Date.now()
128
+ },
129
+ meta: buildEventMeta({ accountId: params.accountId })
130
+ };
131
+ }
132
+ function buildReasoningStartEvent(params) {
133
+ return {
134
+ eventType: "reasoning.start",
135
+ payload: {
136
+ session_id: params.sessionId,
137
+ stream_id: params.streamId,
138
+ ts: Date.now()
139
+ },
140
+ meta: buildEventMeta({ accountId: params.accountId })
141
+ };
142
+ }
143
+ function buildReasoningDeltaEvent(params) {
144
+ return {
145
+ eventType: "reasoning.delta",
146
+ payload: {
147
+ session_id: params.sessionId,
148
+ stream_id: params.streamId,
149
+ seq: params.seq,
150
+ delta: params.delta,
151
+ text: params.text,
152
+ done: false,
153
+ chunk_chars: params.delta.length,
154
+ ts: Date.now()
155
+ },
156
+ meta: buildEventMeta({ accountId: params.accountId })
157
+ };
158
+ }
159
+ function buildReasoningDoneEvent(params) {
160
+ return {
161
+ eventType: "reasoning.done",
162
+ payload: {
163
+ session_id: params.sessionId,
164
+ stream_id: params.streamId,
165
+ seq: params.seq,
166
+ done: true,
167
+ reason: params.reason,
168
+ ts: Date.now()
169
+ },
170
+ meta: buildEventMeta({ accountId: params.accountId })
171
+ };
172
+ }
173
+ function buildToolCallEvent(params) {
174
+ return {
175
+ eventType: "tool.call",
176
+ payload: {
177
+ session_id: params.sessionId,
178
+ seq: params.seq,
179
+ call_id: params.callId,
180
+ phase: params.phase,
181
+ tool_name: params.toolName,
182
+ tool_call_id: params.toolCallId,
183
+ run_id: params.runId,
184
+ session_key: params.sessionKey,
185
+ tool_args: params.toolArgs,
186
+ error: params.error,
187
+ duration_ms: params.durationMs,
188
+ ts: Date.now()
189
+ },
190
+ meta: buildEventMeta({ accountId: params.accountId })
191
+ };
192
+ }
193
+ function buildToolResultEvent(params) {
194
+ const text = extractToolResultText(params.result);
195
+ const mediaUrls = extractToolResultMediaUrls(params.result);
196
+ const safeResult = toJsonSafeValue(params.result);
197
+ const safeToolArgs = toJsonSafeValue(params.toolArgs);
198
+ return {
199
+ eventType: "tool.result",
200
+ payload: {
201
+ session_id: params.sessionId,
202
+ seq: params.seq,
203
+ call_id: params.callId,
204
+ tool_name: params.toolName,
205
+ tool_call_id: params.toolCallId,
206
+ run_id: params.runId,
207
+ session_key: params.sessionKey,
208
+ tool_args: safeToolArgs,
209
+ result: safeResult,
210
+ error: params.error,
211
+ duration_ms: params.durationMs,
212
+ text,
213
+ has_text: text.trim().length > 0,
214
+ media_urls: mediaUrls,
215
+ media_count: mediaUrls.length,
216
+ is_error: Boolean(params.error),
217
+ ts: Date.now()
218
+ },
219
+ meta: buildEventMeta({ accountId: params.accountId })
220
+ };
221
+ }
222
+ export {
223
+ buildReasoningDeltaEvent,
224
+ buildReasoningDoneEvent,
225
+ buildReasoningStartEvent,
226
+ buildSourceFields,
227
+ buildStreamingDeltaEvent,
228
+ buildStreamingDoneEvent,
229
+ buildStreamingStartEvent,
230
+ buildTextPart,
231
+ buildThinkingPart,
232
+ buildToolCallEvent,
233
+ buildToolCallPart,
234
+ buildToolResultEvent,
235
+ buildToolResultPart,
236
+ buildTypingEvent,
237
+ isPathLikeSource
238
+ };
@@ -0,0 +1,30 @@
1
+ import { SiderToolHookPayload } from './channel-types.js';
2
+ import 'openclaw/plugin-sdk';
3
+ import './account.js';
4
+ import 'openclaw/plugin-sdk/setup';
5
+ import './auth.js';
6
+ import 'openclaw/plugin-sdk/plugin-entry';
7
+ import './auto-title.js';
8
+ import 'ws';
9
+
10
+ declare function recordSiderPersistedAgentMessage(params: {
11
+ sessionKey?: string;
12
+ message: unknown;
13
+ }): void;
14
+ declare function recordSiderAgentEnd(params: {
15
+ messages?: unknown[];
16
+ error?: string;
17
+ runId?: string;
18
+ success: boolean;
19
+ }): void;
20
+ declare function recordSiderLlmOutputUsage(params: {
21
+ sessionKey?: string;
22
+ runId?: string;
23
+ provider?: string;
24
+ model?: string;
25
+ usage?: unknown;
26
+ lastAssistant?: unknown;
27
+ }): void;
28
+ declare function emitSiderToolHookEvent(params: SiderToolHookPayload): Promise<void>;
29
+
30
+ export { emitSiderToolHookEvent, recordSiderAgentEnd, recordSiderLlmOutputUsage, recordSiderPersistedAgentMessage };
@@ -0,0 +1,331 @@
1
+ import { extractAssistantText } from "openclaw/plugin-sdk/agent-runtime";
2
+ import {
3
+ buildTextPart,
4
+ buildThinkingPart,
5
+ buildToolCallEvent,
6
+ buildToolCallPart,
7
+ buildToolResultEvent,
8
+ buildToolResultPart
9
+ } from "./channel-builders.js";
10
+ import { sendSiderEventBestEffort } from "./channel-relay.js";
11
+ import { logDebug, logWarn } from "./channel-runtime.js";
12
+ import {
13
+ clearRelayCallIdForToolEvent,
14
+ enqueueCompletedParts,
15
+ normalizeSessionBindingKey,
16
+ resolveRelayCallIdForToolEvent,
17
+ resolveSiderRunState,
18
+ resolveSiderSessionBinding,
19
+ scheduleQueuedPartFlush,
20
+ updateSiderRunStateContext
21
+ } from "./channel-state.js";
22
+ import {
23
+ addUsageTotals,
24
+ choosePreferredUsageTotals,
25
+ hasUsageTotals,
26
+ parseAssistantOutput,
27
+ parseUsageFromAssistantLike,
28
+ parseUsageTotals,
29
+ toRecord
30
+ } from "./channel-util.js";
31
+ function recordSiderPersistedAgentMessage(params) {
32
+ const binding = resolveSiderSessionBinding(params.sessionKey);
33
+ const runId = binding?.currentRunId;
34
+ if (!runId) {
35
+ return;
36
+ }
37
+ const message = toRecord(params.message);
38
+ if (!message) {
39
+ return;
40
+ }
41
+ const role = typeof message.role === "string" ? message.role.trim() : "";
42
+ if (role !== "assistant") {
43
+ return;
44
+ }
45
+ const runState = updateSiderRunStateContext({
46
+ runId,
47
+ sessionKey: params.sessionKey,
48
+ sessionId: binding?.sessionId,
49
+ accountId: binding?.account.accountId,
50
+ provider: typeof message.provider === "string" ? message.provider : void 0,
51
+ model: typeof message.model === "string" ? message.model : void 0
52
+ });
53
+ const directUsage = parseUsageTotals(message.usage);
54
+ if (directUsage && hasUsageTotals(directUsage)) {
55
+ addUsageTotals(runState.usage, directUsage);
56
+ } else if (!hasUsageTotals(runState.usage)) {
57
+ const fallbackUsage = parseUsageFromAssistantLike(message);
58
+ if (fallbackUsage && hasUsageTotals(fallbackUsage)) {
59
+ runState.usage = fallbackUsage;
60
+ }
61
+ }
62
+ const parsed = parseAssistantOutput(message);
63
+ if (!parsed) {
64
+ return;
65
+ }
66
+ const assistantText = extractAssistantText(message).trim() || void 0;
67
+ const stopReason = parsed.stopReason?.trim();
68
+ const stopReasonLower = stopReason?.toLowerCase();
69
+ const shouldTreatAsToolUseMessage = stopReasonLower === "tooluse" || parsed.toolCalls.length > 0 && stopReasonLower !== "error" && stopReasonLower !== "aborted" && !assistantText;
70
+ if (shouldTreatAsToolUseMessage) {
71
+ const parts = [];
72
+ if (parsed.thinkingText) {
73
+ parts.push(buildThinkingPart(parsed.thinkingText));
74
+ }
75
+ if (assistantText) {
76
+ parts.push(buildTextPart(assistantText));
77
+ }
78
+ if (binding) {
79
+ for (const toolCall of parsed.toolCalls) {
80
+ const callId = resolveRelayCallIdForToolEvent({
81
+ binding,
82
+ phase: "start",
83
+ toolCallId: toolCall.toolCallId
84
+ });
85
+ parts.push(
86
+ buildToolCallPart({
87
+ callId,
88
+ toolName: toolCall.toolName,
89
+ toolCallId: toolCall.toolCallId,
90
+ runId,
91
+ toolArgs: toolCall.toolArgs
92
+ })
93
+ );
94
+ }
95
+ }
96
+ enqueueCompletedParts({
97
+ runId,
98
+ parts,
99
+ sessionKey: params.sessionKey,
100
+ sessionId: binding?.sessionId,
101
+ accountId: binding?.account.accountId,
102
+ provider: runState.provider,
103
+ model: runState.model
104
+ });
105
+ void scheduleQueuedPartFlush({
106
+ runId,
107
+ context: "before_message_write.tool_use"
108
+ });
109
+ return;
110
+ }
111
+ if (parsed.toolCalls.length > 0) {
112
+ logDebug("treat assistant message with tool calls as final sider message", {
113
+ runId,
114
+ sessionKey: params.sessionKey,
115
+ stopReason: parsed.stopReason,
116
+ textLength: assistantText?.length ?? 0,
117
+ toolCallCount: parsed.toolCalls.length
118
+ });
119
+ }
120
+ runState.pendingFinalText = assistantText;
121
+ runState.pendingFinalThinking = parsed.thinkingText;
122
+ runState.pendingFinalStopReason = parsed.stopReason;
123
+ }
124
+ function recordSiderAgentEnd(params) {
125
+ if (params.success || !params.runId) {
126
+ return;
127
+ }
128
+ logDebug("observed unsuccessful agent_end; final sider message remains enabled", {
129
+ runId: params.runId,
130
+ error: params.error?.trim() || void 0,
131
+ messageCount: params.messages?.length ?? 0
132
+ });
133
+ }
134
+ function recordSiderLlmOutputUsage(params) {
135
+ const binding = resolveSiderSessionBinding(params.sessionKey);
136
+ const runId = params.runId || binding?.currentRunId;
137
+ if (!runId) {
138
+ return;
139
+ }
140
+ const existingRunState = resolveSiderRunState(runId);
141
+ if (!existingRunState && binding?.currentRunId !== runId) {
142
+ logDebug("skip llm_output sider usage update: run already cleaned up", {
143
+ runId,
144
+ sessionKey: params.sessionKey,
145
+ provider: params.provider,
146
+ model: params.model
147
+ });
148
+ return;
149
+ }
150
+ const runState = existingRunState ?? updateSiderRunStateContext({
151
+ runId,
152
+ sessionKey: params.sessionKey,
153
+ sessionId: binding?.sessionId,
154
+ accountId: binding?.account.accountId
155
+ });
156
+ updateSiderRunStateContext({
157
+ runId,
158
+ sessionKey: params.sessionKey,
159
+ sessionId: binding?.sessionId,
160
+ accountId: binding?.account.accountId,
161
+ provider: params.provider,
162
+ model: params.model
163
+ });
164
+ const parsed = choosePreferredUsageTotals(
165
+ parseUsageTotals(params.usage),
166
+ parseUsageFromAssistantLike(params.lastAssistant)
167
+ );
168
+ if (parsed && hasUsageTotals(parsed)) {
169
+ runState.usage = parsed;
170
+ }
171
+ }
172
+ async function emitSiderToolHookEvent(params) {
173
+ const binding = resolveSiderSessionBinding(params.sessionKey);
174
+ if (!binding) {
175
+ logDebug("skip sider tool hook event: session binding not found", {
176
+ sessionKey: params.sessionKey,
177
+ toolName: params.toolName,
178
+ toolCallId: params.toolCallId,
179
+ phase: params.phase
180
+ });
181
+ return;
182
+ }
183
+ if (params.runId) {
184
+ binding.currentRunId = params.runId;
185
+ }
186
+ const normalizedToolName = (params.toolName ?? "").trim().toLowerCase();
187
+ const toolArgs = toRecord(params.params);
188
+ const currentSessionKey = normalizeSessionBindingKey(params.sessionKey);
189
+ const targetSessionKeyRaw = typeof toolArgs?.sessionKey === "string" ? toolArgs.sessionKey : void 0;
190
+ const targetSessionKey = normalizeSessionBindingKey(targetSessionKeyRaw);
191
+ const hasAttachmentLikeArgs = Boolean(
192
+ toolArgs && [
193
+ "attachments",
194
+ "attachment",
195
+ "media",
196
+ "mediaUrl",
197
+ "mediaUrls",
198
+ "file",
199
+ "files",
200
+ "buffer",
201
+ "content",
202
+ "contentBase64"
203
+ ].some((field) => Object.prototype.hasOwnProperty.call(toolArgs, field))
204
+ );
205
+ if (normalizedToolName === "sessions_send" && params.phase === "start") {
206
+ if (hasAttachmentLikeArgs) {
207
+ logWarn("sider observed sessions_send with attachment-like args; sessions_send only forwards text/message args", {
208
+ accountId: binding.account.accountId,
209
+ sessionId: binding.sessionId,
210
+ runId: params.runId,
211
+ sessionKey: params.sessionKey,
212
+ targetSessionKey: targetSessionKeyRaw,
213
+ toolCallId: params.toolCallId
214
+ });
215
+ }
216
+ if (currentSessionKey && targetSessionKey && currentSessionKey === targetSessionKey) {
217
+ logWarn("sider observed sessions_send targeting current session; this often times out while current run is still active", {
218
+ accountId: binding.account.accountId,
219
+ sessionId: binding.sessionId,
220
+ runId: params.runId,
221
+ sessionKey: params.sessionKey,
222
+ targetSessionKey: targetSessionKeyRaw,
223
+ toolCallId: params.toolCallId
224
+ });
225
+ }
226
+ }
227
+ const callId = resolveRelayCallIdForToolEvent({
228
+ binding,
229
+ phase: params.phase,
230
+ toolCallId: params.toolCallId
231
+ });
232
+ if (params.phase === "start") {
233
+ binding.toolSeq += 1;
234
+ const toolCallEvent = buildToolCallEvent({
235
+ sessionId: binding.sessionId,
236
+ accountId: binding.account.accountId,
237
+ seq: binding.toolSeq,
238
+ callId,
239
+ phase: "start",
240
+ toolName: params.toolName,
241
+ toolCallId: params.toolCallId,
242
+ runId: params.runId,
243
+ sessionKey: params.sessionKey,
244
+ toolArgs: params.params,
245
+ error: params.error,
246
+ durationMs: params.durationMs
247
+ });
248
+ await sendSiderEventBestEffort({
249
+ account: binding.account,
250
+ sessionId: binding.sessionId,
251
+ event: toolCallEvent,
252
+ context: "tool.call.hook.start"
253
+ });
254
+ }
255
+ if (params.phase !== "start") {
256
+ if (normalizedToolName === "sessions_send") {
257
+ const resultRecord = toRecord(params.result);
258
+ const status = typeof resultRecord?.status === "string" ? resultRecord.status.trim().toLowerCase() : "";
259
+ if (status === "timeout") {
260
+ logWarn("sider observed sessions_send timeout", {
261
+ accountId: binding.account.accountId,
262
+ sessionId: binding.sessionId,
263
+ runId: params.runId,
264
+ sessionKey: params.sessionKey,
265
+ targetSessionKey: targetSessionKeyRaw,
266
+ toolCallId: params.toolCallId,
267
+ error: params.error,
268
+ durationMs: params.durationMs,
269
+ selfTargeted: Boolean(currentSessionKey && targetSessionKey && currentSessionKey === targetSessionKey),
270
+ hasAttachmentLikeArgs
271
+ });
272
+ }
273
+ }
274
+ binding.toolSeq += 1;
275
+ const toolResultEvent = buildToolResultEvent({
276
+ sessionId: binding.sessionId,
277
+ accountId: binding.account.accountId,
278
+ seq: binding.toolSeq,
279
+ callId,
280
+ toolName: params.toolName,
281
+ toolCallId: params.toolCallId,
282
+ runId: params.runId,
283
+ sessionKey: params.sessionKey,
284
+ toolArgs: params.params,
285
+ result: params.result,
286
+ error: params.error,
287
+ durationMs: params.durationMs
288
+ });
289
+ await sendSiderEventBestEffort({
290
+ account: binding.account,
291
+ sessionId: binding.sessionId,
292
+ event: toolResultEvent,
293
+ context: `tool.result.hook.${params.phase}`
294
+ });
295
+ if (params.runId) {
296
+ enqueueCompletedParts({
297
+ runId: params.runId,
298
+ parts: [
299
+ buildToolResultPart({
300
+ callId,
301
+ toolName: params.toolName,
302
+ toolCallId: params.toolCallId,
303
+ runId: params.runId,
304
+ toolArgs: params.params,
305
+ result: params.result,
306
+ error: params.error,
307
+ durationMs: params.durationMs
308
+ })
309
+ ],
310
+ sessionKey: params.sessionKey,
311
+ sessionId: binding.sessionId,
312
+ accountId: binding.account.accountId
313
+ });
314
+ void scheduleQueuedPartFlush({
315
+ runId: params.runId,
316
+ context: `tool.result.hook.${params.phase}`
317
+ });
318
+ }
319
+ clearRelayCallIdForToolEvent({
320
+ binding,
321
+ callId,
322
+ toolCallId: params.toolCallId
323
+ });
324
+ }
325
+ }
326
+ export {
327
+ emitSiderToolHookEvent,
328
+ recordSiderAgentEnd,
329
+ recordSiderLlmOutputUsage,
330
+ recordSiderPersistedAgentMessage
331
+ };
@@ -0,0 +1,34 @@
1
+ import { OpenClawConfig } from 'openclaw/plugin-sdk';
2
+ import { ResolvedSiderAccount } from './account.js';
3
+ import { SiderRelayMonitorRegistration, SiderMonitorLogger, SiderInboundRealtimeMessage } from './channel-types.js';
4
+ import 'openclaw/plugin-sdk/setup';
5
+ import './auth.js';
6
+ import 'openclaw/plugin-sdk/plugin-entry';
7
+ import './auto-title.js';
8
+ import 'ws';
9
+
10
+ declare function monitorSiderSession(params: {
11
+ cfg: OpenClawConfig;
12
+ account: ResolvedSiderAccount;
13
+ abortSignal: AbortSignal;
14
+ log?: SiderMonitorLogger;
15
+ onInboundMessage: (params: {
16
+ cfg: OpenClawConfig;
17
+ account: ResolvedSiderAccount;
18
+ event: SiderInboundRealtimeMessage;
19
+ }) => Promise<void>;
20
+ }): Promise<void>;
21
+ declare function launchManagedRelayMonitor(registration: SiderRelayMonitorRegistration): void;
22
+ declare function runManagedSiderRelayMonitor(params: {
23
+ cfg: OpenClawConfig;
24
+ account: ResolvedSiderAccount;
25
+ abortSignal: AbortSignal;
26
+ log?: SiderMonitorLogger;
27
+ onInboundMessage: (params: {
28
+ cfg: OpenClawConfig;
29
+ account: ResolvedSiderAccount;
30
+ event: SiderInboundRealtimeMessage;
31
+ }) => Promise<void>;
32
+ }): Promise<void>;
33
+
34
+ export { launchManagedRelayMonitor, monitorSiderSession, runManagedSiderRelayMonitor };