openclaw-xiaoyou 1.0.5 → 1.0.7

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.
package/index.ts CHANGED
@@ -15,6 +15,7 @@ const plugin = {
15
15
  id: "xiaoyou",
16
16
  name: "Xiaoyou",
17
17
  description: "Bridge OpenClaw to enterprise services via persistent WebSocket connection",
18
+ configSchema: { type: "object", additionalProperties: true, properties: {} },
18
19
 
19
20
  register(api: any) {
20
21
  // 注入 runtime,供 gateway/outbound 内部使用
@@ -1,67 +1,9 @@
1
1
  {
2
- "id": "openclaw-xiaoyou",
3
- "name": "Xiaoyou",
4
- "description": "Bridge OpenClaw to enterprise services via persistent WebSocket connection",
5
- "version": "1.0.5",
2
+ "id": "xiaoyou",
3
+ "channels": ["xiaoyou"],
6
4
  "configSchema": {
7
5
  "type": "object",
8
- "properties": {
9
- "enabled": {
10
- "type": "boolean",
11
- "default": false,
12
- "description": "启用/禁用此 channel"
13
- },
14
- "wsUrl": {
15
- "type": "string",
16
- "description": "企业 WebSocket 服务地址",
17
- "examples": ["wss://im.corp.example.com/ws", "ws://192.168.1.100:9090"]
18
- },
19
- "authToken": {
20
- "type": "string",
21
- "sensitive": true,
22
- "description": "连接企业服务的认证 Token"
23
- },
24
- "dmSecurity": {
25
- "type": "string",
26
- "enum": ["open", "allowlist"],
27
- "default": "open",
28
- "description": "DM 安全策略。open=允许所有用户,allowlist=仅白名单用户"
29
- },
30
- "allowFrom": {
31
- "type": "array",
32
- "items": { "type": "string" },
33
- "default": [],
34
- "description": "白名单用户 ID 列表(dmSecurity=allowlist 时生效)"
35
- },
36
- "reconnectIntervalMs": {
37
- "type": "number",
38
- "default": 3000,
39
- "description": "重连基础间隔(毫秒),实际按指数退避递增"
40
- },
41
- "maxReconnectAttempts": {
42
- "type": "number",
43
- "default": 0,
44
- "description": "最大重连次数,0=无限重试"
45
- },
46
- "heartbeatIntervalMs": {
47
- "type": "number",
48
- "default": 30000,
49
- "description": "心跳发送间隔(毫秒)"
50
- },
51
- "heartbeatTimeoutMs": {
52
- "type": "number",
53
- "default": 10000,
54
- "description": "心跳超时时间(毫秒),超时则断开重连"
55
- }
56
- }
57
- },
58
- "channel": {
59
- "id": "xiaoyou",
60
- "label": "Xiaoyou",
61
- "selectionLabel": "Xiaoyou (enterprise WebSocket)",
62
- "blurb": "Bridge OpenClaw to enterprise services via persistent WebSocket.",
63
- "docsPath": "/channels/xiaoyou",
64
- "aliases": ["xiaoyou"],
65
- "order": 50
6
+ "additionalProperties": true,
7
+ "properties": {}
66
8
  }
67
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-xiaoyou",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "type": "module",
5
5
  "description": "Xiaoyou channel plugin for OpenClaw — connects enterprise services via persistent outbound WebSocket",
6
6
  "openclaw": {
@@ -10,17 +10,8 @@
10
10
  "setupEntry": "./setup-entry.ts",
11
11
  "configSchema": {
12
12
  "type": "object",
13
- "properties": {
14
- "enabled": { "type": "boolean", "default": false },
15
- "wsUrl": { "type": "string", "description": "企业 WebSocket 服务地址" },
16
- "authToken": { "type": "string", "sensitive": true, "description": "连接企业服务的认证 Token" },
17
- "dmSecurity": { "type": "string", "enum": ["open", "allowlist"], "default": "open" },
18
- "allowFrom": { "type": "array", "items": { "type": "string" }, "default": [] },
19
- "reconnectIntervalMs": { "type": "number", "default": 3000 },
20
- "maxReconnectAttempts": { "type": "number", "default": 0 },
21
- "heartbeatIntervalMs": { "type": "number", "default": 30000 },
22
- "heartbeatTimeoutMs": { "type": "number", "default": 10000 }
23
- }
13
+ "additionalProperties": true,
14
+ "properties": {}
24
15
  },
25
16
  "channel": {
26
17
  "id": "xiaoyou",
package/src/channel.ts CHANGED
@@ -21,12 +21,21 @@ export function getRuntime() { return _runtime; }
21
21
 
22
22
  // ─── Config Adapter ──────────────────────────────────
23
23
 
24
- function resolveAccount(cfg: any): ResolvedAccount {
25
- const section = cfg.channels?.["xiaoyou"] ?? cfg;
26
- if (!section.wsUrl) throw new Error("xiaoyou: wsUrl is required");
24
+ function getChannelConfig(cfg: any): any {
25
+ return cfg?.channels?.xiaoyou ?? {};
26
+ }
27
+
28
+ function resolveAccount(cfg: any, accountId?: string | null): any {
29
+ const section = getChannelConfig(cfg);
30
+ const id = accountId || "default";
31
+ const configured = Boolean(section.wsUrl);
27
32
 
28
33
  return {
29
- wsUrl: section.wsUrl,
34
+ accountId: id,
35
+ config: section,
36
+ enabled: section.enabled !== false,
37
+ configured,
38
+ wsUrl: section.wsUrl ?? "",
30
39
  authToken: section.authToken ?? "",
31
40
  allowFrom: section.allowFrom ?? [],
32
41
  dmPolicy: section.dmSecurity,
@@ -38,7 +47,7 @@ function resolveAccount(cfg: any): ResolvedAccount {
38
47
  }
39
48
 
40
49
  function inspectAccount(cfg: any) {
41
- const section = cfg.channels?.["xiaoyou"] ?? cfg;
50
+ const section = getChannelConfig(cfg);
42
51
  return {
43
52
  enabled: Boolean(section?.wsUrl),
44
53
  configured: Boolean(section?.wsUrl),
@@ -47,7 +56,7 @@ function inspectAccount(cfg: any) {
47
56
  }
48
57
 
49
58
  function listAccountIds(cfg: any): string[] {
50
- const section = cfg.channels?.["xiaoyou"] ?? cfg;
59
+ const section = getChannelConfig(cfg);
51
60
  if (section?.wsUrl) return ["default"];
52
61
  return [];
53
62
  }
@@ -104,9 +113,18 @@ export const xiayouPlugin = {
104
113
  gateway: {
105
114
  start: async ({ account, config, logger }: any) => {
106
115
  const resolved: ResolvedAccount =
107
- typeof account.wsUrl === "string"
116
+ typeof account?.wsUrl === "string"
108
117
  ? account
109
- : resolveAccount(config);
118
+ : {
119
+ wsUrl: account?.config?.wsUrl ?? "",
120
+ authToken: account?.config?.authToken ?? "",
121
+ allowFrom: account?.config?.allowFrom ?? [],
122
+ dmPolicy: account?.config?.dmSecurity,
123
+ reconnectIntervalMs: account?.config?.reconnectIntervalMs ?? 3000,
124
+ maxReconnectAttempts: account?.config?.maxReconnectAttempts ?? 0,
125
+ heartbeatIntervalMs: account?.config?.heartbeatIntervalMs ?? 30000,
126
+ heartbeatTimeoutMs: account?.config?.heartbeatTimeoutMs ?? 10000,
127
+ };
110
128
 
111
129
  // 断开已有连接
112
130
  if (_client) _client.disconnect();
@@ -184,9 +202,11 @@ export const xiayouPlugin = {
184
202
  status: {
185
203
  describe: async ({ account }: any) => {
186
204
  const issues: Array<{ severity: string; message: string }> = [];
205
+ const wsUrl = account?.wsUrl ?? account?.config?.wsUrl;
206
+ const authToken = account?.authToken ?? account?.config?.authToken;
187
207
 
188
- if (!account?.wsUrl) issues.push({ severity: "error", message: "wsUrl not configured" });
189
- if (!account?.authToken) issues.push({ severity: "warning", message: "authToken not set" });
208
+ if (!wsUrl) issues.push({ severity: "error", message: "wsUrl not configured" });
209
+ if (!authToken) issues.push({ severity: "warning", message: "authToken not set" });
190
210
  if (!_client || !_client.isConnected()) issues.push({ severity: "error", message: "WebSocket not connected" });
191
211
 
192
212
  return {