@efengx/openclaw-channel-dragon 0.5.37 → 0.5.38

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.
@@ -20,10 +20,13 @@ export declare class ChannelComponent implements IComponent {
20
20
  private normalizeSessionSegment;
21
21
  private encodeWorkbenchTarget;
22
22
  private decodeWorkbenchTarget;
23
+ private maybeDecodeWorkbenchTarget;
24
+ private resolveOutboundSessionId;
23
25
  private resolveOpenClawAgentId;
24
26
  private buildOpenClawSessionKey;
25
27
  private resolveWorkbenchSessionIdFromOpenClawSessionKey;
26
28
  private stringifyProgressDetail;
29
+ private summarizeOutboundContext;
27
30
  private findTaskCompletionEvent;
28
31
  private formatTaskCompletionReply;
29
32
  deliverToOpenClaw: (content: string, sessionId?: string, modelId?: string, attachments?: any[], messageId?: string | number) => Promise<void>;
@@ -38,6 +38,41 @@ export class ChannelComponent {
38
38
  }
39
39
  return sessionId;
40
40
  }
41
+ maybeDecodeWorkbenchTarget(value) {
42
+ const target = String(value || '').trim();
43
+ if (!target || !target.startsWith(workbenchTargetPrefix))
44
+ return undefined;
45
+ return this.decodeWorkbenchTarget(target);
46
+ }
47
+ resolveOutboundSessionId(ctx) {
48
+ const rawTarget = ctx?.peer?.id ?? ctx?.target ?? ctx?.to ?? ctx?.route?.to ?? ctx?.route?.from;
49
+ const decoded = this.maybeDecodeWorkbenchTarget(rawTarget);
50
+ if (decoded)
51
+ return { sessionId: decoded, rawTarget, inferred: false };
52
+ const explicitTarget = String(rawTarget || '').trim();
53
+ if (explicitTarget) {
54
+ return { sessionId: this.decodeWorkbenchTarget(explicitTarget), rawTarget, inferred: false };
55
+ }
56
+ const currentChannelId = this.maybeDecodeWorkbenchTarget(ctx?.toolContext?.currentChannelId);
57
+ if (currentChannelId) {
58
+ return { sessionId: currentChannelId, rawTarget: ctx?.toolContext?.currentChannelId, inferred: true };
59
+ }
60
+ const sessionKey = ctx?.sessionKey ||
61
+ ctx?.SessionKey ||
62
+ ctx?.ctx?.SessionKey ||
63
+ ctx?.message?.sessionKey ||
64
+ ctx?.route?.sessionKey ||
65
+ ctx?.session?.key;
66
+ const sessionFromKey = this.resolveWorkbenchSessionIdFromOpenClawSessionKey(sessionKey);
67
+ if (sessionKey || sessionFromKey !== 'default') {
68
+ return { sessionId: sessionFromKey, rawTarget: sessionKey, inferred: true };
69
+ }
70
+ const sessionId = String(ctx?.sessionId || ctx?.session?.id || '').trim();
71
+ if (sessionId) {
72
+ return { sessionId, rawTarget: sessionId, inferred: true };
73
+ }
74
+ return { sessionId: 'default', rawTarget: rawTarget || '<empty>', inferred: true };
75
+ }
41
76
  resolveOpenClawAgentId() {
42
77
  const agents = this.options.cfg?.agents?.list;
43
78
  if (Array.isArray(agents)) {
@@ -80,6 +115,32 @@ export class ChannelComponent {
80
115
  return String(value).slice(0, maxLength);
81
116
  }
82
117
  }
118
+ summarizeOutboundContext(ctx) {
119
+ const summarizeValue = (value) => {
120
+ if (Array.isArray(value))
121
+ return { type: 'array', length: value.length };
122
+ if (value && typeof value === 'object')
123
+ return { type: 'object', keys: Object.keys(value).slice(0, 20) };
124
+ if (typeof value === 'string')
125
+ return value.length > 180 ? `${value.slice(0, 180)}...` : value;
126
+ return value;
127
+ };
128
+ return {
129
+ topLevelKeys: ctx && typeof ctx === 'object' ? Object.keys(ctx).slice(0, 40) : [],
130
+ textLength: String(ctx?.text || '').length,
131
+ peerId: ctx?.peer?.id,
132
+ target: ctx?.target,
133
+ to: ctx?.to,
134
+ routeTo: ctx?.route?.to,
135
+ routeFrom: ctx?.route?.from,
136
+ sessionKey: ctx?.sessionKey || ctx?.SessionKey || ctx?.ctx?.SessionKey || ctx?.message?.sessionKey || ctx?.route?.sessionKey || ctx?.session?.key,
137
+ sessionId: ctx?.sessionId || ctx?.session?.id,
138
+ currentChannelId: ctx?.toolContext?.currentChannelId,
139
+ attachments: summarizeValue(ctx?.attachments),
140
+ media: summarizeValue(ctx?.media),
141
+ mediaUrls: summarizeValue(ctx?.mediaUrls),
142
+ };
143
+ }
83
144
  findTaskCompletionEvent(value) {
84
145
  if (!value || typeof value !== 'object')
85
146
  return undefined;
@@ -360,8 +421,15 @@ export class ChannelComponent {
360
421
  const { logger } = this.options;
361
422
  const archivedAttachments = await this.mediaRegistry.archiveStructuredMedia(ctx);
362
423
  let sessionId;
424
+ let rawTarget;
363
425
  try {
364
- sessionId = this.decodeWorkbenchTarget(ctx?.peer?.id);
426
+ const resolved = this.resolveOutboundSessionId(ctx);
427
+ sessionId = resolved.sessionId;
428
+ rawTarget = resolved.rawTarget;
429
+ if (resolved.inferred) {
430
+ logger?.warn?.(`[dragon channels][Dragon Plugin] outbound target missing; inferred workbench session "${sessionId}" from runtime context instead of reporting protocol error.`);
431
+ logger?.warn?.(`[dragon channels][Dragon Plugin] non-standard outbound context: ${JSON.stringify(this.summarizeOutboundContext(ctx))}`);
432
+ }
365
433
  }
366
434
  catch (error) {
367
435
  const message = error?.message || String(error);
@@ -369,7 +437,7 @@ export class ChannelComponent {
369
437
  await this.reportTargetProtocolError(message, ctx?.peer?.id);
370
438
  return { ok: false, messageId: Date.now().toString(), error: message };
371
439
  }
372
- logger?.info?.(`[dragon channels][Dragon Plugin] Outbound Text (Action): "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}" [Session: ${sessionId}] [RawPeer: ${ctx?.peer?.id || 'none'}]`);
440
+ logger?.info?.(`[dragon channels][Dragon Plugin] Outbound Text (Action): "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}" [Session: ${sessionId}] [RawPeer: ${String(rawTarget || ctx?.peer?.id || 'none')}]`);
373
441
  await this.telemetry.reportReply({
374
442
  content: text,
375
443
  sessionId,
@@ -73,7 +73,8 @@ export class TelemetryComponent {
73
73
  async reportProgress(payload) {
74
74
  try {
75
75
  const sessionId = payload.sessionId || "default";
76
- const key = `${sessionId}:${payload.kind}:${payload.title || ""}`;
76
+ const msgId = payload.msgId || "no-msg";
77
+ const key = `${sessionId}:${msgId}:${payload.kind}:${payload.title || ""}`;
77
78
  const signature = JSON.stringify({
78
79
  phase: payload.phase,
79
80
  status: payload.status,
package/dist/index.js CHANGED
@@ -231,7 +231,7 @@ const plugin = createChatChannelPlugin({
231
231
  const account = base.config.resolveAccount(cfg, accountId);
232
232
  const container = await getOrCreateContainer(account, ctx);
233
233
  const channel = container.get('channel');
234
- const rawTarget = params.to || params.target || ctx.toolContext?.currentChannelId || "default";
234
+ const rawTarget = params.to || params.target || ctx.toolContext?.currentChannelId || encodeWorkbenchTarget("default");
235
235
  logger?.info?.(`[dragon channels][Dragon Plugin] handleAction target resolution input: ${rawTarget}`);
236
236
  let sessionId;
237
237
  let target;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const dragonChannelPluginVersion = "0.5.37";
1
+ export declare const dragonChannelPluginVersion = "0.5.38";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const dragonChannelPluginVersion = "0.5.37";
1
+ export const dragonChannelPluginVersion = "0.5.38";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@efengx/openclaw-channel-dragon",
3
- "version": "0.5.37",
3
+ "version": "0.5.38",
4
4
  "description": "Dragon workbench channel for OpenClaw",
5
5
  "author": "feng xiang <ofengx@gmail.com>",
6
6
  "type": "module",