@efengx/openclaw-channel-dragon 0.5.29 → 0.5.30
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.
|
@@ -125,7 +125,7 @@ export class ChannelComponent {
|
|
|
125
125
|
const current = previous
|
|
126
126
|
.catch(() => { })
|
|
127
127
|
.then(async () => {
|
|
128
|
-
logger?.info?.(`[Dragon Plugin] v${dragonChannelPluginVersion} Sending to OpenClaw: "${content.substring(0, 50)}${content.length > 50 ? '...' : ''}" [WorkbenchSession: ${sessionId}] [OpenClawSessionKey: ${sessionKey}]`);
|
|
128
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] v${dragonChannelPluginVersion} Sending to OpenClaw: "${content.substring(0, 50)}${content.length > 50 ? '...' : ''}" [WorkbenchSession: ${sessionId}] [OpenClawSessionKey: ${sessionKey}]`);
|
|
129
129
|
const progress = (payload) => this.telemetry.reportProgress({
|
|
130
130
|
sessionId,
|
|
131
131
|
msgId: replyMsgId,
|
|
@@ -284,7 +284,7 @@ export class ChannelComponent {
|
|
|
284
284
|
});
|
|
285
285
|
}
|
|
286
286
|
catch (err) {
|
|
287
|
-
logger?.error?.(`[Dragon Plugin] Error during replyDispatcher: ${err?.message || err}`);
|
|
287
|
+
logger?.error?.(`[dragon channels][Dragon Plugin] Error during replyDispatcher: ${err?.message || err}`);
|
|
288
288
|
let resolvedErrorMessage = err?.message || String(err);
|
|
289
289
|
const isTakeoverError = resolvedErrorMessage.includes("session file changed while embedded prompt lock was released");
|
|
290
290
|
if (isTakeoverError) {
|
|
@@ -303,7 +303,7 @@ export class ChannelComponent {
|
|
|
303
303
|
const item = JSON.parse(lines[i]);
|
|
304
304
|
if (item.type === "message" && item.stopReason === "error" && item.errorMessage) {
|
|
305
305
|
resolvedErrorMessage = item.errorMessage;
|
|
306
|
-
logger?.warn?.(`[Dragon Plugin] Extracted real underlying error from session file: ${resolvedErrorMessage}`);
|
|
306
|
+
logger?.warn?.(`[dragon channels][Dragon Plugin] Extracted real underlying error from session file: ${resolvedErrorMessage}`);
|
|
307
307
|
break;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
@@ -314,7 +314,7 @@ export class ChannelComponent {
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
catch (fsErr) {
|
|
317
|
-
logger?.error?.(`[Dragon Plugin] Failed to read real error from session file: ${fsErr}`);
|
|
317
|
+
logger?.error?.(`[dragon channels][Dragon Plugin] Failed to read real error from session file: ${fsErr}`);
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
// Check for insufficient spending cap/quota error and provide a friendly Chinese message
|
|
@@ -355,7 +355,7 @@ export class ChannelComponent {
|
|
|
355
355
|
handleOutboundText = async (ctx) => {
|
|
356
356
|
const text = ctx?.text || "";
|
|
357
357
|
const { logger } = this.options;
|
|
358
|
-
logger?.info?.(`[Dragon Plugin] Outbound Text (Action): "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}"`);
|
|
358
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] Outbound Text (Action): "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}"`);
|
|
359
359
|
await this.telemetry.reportReply({ content: text, sessionId: ctx?.peer?.id || "default", source: "channel_outbound" });
|
|
360
360
|
return { ok: true, messageId: Date.now().toString() };
|
|
361
361
|
};
|
|
@@ -4,7 +4,7 @@ export class HttpComponent {
|
|
|
4
4
|
this.options = options;
|
|
5
5
|
}
|
|
6
6
|
async start() {
|
|
7
|
-
this.options.logger?.info?.(`[Dragon-Channel] HttpComponent started for ${this.options.baseURL}`);
|
|
7
|
+
this.options.logger?.info?.(`[dragon channels][Dragon-Channel] HttpComponent started for ${this.options.baseURL}`);
|
|
8
8
|
}
|
|
9
9
|
async stop() { }
|
|
10
10
|
async fetch(path, init) {
|
|
@@ -20,7 +20,7 @@ export class HttpComponent {
|
|
|
20
20
|
headers
|
|
21
21
|
});
|
|
22
22
|
if (!res.ok && res.status !== 404) {
|
|
23
|
-
this.options.logger?.warn?.(`[Dragon-Channel] HTTP Request failed: ${res.status} ${url}`);
|
|
23
|
+
this.options.logger?.warn?.(`[dragon channels][Dragon-Channel] HTTP Request failed: ${res.status} ${url}`);
|
|
24
24
|
}
|
|
25
25
|
return res;
|
|
26
26
|
}
|
|
@@ -24,7 +24,7 @@ export class SseComponent {
|
|
|
24
24
|
return;
|
|
25
25
|
const { agentId, logger } = this.options;
|
|
26
26
|
const url = `${this.http.options.baseURL}/api/agents/events`;
|
|
27
|
-
logger?.info?.(`[Dragon Plugin] v${this.options.version} connecting to Orchestrator SSE: ${url} (agent=${agentId})`);
|
|
27
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] v${this.options.version} connecting to Orchestrator SSE: ${url} (agent=${agentId})`);
|
|
28
28
|
try {
|
|
29
29
|
// In Node 22, we might need a fetch-based SSE or a library,
|
|
30
30
|
// but for simplicity we'll use the same pattern as Bridge if possible.
|
|
@@ -33,7 +33,7 @@ export class SseComponent {
|
|
|
33
33
|
this.startSseReader(url);
|
|
34
34
|
}
|
|
35
35
|
catch (err) {
|
|
36
|
-
logger?.error?.(`[Dragon Plugin] SSE Init Failed: ${err.message}`);
|
|
36
|
+
logger?.error?.(`[dragon channels][Dragon Plugin] SSE Init Failed: ${err.message}`);
|
|
37
37
|
this.scheduleReconnect();
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -51,7 +51,7 @@ export class SseComponent {
|
|
|
51
51
|
const reader = response.body?.getReader();
|
|
52
52
|
if (!reader)
|
|
53
53
|
throw new Error("Response body is null");
|
|
54
|
-
this.options.logger?.debug?.(`[Dragon Plugin] SSE Stream Established.`);
|
|
54
|
+
this.options.logger?.debug?.(`[dragon channels][Dragon Plugin] SSE Stream Established.`);
|
|
55
55
|
const decoder = new TextDecoder();
|
|
56
56
|
let buffer = "";
|
|
57
57
|
while (this.shouldReconnect) {
|
|
@@ -62,21 +62,24 @@ export class SseComponent {
|
|
|
62
62
|
const lines = buffer.split("\n");
|
|
63
63
|
buffer = lines.pop() || "";
|
|
64
64
|
for (const line of lines) {
|
|
65
|
-
|
|
65
|
+
const cleanLine = line.trim();
|
|
66
|
+
if (cleanLine.startsWith("data: ")) {
|
|
66
67
|
try {
|
|
67
|
-
const data = JSON.parse(
|
|
68
|
+
const data = JSON.parse(cleanLine.slice(6));
|
|
68
69
|
void this.handleEvent(data).catch((err) => {
|
|
69
|
-
this.options.logger?.error?.(`[Dragon Plugin] SSE event handling failed: ${err?.message || err}`);
|
|
70
|
+
this.options.logger?.error?.(`[dragon channels][Dragon Plugin] SSE event handling failed: ${err?.message || err}`);
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
|
-
catch (e) {
|
|
73
|
+
catch (e) {
|
|
74
|
+
this.options.logger?.error?.(`[dragon channels][Dragon Plugin] SSE event JSON parse failed for line: "${cleanLine}", error: ${e?.message || e}`);
|
|
75
|
+
}
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
80
|
catch (err) {
|
|
78
81
|
if (this.shouldReconnect) {
|
|
79
|
-
this.options.logger?.warn?.(`[Dragon Plugin] SSE Stream Disconnected: ${err.message}`);
|
|
82
|
+
this.options.logger?.warn?.(`[dragon channels][Dragon Plugin] SSE Stream Disconnected: ${err.message}`);
|
|
80
83
|
this.scheduleReconnect();
|
|
81
84
|
}
|
|
82
85
|
}
|
|
@@ -89,12 +92,12 @@ export class SseComponent {
|
|
|
89
92
|
// 2. Handle specific types
|
|
90
93
|
if (data.type === 'WORKBENCH_MESSAGE') {
|
|
91
94
|
const { content, sessionId, attachments, id, msgId } = data.payload || {};
|
|
92
|
-
logger?.info?.(`[Dragon Plugin] v${this.options.version} [SSE] Received from Workbench: "${content?.substring(0, 50)}${content?.length > 50 ? '...' : ''}" [Session: ${sessionId}]`);
|
|
95
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] v${this.options.version} [SSE] Received from Workbench: "${content?.substring(0, 50)}${content?.length > 50 ? '...' : ''}" [Session: ${sessionId}]`);
|
|
93
96
|
await this.channel.deliverToOpenClaw(content, sessionId, undefined, attachments, msgId || id);
|
|
94
97
|
}
|
|
95
98
|
else if (data.type === 'FETCH_HISTORY') {
|
|
96
99
|
const { sessionId } = data.payload || {};
|
|
97
|
-
logger?.info?.(`[Dragon Plugin] Triggering history sync for session: ${sessionId}`);
|
|
100
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] Triggering history sync for session: ${sessionId}`);
|
|
98
101
|
// Handle history sync if needed, but deliverToOpenClaw usually handles normal chat
|
|
99
102
|
}
|
|
100
103
|
}
|
package/dist/index.js
CHANGED
|
@@ -28,11 +28,15 @@ async function getOrCreateContainer(account, ctx) {
|
|
|
28
28
|
return containers.get(key);
|
|
29
29
|
const logger = ctx?.logger ?? ctx?.log ?? cachedRuntime?.logger ?? cachedRuntime?.log;
|
|
30
30
|
const container = new ServiceContainer();
|
|
31
|
-
logger?.info?.(`[Dragon Plugin] Starting channel plugin v${dragonChannelPluginVersion} for agent=${account.agentId}, account=${account.accountId}, orchestrator=${account.orchestratorUrl}`);
|
|
31
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] Starting channel plugin v${dragonChannelPluginVersion} for agent=${account.agentId}, account=${account.accountId}, orchestrator=${account.orchestratorUrl}`);
|
|
32
32
|
// 1. Core Infrastructure
|
|
33
33
|
const http = container.register('http', new HttpComponent({
|
|
34
34
|
baseURL: account.orchestratorUrl,
|
|
35
|
-
authToken: account.orchestratorAuthToken ||
|
|
35
|
+
authToken: account.orchestratorAuthToken ||
|
|
36
|
+
process.env.DRAGON_ORCHESTRATOR_AUTH_TOKEN ||
|
|
37
|
+
process.env.DRAGON_GATEWAY_TOKEN ||
|
|
38
|
+
process.env.GATEWAY_TOKEN ||
|
|
39
|
+
process.env.OPENCLAW_GATEWAY_AUTH_TOKEN,
|
|
36
40
|
logger
|
|
37
41
|
}));
|
|
38
42
|
const telemetry = container.register('telemetry', new TelemetryComponent(http, account.agentId));
|
|
@@ -160,20 +164,20 @@ const plugin = createChatChannelPlugin({
|
|
|
160
164
|
handleAction: async (ctx) => {
|
|
161
165
|
const { action, params, cfg, accountId } = ctx;
|
|
162
166
|
const logger = ctx?.logger ?? ctx?.log ?? cachedRuntime?.logger ?? cachedRuntime?.log;
|
|
163
|
-
logger?.info?.(`[Dragon Plugin] handleAction start: action=${action}, accountId=${accountId}, paramsKeys=${Object.keys(params || {})}`);
|
|
167
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction start: action=${action}, accountId=${accountId}, paramsKeys=${Object.keys(params || {})}`);
|
|
164
168
|
if (action === "send") {
|
|
165
169
|
const account = base.config.resolveAccount(cfg, accountId);
|
|
166
170
|
const container = await getOrCreateContainer(account, ctx);
|
|
167
171
|
const channel = container.get('channel');
|
|
168
172
|
let target = params.to || params.target || ctx.toolContext?.currentChannelId || "default";
|
|
169
|
-
logger?.info?.(`[Dragon Plugin] handleAction target resolution input: ${target}`);
|
|
173
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction target resolution input: ${target}`);
|
|
170
174
|
for (const prefix of ["dragon-workbench-", "dragon-workbench:", "dragon-", "dragon:"]) {
|
|
171
175
|
if (target.startsWith(prefix)) {
|
|
172
176
|
target = target.substring(prefix.length);
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
179
|
const sessionId = target || "default";
|
|
176
|
-
logger?.info?.(`[Dragon Plugin] handleAction target resolved: sessionId=${sessionId}, rawTarget=${target}`);
|
|
180
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction target resolved: sessionId=${sessionId}, rawTarget=${target}`);
|
|
177
181
|
// Collect ALL media URLs from the params (mirrors what OpenClaw tracks internally
|
|
178
182
|
// via collectMessagingMediaUrlsFromRecord when the tool call starts, so that
|
|
179
183
|
// hasGatewayAgentDeliveredExpectedMedia can match them against expectedMediaUrls).
|
|
@@ -182,7 +186,7 @@ const plugin = createChatChannelPlugin({
|
|
|
182
186
|
if (typeof v === 'string' && v.trim()) {
|
|
183
187
|
const url = v.trim();
|
|
184
188
|
sentMediaUrls.push(url);
|
|
185
|
-
logger?.info?.(`[Dragon Plugin] handleAction extracted media URL from ${source}: ${url}`);
|
|
189
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction extracted media URL from ${source}: ${url}`);
|
|
186
190
|
}
|
|
187
191
|
};
|
|
188
192
|
pushMedia(params.media, "params.media");
|
|
@@ -191,12 +195,12 @@ const plugin = createChatChannelPlugin({
|
|
|
191
195
|
pushMedia(params.filePath, "params.filePath");
|
|
192
196
|
pushMedia(params.fileUrl, "params.fileUrl");
|
|
193
197
|
if (Array.isArray(params.mediaUrls)) {
|
|
194
|
-
logger?.info?.(`[Dragon Plugin] handleAction found params.mediaUrls array, size=${params.mediaUrls.length}`);
|
|
198
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction found params.mediaUrls array, size=${params.mediaUrls.length}`);
|
|
195
199
|
for (const u of params.mediaUrls)
|
|
196
200
|
pushMedia(u, "params.mediaUrls");
|
|
197
201
|
}
|
|
198
202
|
if (Array.isArray(params.attachments)) {
|
|
199
|
-
logger?.info?.(`[Dragon Plugin] handleAction found params.attachments array, size=${params.attachments.length}`);
|
|
203
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction found params.attachments array, size=${params.attachments.length}`);
|
|
200
204
|
for (const a of params.attachments) {
|
|
201
205
|
if (a && typeof a === 'object') {
|
|
202
206
|
pushMedia(a.media, "attachment.media");
|
|
@@ -207,9 +211,9 @@ const plugin = createChatChannelPlugin({
|
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
|
-
logger?.info?.(`[Dragon Plugin] handleAction total media URLs extracted: count=${sentMediaUrls.length}, urls=${JSON.stringify(sentMediaUrls)}`);
|
|
214
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction total media URLs extracted: count=${sentMediaUrls.length}, urls=${JSON.stringify(sentMediaUrls)}`);
|
|
211
215
|
let text = params.message || params.text || "";
|
|
212
|
-
logger?.info?.(`[Dragon Plugin] handleAction base message text length: ${text.length}`);
|
|
216
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction base message text length: ${text.length}`);
|
|
213
217
|
// Append media path to text so the Workbench can render the image
|
|
214
218
|
for (const url of sentMediaUrls) {
|
|
215
219
|
const mediaLine = `MEDIA: ${url}`;
|
|
@@ -217,12 +221,12 @@ const plugin = createChatChannelPlugin({
|
|
|
217
221
|
text = text ? `${text}\n${mediaLine}` : mediaLine;
|
|
218
222
|
}
|
|
219
223
|
}
|
|
220
|
-
logger?.info?.(`[Dragon Plugin] handleAction sending text over channel: text_len=${text.length}, targetSession=${sessionId}`);
|
|
224
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction sending text over channel: text_len=${text.length}, targetSession=${sessionId}`);
|
|
221
225
|
const result = await channel.handleOutboundText({
|
|
222
226
|
text,
|
|
223
227
|
peer: { id: sessionId }
|
|
224
228
|
});
|
|
225
|
-
logger?.info?.(`[Dragon Plugin] handleAction channel send result: ok=${result.ok}, messageId=${result.messageId || "none"}`);
|
|
229
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction channel send result: ok=${result.ok}, messageId=${result.messageId || "none"}`);
|
|
226
230
|
const evidence = {
|
|
227
231
|
ok: result.ok,
|
|
228
232
|
...result.messageId ? { messageId: result.messageId } : {},
|
|
@@ -233,10 +237,10 @@ const plugin = createChatChannelPlugin({
|
|
|
233
237
|
messagingToolSentMediaUrls: sentMediaUrls,
|
|
234
238
|
messagingToolSentTargets: [{ to: target, ...(sentMediaUrls.length > 0 ? { mediaUrls: sentMediaUrls } : {}) }],
|
|
235
239
|
};
|
|
236
|
-
logger?.info?.(`[Dragon Plugin] handleAction returning evidence to OpenClaw: didSendViaMessagingTool=${evidence.didSendViaMessagingTool}, sentMediaUrlsCount=${evidence.messagingToolSentMediaUrls.length}`);
|
|
240
|
+
logger?.info?.(`[dragon channels][Dragon Plugin] handleAction returning evidence to OpenClaw: didSendViaMessagingTool=${evidence.didSendViaMessagingTool}, sentMediaUrlsCount=${evidence.messagingToolSentMediaUrls.length}`);
|
|
237
241
|
return evidence;
|
|
238
242
|
}
|
|
239
|
-
logger?.warn?.(`[Dragon Plugin] handleAction action "${action}" is not supported. Ignoring.`);
|
|
243
|
+
logger?.warn?.(`[dragon channels][Dragon Plugin] handleAction action "${action}" is not supported. Ignoring.`);
|
|
240
244
|
throw new Error(`Action "${action}" is not supported by the dragon channel plugin.`);
|
|
241
245
|
}
|
|
242
246
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const dragonChannelPluginVersion = "0.5.
|
|
1
|
+
export declare const dragonChannelPluginVersion = "0.5.30";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const dragonChannelPluginVersion = "0.5.
|
|
1
|
+
export const dragonChannelPluginVersion = "0.5.30";
|