@efengx/openclaw-channel-dragon 0.5.18 → 0.5.20

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.
@@ -15,6 +15,9 @@ export declare class ChannelComponent implements IComponent {
15
15
  constructor(options: ChannelOptions, telemetry: TelemetryComponent);
16
16
  start(): Promise<void>;
17
17
  stop(): Promise<void>;
18
+ private normalizeSessionSegment;
19
+ private resolveOpenClawAgentId;
20
+ private buildOpenClawSessionKey;
18
21
  private stringifyProgressDetail;
19
22
  deliverToOpenClaw: (content: string, sessionId?: string, modelId?: string, attachments?: any[], messageId?: string | number) => Promise<void>;
20
23
  handleOutboundText: (ctx: any) => Promise<{
@@ -10,6 +10,29 @@ export class ChannelComponent {
10
10
  }
11
11
  async start() { }
12
12
  async stop() { }
13
+ normalizeSessionSegment(value, fallback) {
14
+ const raw = String(value || '').trim().toLowerCase();
15
+ const normalized = raw
16
+ .replace(/[^a-z0-9_-]+/g, '-')
17
+ .replace(/^-+/, '')
18
+ .replace(/-+$/, '')
19
+ .slice(0, 64);
20
+ return normalized || fallback;
21
+ }
22
+ resolveOpenClawAgentId() {
23
+ const agents = this.options.cfg?.agents?.list;
24
+ if (Array.isArray(agents)) {
25
+ const selected = agents.find((agent) => agent?.default)?.id || agents[0]?.id;
26
+ return this.normalizeSessionSegment(selected, 'main');
27
+ }
28
+ return 'main';
29
+ }
30
+ buildOpenClawSessionKey(agentId, sessionId) {
31
+ const openClawAgentId = this.resolveOpenClawAgentId();
32
+ const dragonAgentId = this.normalizeSessionSegment(agentId, 'agent');
33
+ const workbenchSessionId = this.normalizeSessionSegment(sessionId, 'default');
34
+ return `agent:${openClawAgentId}:dragon:direct:${dragonAgentId}:${workbenchSessionId}`;
35
+ }
13
36
  stringifyProgressDetail(value, maxLength = 240) {
14
37
  if (typeof value === 'string') {
15
38
  const text = value.trim();
@@ -41,12 +64,12 @@ export class ChannelComponent {
41
64
  if (typeof replyDispatcher !== 'function')
42
65
  return;
43
66
  const { accountId, agentId, cfg, logger } = this.options;
44
- const sessionKey = `dragon:${agentId}:direct:${sessionId}`;
67
+ const sessionKey = this.buildOpenClawSessionKey(agentId, sessionId);
45
68
  const previous = this.sessionQueues.get(sessionKey) || Promise.resolve();
46
69
  const current = previous
47
70
  .catch(() => { })
48
71
  .then(async () => {
49
- logger?.info?.(`[Dragon Plugin] Sending to OpenClaw: "${content.substring(0, 50)}${content.length > 50 ? '...' : ''}" [Session: ${sessionId}]`);
72
+ logger?.info?.(`[Dragon Plugin] Sending to OpenClaw: "${content.substring(0, 50)}${content.length > 50 ? '...' : ''}" [WorkbenchSession: ${sessionId}] [OpenClawSessionKey: ${sessionKey}]`);
50
73
  const progress = (payload) => this.telemetry.reportProgress({
51
74
  sessionId,
52
75
  msgId: replyMsgId,
@@ -10,6 +10,7 @@ export declare class SseComponent implements IComponent {
10
10
  private reconnectTimer;
11
11
  constructor(http: HttpComponent, channel: ChannelComponent, options: {
12
12
  agentId: string;
13
+ version: string;
13
14
  logger?: any;
14
15
  });
15
16
  start(): Promise<void>;
@@ -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] Connecting to Orchestrator SSE: ${url}`);
27
+ logger?.info?.(`[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.
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { TelemetryComponent } from "./components/telemetry/TelemetryComponent.js
6
6
  import { HttpComponent } from "./components/http/HttpComponent.js";
7
7
  import { ChannelComponent } from "./components/channel/ChannelComponent.js";
8
8
  import { SseComponent } from "./components/sync/SseComponent.js";
9
+ import { dragonChannelPluginVersion } from "./version.js";
9
10
  const channelId = "dragon";
10
11
  let cachedRuntime;
11
12
  const containers = new Map();
@@ -15,6 +16,7 @@ async function getOrCreateContainer(account, ctx) {
15
16
  return containers.get(key);
16
17
  const logger = ctx?.logger ?? ctx?.log ?? cachedRuntime?.logger ?? cachedRuntime?.log;
17
18
  const container = new ServiceContainer();
19
+ logger?.info?.(`[Dragon Plugin] Starting channel plugin v${dragonChannelPluginVersion} for agent=${account.agentId}, account=${account.accountId}, orchestrator=${account.orchestratorUrl}`);
18
20
  // 1. Core Infrastructure
19
21
  const http = container.register('http', new HttpComponent({
20
22
  baseURL: account.orchestratorUrl,
@@ -33,6 +35,7 @@ async function getOrCreateContainer(account, ctx) {
33
35
  // 3. Sync Infrastructure
34
36
  container.register('sse', new SseComponent(http, channel, {
35
37
  agentId: account.agentId,
38
+ version: dragonChannelPluginVersion,
36
39
  logger
37
40
  }));
38
41
  await container.startAll();
@@ -0,0 +1 @@
1
+ export declare const dragonChannelPluginVersion = "0.5.20";
@@ -0,0 +1 @@
1
+ export const dragonChannelPluginVersion = "0.5.20";
@@ -2,7 +2,7 @@
2
2
  "id": "dragon",
3
3
  "name": "Dragon Workbench Channel",
4
4
  "description": "Connect OpenClaw to the Dragon agent-client workbench chat.",
5
- "version": "0.5.18",
5
+ "version": "0.5.20",
6
6
  "enabledByDefault": true,
7
7
  "activation": {
8
8
  "onCapabilities": ["hook"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@efengx/openclaw-channel-dragon",
3
- "version": "0.5.18",
3
+ "version": "0.5.20",
4
4
  "description": "Dragon workbench channel for OpenClaw",
5
5
  "author": "feng xiang <ofengx@gmail.com>",
6
6
  "type": "module",