@honor-claw/yoyo 1.1.2 → 1.1.4-beta.1

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 (66) hide show
  1. package/index.ts +25 -25
  2. package/package.json +5 -5
  3. package/src/apis/claw-cloud.ts +124 -124
  4. package/src/apis/helpers.ts +10 -10
  5. package/src/apis/honor-auth.ts +158 -158
  6. package/src/apis/http-client.ts +239 -239
  7. package/src/apis/index.ts +8 -8
  8. package/src/apis/types.ts +77 -73
  9. package/src/cloud-channel/channel.ts +117 -117
  10. package/src/cloud-channel/client.ts +3 -3
  11. package/src/cloud-channel/index.ts +4 -4
  12. package/src/cloud-channel/message-handler.ts +50 -42
  13. package/src/cloud-channel/session-manager.ts +14 -9
  14. package/src/cloud-channel/types.ts +115 -115
  15. package/src/commands/env/impl.ts +58 -58
  16. package/src/commands/env/index.ts +1 -1
  17. package/src/commands/index.ts +30 -30
  18. package/src/commands/login/impl.ts +30 -30
  19. package/src/commands/login/index.ts +1 -1
  20. package/src/commands/logout/index.ts +1 -1
  21. package/src/commands/status/index.ts +194 -194
  22. package/src/gateway-client/client.ts +90 -90
  23. package/src/gateway-client/device/auth.ts +57 -57
  24. package/src/gateway-client/device/builder.ts +105 -105
  25. package/src/gateway-client/device/helpers.ts +40 -40
  26. package/src/gateway-client/device/identity.ts +251 -251
  27. package/src/gateway-client/device/index.ts +40 -40
  28. package/src/gateway-client/device/types.ts +57 -57
  29. package/src/gateway-client/index.ts +5 -5
  30. package/src/gateway-client/protocol-client.ts +49 -34
  31. package/src/honor-auth/browser.ts +2 -2
  32. package/src/honor-auth/callback-server.ts +109 -109
  33. package/src/honor-auth/cloud.ts +57 -57
  34. package/src/honor-auth/config.ts +43 -43
  35. package/src/honor-auth/index.ts +3 -3
  36. package/src/honor-auth/token-manager.ts +90 -90
  37. package/src/honor-auth/types.ts +50 -50
  38. package/src/index.ts +10 -10
  39. package/src/modules/claw-configs/config-manager.ts +409 -409
  40. package/src/modules/claw-configs/hosts.ts +48 -48
  41. package/src/modules/claw-configs/index.ts +8 -8
  42. package/src/modules/claw-configs/provider.ts +394 -394
  43. package/src/modules/claw-configs/types.ts +34 -34
  44. package/src/modules/device/device-info.ts +1 -1
  45. package/src/modules/device/index.ts +3 -3
  46. package/src/modules/device/providers/base.ts +32 -32
  47. package/src/modules/device/providers/pad.ts +107 -107
  48. package/src/modules/device/providers/windows.ts +130 -130
  49. package/src/modules/device/registry.ts +48 -43
  50. package/src/modules/login/impl.ts +31 -26
  51. package/src/modules/login/index.ts +6 -6
  52. package/src/schemas.ts +23 -23
  53. package/src/services/connection/impl.ts +339 -339
  54. package/src/services/connection/status-tracker/events.ts +127 -127
  55. package/src/services/connection/status-tracker/index.ts +31 -31
  56. package/src/services/connection/status-tracker/storage.ts +133 -133
  57. package/src/services/connection/status-tracker/tracker.ts +370 -370
  58. package/src/services/connection/status-tracker/types.ts +131 -131
  59. package/src/services/connection/types.ts +20 -20
  60. package/src/types.ts +64 -64
  61. package/src/utils/id.ts +8 -8
  62. package/src/utils/jwt.ts +37 -37
  63. package/src/utils/logger.ts +20 -20
  64. package/src/utils/proxy.ts +58 -58
  65. package/src/utils/version.ts +29 -29
  66. package/src/utils/ws.ts +21 -21
@@ -1,117 +1,117 @@
1
- import type { ClawChannelConfig } from "./types.js";
2
- import { ClawCloudSocketClient } from "./client.js";
3
- import { SessionManager } from "./session-manager.js";
4
- import { AdminClientManager } from "./admin-client-manager.js";
5
- import { MessageHandler } from "./message-handler.js";
6
- import { useClawLogger } from "../utils/logger.js";
7
- import { takeApiHost } from "../modules/claw-configs/hosts.js";
8
-
9
- /**
10
- * 新的Channel实现
11
- * - 使用ClawCloudSocketClient连接云侧服务器
12
- * - 处理配对消息和用户消息
13
- * - 管理GatewayClient连接
14
- */
15
- export class ClawChannel {
16
- private cloudClient: ClawCloudSocketClient;
17
- private sessionManager: SessionManager;
18
- private adminClientManager: AdminClientManager;
19
- private messageHandler: MessageHandler;
20
- private config: ClawChannelConfig;
21
-
22
- constructor(config: ClawChannelConfig) {
23
- this.config = config;
24
- const hosts = takeApiHost();
25
-
26
- this.sessionManager = new SessionManager();
27
- this.adminClientManager = new AdminClientManager({
28
- onStatusEvent: this.handleStatusEvent,
29
- });
30
-
31
- const extraHeaders = hosts.grayTag ? { 'x-gray': hosts.grayTag } : undefined;
32
-
33
- this.cloudClient = new ClawCloudSocketClient({
34
- serverUrl: `wss://${hosts.clawCloud}/aicloud/yoyo-claw-service/v1/yoyoclaw/fullduplex`,
35
- deviceInfo: config.deviceInfo,
36
- userInfo: config.userInfo,
37
- extraHeaders,
38
- onStatusEvent: this.handleStatusEvent,
39
- });
40
-
41
- this.messageHandler = new MessageHandler({
42
- sessionManager: this.sessionManager,
43
- adminClientManager: this.adminClientManager,
44
- cloudClient: this.cloudClient,
45
- config: {
46
- deviceInfo: {
47
- deviceId: config.deviceInfo.deviceId,
48
- port: config.deviceInfo.port,
49
- },
50
- onStatusEvent: this.handleStatusEvent,
51
- },
52
- });
53
-
54
- this.cloudClient.setMessageHandler(this.messageHandler.handleCloudMessage);
55
- this.cloudClient.setOpenHandler(this.handleCloudOpen);
56
- this.cloudClient.setCloseHandler(this.handleCloudClose);
57
- this.cloudClient.setRemoteDeviceOfflineHandler(this.handleRemoteDeviceOffline);
58
- this.cloudClient.setDeviceNotRegisteredHandler(this.handleDeviceNotRegistered);
59
-
60
- // 实例化AdminGatewayClient
61
- this.adminClientManager.init();
62
- }
63
-
64
- start(): void {
65
- useClawLogger().info("[yoyoclaw-channel] starting connection");
66
- this.adminClientManager.ensureConnected();
67
- this.cloudClient.connect();
68
- }
69
-
70
- /**
71
- * 关闭连接
72
- */
73
- destroy(): void {
74
- useClawLogger().info("[yoyoclaw-channel] closing connection");
75
- this.sessionManager.closeAllNodeGatewayClients();
76
- this.adminClientManager.destroy();
77
- this.cloudClient.close();
78
- }
79
-
80
- /**
81
- * 处理云侧连接打开
82
- */
83
- private handleCloudOpen = () => {
84
- useClawLogger().info("[yoyoclaw-channel] cloud connection established");
85
- this.config.onOpen?.();
86
- };
87
-
88
- /**
89
- * 统一处理所有状态事件
90
- */
91
- private handleStatusEvent = (event: any) => {
92
- this.config.onStatusEvent?.(event);
93
- };
94
-
95
- /**
96
- * 处理云侧连接关闭
97
- */
98
- private handleCloudClose = () => {
99
- useClawLogger().info("[yoyoclaw-channel] cloud connection closed");
100
- this.config.onClose?.();
101
- };
102
-
103
- /**
104
- * 处理对向设备离线
105
- */
106
- private handleRemoteDeviceOffline = (sourceDeviceId: string) => {
107
- this.sessionManager.closeNodeGatewayClient(sourceDeviceId);
108
- };
109
-
110
- /**
111
- * 处理当前设备未注册
112
- */
113
- private handleDeviceNotRegistered = () => {
114
- useClawLogger().info("[yoyoclaw-channel] device not registered, notifying connection layer");
115
- this.config.onDeviceNotRegistered?.();
116
- };
117
- }
1
+ import type { ClawChannelConfig } from "./types.js";
2
+ import { ClawCloudSocketClient } from "./client.js";
3
+ import { SessionManager } from "./session-manager.js";
4
+ import { AdminClientManager } from "./admin-client-manager.js";
5
+ import { MessageHandler } from "./message-handler.js";
6
+ import { useClawLogger } from "../utils/logger.js";
7
+ import { takeApiHost } from "../modules/claw-configs/hosts.js";
8
+
9
+ /**
10
+ * 新的Channel实现
11
+ * - 使用ClawCloudSocketClient连接云侧服务器
12
+ * - 处理配对消息和用户消息
13
+ * - 管理GatewayClient连接
14
+ */
15
+ export class ClawChannel {
16
+ private cloudClient: ClawCloudSocketClient;
17
+ private sessionManager: SessionManager;
18
+ private adminClientManager: AdminClientManager;
19
+ private messageHandler: MessageHandler;
20
+ private config: ClawChannelConfig;
21
+
22
+ constructor(config: ClawChannelConfig) {
23
+ this.config = config;
24
+ const hosts = takeApiHost();
25
+
26
+ this.sessionManager = new SessionManager();
27
+ this.adminClientManager = new AdminClientManager({
28
+ onStatusEvent: this.handleStatusEvent,
29
+ });
30
+
31
+ const extraHeaders = hosts.grayTag ? { 'x-gray': hosts.grayTag } : undefined;
32
+
33
+ this.cloudClient = new ClawCloudSocketClient({
34
+ serverUrl: `wss://${hosts.clawCloud}/aicloud/yoyo-claw-service/v1/yoyoclaw/fullduplex`,
35
+ deviceInfo: config.deviceInfo,
36
+ userInfo: config.userInfo,
37
+ extraHeaders,
38
+ onStatusEvent: this.handleStatusEvent,
39
+ });
40
+
41
+ this.messageHandler = new MessageHandler({
42
+ sessionManager: this.sessionManager,
43
+ adminClientManager: this.adminClientManager,
44
+ cloudClient: this.cloudClient,
45
+ config: {
46
+ deviceInfo: {
47
+ deviceId: config.deviceInfo.deviceId,
48
+ port: config.deviceInfo.port,
49
+ },
50
+ onStatusEvent: this.handleStatusEvent,
51
+ },
52
+ });
53
+
54
+ this.cloudClient.setMessageHandler(this.messageHandler.handleCloudMessage);
55
+ this.cloudClient.setOpenHandler(this.handleCloudOpen);
56
+ this.cloudClient.setCloseHandler(this.handleCloudClose);
57
+ this.cloudClient.setRemoteDeviceOfflineHandler(this.handleRemoteDeviceOffline);
58
+ this.cloudClient.setDeviceNotRegisteredHandler(this.handleDeviceNotRegistered);
59
+
60
+ // 实例化AdminGatewayClient
61
+ this.adminClientManager.init();
62
+ }
63
+
64
+ start(): void {
65
+ useClawLogger().info("[yoyoclaw-channel] starting connection");
66
+ this.adminClientManager.ensureConnected();
67
+ this.cloudClient.connect();
68
+ }
69
+
70
+ /**
71
+ * 关闭连接
72
+ */
73
+ destroy(): void {
74
+ useClawLogger().info("[yoyoclaw-channel] closing connection");
75
+ this.sessionManager.closeAllNodeGatewayClients();
76
+ this.adminClientManager.destroy();
77
+ this.cloudClient.close();
78
+ }
79
+
80
+ /**
81
+ * 处理云侧连接打开
82
+ */
83
+ private handleCloudOpen = () => {
84
+ useClawLogger().info("[yoyoclaw-channel] cloud connection established");
85
+ this.config.onOpen?.();
86
+ };
87
+
88
+ /**
89
+ * 统一处理所有状态事件
90
+ */
91
+ private handleStatusEvent = (event: any) => {
92
+ this.config.onStatusEvent?.(event);
93
+ };
94
+
95
+ /**
96
+ * 处理云侧连接关闭
97
+ */
98
+ private handleCloudClose = () => {
99
+ useClawLogger().info("[yoyoclaw-channel] cloud connection closed");
100
+ this.config.onClose?.();
101
+ };
102
+
103
+ /**
104
+ * 处理对向设备离线
105
+ */
106
+ private handleRemoteDeviceOffline = (sourceDeviceId: string) => {
107
+ this.sessionManager.closeNodeGatewayClient(sourceDeviceId);
108
+ };
109
+
110
+ /**
111
+ * 处理当前设备未注册
112
+ */
113
+ private handleDeviceNotRegistered = () => {
114
+ useClawLogger().info("[yoyoclaw-channel] device not registered, notifying connection layer");
115
+ this.config.onDeviceNotRegistered?.();
116
+ };
117
+ }
@@ -126,12 +126,12 @@ export class ClawCloudSocketClient {
126
126
 
127
127
  this.ws.on("ping", () => {
128
128
  // 收到服务端的 ping,自动回复 pong(ws 库会自动处理)
129
- useClawLogger().debug("[claw-cloud-socket] received ping from server");
129
+ useClawLogger().debug?.("[claw-cloud-socket] received ping from server");
130
130
  });
131
131
 
132
132
  this.ws.on("pong", () => {
133
133
  // 收到服务端的 pong 响应
134
- useClawLogger().debug("[claw-cloud-socket] received pong from server");
134
+ useClawLogger().debug?.("[claw-cloud-socket] received pong from server");
135
135
  });
136
136
 
137
137
  this.ws.on("close", (code: number, reason: Buffer) => {
@@ -354,7 +354,7 @@ export class ClawCloudSocketClient {
354
354
 
355
355
  // 发送 ping
356
356
  this.ws.ping();
357
- useClawLogger().debug("[claw-cloud-socket] sent ping to server");
357
+ useClawLogger().debug?.("[claw-cloud-socket] sent ping to server");
358
358
  }, PING_INTERVAL);
359
359
  }
360
360
 
@@ -1,4 +1,4 @@
1
- /**
2
- * Gateway Channel 导出
3
- */
4
- export { ClawChannel } from "./channel.js";
1
+ /**
2
+ * Gateway Channel 导出
3
+ */
4
+ export { ClawChannel } from "./channel.js";
@@ -1,9 +1,9 @@
1
- import type { YoyoClawMessage, DeviceSessionInfo } from "./types.js";
2
- import type { ClawCloudSocketClient } from "./client.js";
3
- import { SessionManager } from "./session-manager.js";
4
- import { AdminClientManager } from "./admin-client-manager.js";
5
1
  import type { NodeStatusEvent } from "../gateway-client/node-gateway-client.js";
6
2
  import { useClawLogger } from "../utils/logger.js";
3
+ import { AdminClientManager } from "./admin-client-manager.js";
4
+ import type { ClawCloudSocketClient } from "./client.js";
5
+ import { SessionManager } from "./session-manager.js";
6
+ import type { YoyoClawMessage, DeviceSessionInfo } from "./types.js";
7
7
 
8
8
  export interface MessageHandlerConfig {
9
9
  deviceInfo: { deviceId: string; port: number };
@@ -60,30 +60,29 @@ export class MessageHandler {
60
60
  * 处理配对消息,创建GatewayClient连接
61
61
  */
62
62
  private handlePairMessage(message: YoyoClawMessage): void {
63
- if (message.msgType !== "devicePairMessage") return;
63
+ if (message.msgType !== "devicePairMessage") {
64
+ return;
65
+ }
64
66
 
65
67
  try {
66
68
  const { sourceDeviceId, sourceDeviceInfo, targetDeviceId, port, sessionInfo } = message;
67
69
 
68
- if (
69
- sourceDeviceId &&
70
- targetDeviceId &&
71
- port &&
72
- sourceDeviceInfo?.deviceId
73
- ) {
70
+ if (sourceDeviceId && targetDeviceId && port && sourceDeviceInfo?.deviceId) {
74
71
  const hardwareDeviceId = sourceDeviceInfo.deviceId;
75
72
  const newTimestamp = sessionInfo?.nodeConnectTimestamp;
76
73
 
77
74
  if (!newTimestamp) {
78
75
  // 兜底旧版本,异常场景,暂时不移除旧连接
79
- useClawLogger().warn(`[yoyoclaw-channel] pair message missing timestamp for device: ${sourceDeviceId}`);
76
+ useClawLogger().warn(
77
+ `[yoyoclaw-channel] pair message missing timestamp for device: ${sourceDeviceId}`,
78
+ );
80
79
  } else {
81
80
  // 关闭该硬件设备ID对应的所有前序 GatewayClient(timestamp 小于新 timestamp)
82
81
  this.sessionManager.closePreviousNodeGatewayClients(hardwareDeviceId, newTimestamp);
83
82
  }
84
83
 
85
84
  useClawLogger().info(
86
- `[yoyoclaw-channel] received pair message, creating node gateway client for device: ${sourceDeviceId}, hardware device: ${hardwareDeviceId}, timestamp: ${newTimestamp}`
85
+ `[yoyoclaw-channel] received pair message, creating node gateway client for device: ${sourceDeviceId}, hardware device: ${hardwareDeviceId}, timestamp: ${newTimestamp}`,
87
86
  );
88
87
 
89
88
  const sessionInfoData: DeviceSessionInfo = {
@@ -122,9 +121,10 @@ export class MessageHandler {
122
121
  onStatusEvent: (event: NodeStatusEvent) => {
123
122
  // 通知状态跟踪器:GatewayClient状态变化
124
123
  this.config.onStatusEvent?.({
125
- type: event.type === "node_connected"
126
- ? "gateway_client_connected"
127
- : "gateway_client_disconnected",
124
+ type:
125
+ event.type === "node_connected"
126
+ ? "gateway_client_connected"
127
+ : "gateway_client_disconnected",
128
128
  timestamp: event.timestamp,
129
129
  data: event.data,
130
130
  });
@@ -134,9 +134,7 @@ export class MessageHandler {
134
134
  nodeGatewayClient.connect();
135
135
  }
136
136
  } catch (error) {
137
- useClawLogger().error(
138
- `[yoyoclaw-channel] failed to handle pair message: ${String(error)}`
139
- );
137
+ useClawLogger().error(`[yoyoclaw-channel] failed to handle pair message: ${String(error)}`);
140
138
  }
141
139
  }
142
140
 
@@ -156,20 +154,20 @@ export class MessageHandler {
156
154
  const nodeGatewayClient = this.sessionManager.getNodeGatewayClient(sourceDeviceId);
157
155
  if (!nodeGatewayClient) {
158
156
  useClawLogger().warn(
159
- `[yoyoclaw-channel] no node gateway client found for source device: ${hardwareDeviceId}, session: ${sourceDeviceId}`
157
+ `[yoyoclaw-channel] no node gateway client found for source device: ${hardwareDeviceId}, session: ${sourceDeviceId}`,
160
158
  );
161
159
  return;
162
160
  }
163
161
 
164
162
  if (message.data) {
165
163
  useClawLogger().info(
166
- `[yoyoclaw-channel] forwarding user message to node gateway from ${hardwareDeviceId}, session: ${sourceDeviceId}`
164
+ `[yoyoclaw-channel] forwarding user message to node gateway from ${hardwareDeviceId}, session: ${sourceDeviceId}`,
167
165
  );
168
166
  nodeGatewayClient.send(message.data);
169
167
  }
170
168
  } catch (error) {
171
169
  useClawLogger().error(
172
- `[yoyoclaw-channel] failed to send node gateway message to ${hardwareDeviceId}: ${String(error)}, session: ${sourceDeviceId}`
170
+ `[yoyoclaw-channel] failed to send node gateway message to ${hardwareDeviceId}: ${String(error)}, session: ${sourceDeviceId}`,
173
171
  );
174
172
  }
175
173
  }
@@ -180,7 +178,9 @@ export class MessageHandler {
180
178
  handleNodeGatewayMessage = (sourceDeviceId: string, data: string): void => {
181
179
  const hardwareDeviceId = this.sessionManager.getHardwareDeviceId(sourceDeviceId);
182
180
  if (!hardwareDeviceId) {
183
- useClawLogger().warn(`[yoyoclaw-channel] node gateway source offline, session: ${sourceDeviceId}`);
181
+ useClawLogger().warn(
182
+ `[yoyoclaw-channel] node gateway source offline, session: ${sourceDeviceId}`,
183
+ );
184
184
  return;
185
185
  }
186
186
 
@@ -188,29 +188,36 @@ export class MessageHandler {
188
188
  const deviceId = sessionInfo?.sourceInfo.sourceDeviceInfo?.deviceId;
189
189
 
190
190
  if (!sessionInfo) {
191
- useClawLogger().warn(`[yoyoclaw-channel] node gateway source offline, session: ${sourceDeviceId}`);
191
+ useClawLogger().warn(
192
+ `[yoyoclaw-channel] node gateway source offline, session: ${sourceDeviceId}`,
193
+ );
192
194
  return;
193
195
  }
194
196
 
195
- useClawLogger().debug?.(
196
- `[yoyoclaw-channel] received node gateway message from ${deviceId} to cloud:, ${data.slice(0, 1000)}`
197
- );
197
+ useClawLogger().info(`[yoyoclaw-channel] received node gateway message from ${deviceId}`);
198
198
 
199
199
  try {
200
200
  // 使用当前接收到的socket对应deviceId的来源信息
201
201
  const targetDeviceId = sessionInfo.sourceInfo.sourceDeviceId;
202
+
203
+ useClawLogger().debug?.(
204
+ `[yoyoclaw-channel] trans gateway msg to cloud device: ${targetDeviceId}, ${data.slice(0, 1000)}`,
205
+ );
206
+
202
207
  const result = this.sendMessage("userMessage", targetDeviceId, data, undefined, deviceId);
203
208
 
204
209
  if (!result) {
205
210
  // 云socket挂了,这个gateway连接就需要取消掉
206
211
  // 最好不要一次性把所有的gateway连接都干掉,让惰性关闭
207
212
  useClawLogger().error(
208
- `[yoyoclaw-channel] failed to send message, cloud socket closed, from ${targetDeviceId}`
213
+ `[yoyoclaw-channel] failed to send message, cloud socket closed, from ${targetDeviceId}`,
209
214
  );
210
215
  this.sessionManager.closeNodeGatewayClient(targetDeviceId);
211
216
  }
212
217
  } catch (error) {
213
- useClawLogger().error(`[yoyoclaw-channel] failed to handle node gateway message: ${String(error)}`);
218
+ useClawLogger().error(
219
+ `[yoyoclaw-channel] failed to handle node gateway message: ${String(error)}`,
220
+ );
214
221
  }
215
222
  };
216
223
 
@@ -227,7 +234,7 @@ export class MessageHandler {
227
234
  return;
228
235
  }
229
236
 
230
- if (!await this.adminClientManager.waitForReady()) {
237
+ if (!(await this.adminClientManager.waitForReady())) {
231
238
  useClawLogger().error("[yoyoclaw-channel] admin gateway client not ready after retry");
232
239
  this.sendResponse("updateContexts", message.sourceDeviceId, {
233
240
  success: false,
@@ -276,7 +283,7 @@ export class MessageHandler {
276
283
  private async handleFetchContexts(message: YoyoClawMessage): Promise<void> {
277
284
  useClawLogger().info("[yoyoclaw-channel] handling fetchContexts message");
278
285
 
279
- if (!await this.adminClientManager.waitForReady()) {
286
+ if (!(await this.adminClientManager.waitForReady())) {
280
287
  useClawLogger().error("[yoyoclaw-channel] admin gateway client not ready after retry");
281
288
  this.sendResponse("fetchContexts", message.sourceDeviceId, {
282
289
  success: false,
@@ -288,17 +295,18 @@ export class MessageHandler {
288
295
  try {
289
296
  const context = message.contexts?.[0];
290
297
  const client = this.adminClientManager.getClient()!;
291
- const { name } = context.header;
298
+ const { name } = context?.header || {};
292
299
  if (name === "skills") {
293
300
  const result = await client.getSkillsStatus();
294
- const skills = result.skills
295
- ?.filter(v => v.eligible)
296
- .map(v => ({
297
- name: v.name,
298
- description: v.description,
299
- source: v.source,
300
- disableModelInvocation: v.disabled,
301
- })) ?? [];
301
+ const skills =
302
+ result.skills
303
+ ?.filter((v) => v.eligible)
304
+ .map((v) => ({
305
+ name: v.name,
306
+ description: v.description,
307
+ source: v.source,
308
+ disableModelInvocation: v.disabled,
309
+ })) ?? [];
302
310
  this.sendResponse("fetchContexts", message.sourceDeviceId, { success: true }, [
303
311
  { header: { name: "skills", namespace: "yoyoclaw" }, payload: { skills } },
304
312
  ]);
@@ -324,7 +332,7 @@ export class MessageHandler {
324
332
  targetDeviceId: string,
325
333
  data: string | Record<string, any>,
326
334
  contexts?: YoyoClawMessage["contexts"],
327
- logDeviceId?: string
335
+ logDeviceId?: string,
328
336
  ): boolean {
329
337
  const message: YoyoClawMessage = {
330
338
  msgType,
@@ -343,7 +351,7 @@ export class MessageHandler {
343
351
  msgType: "updateContexts" | "fetchContexts",
344
352
  targetDeviceId: string,
345
353
  data: Record<string, any>,
346
- contexts?: YoyoClawMessage["contexts"]
354
+ contexts?: YoyoClawMessage["contexts"],
347
355
  ): void {
348
356
  this.sendMessage(msgType, targetDeviceId, data, contexts);
349
357
  }
@@ -1,11 +1,12 @@
1
- import type { DeviceSessionInfo } from "./types.js";
1
+ import type { ClawDeviceInfo } from "src/types.js";
2
2
  import { NodeGatewayClient, type NodeStatusEvent } from "../gateway-client/node-gateway-client.js";
3
3
  import { useClawLogger } from "../utils/logger.js";
4
+ import type { DeviceSessionInfo } from "./types.js";
4
5
 
5
6
  export interface CreateNodeGatewayClientOptions {
6
7
  sessionId: string;
7
8
  hardwareDeviceId: string;
8
- deviceInfo: any;
9
+ deviceInfo: ClawDeviceInfo;
9
10
  onMessage: (data: string) => void;
10
11
  onStatusEvent: (event: NodeStatusEvent) => void;
11
12
  }
@@ -42,7 +43,9 @@ export class SessionManager {
42
43
 
43
44
  getSession(sessionId: string): DeviceSessionInfo | undefined {
44
45
  const hardwareDeviceId = this.sessionIdToHardwareDeviceMap.get(sessionId);
45
- if (!hardwareDeviceId) return undefined;
46
+ if (!hardwareDeviceId) {
47
+ return undefined;
48
+ }
46
49
  const sessions = this.deviceSessionsMap.get(hardwareDeviceId);
47
50
  return sessions?.find((s) => s.sessionId === sessionId);
48
51
  }
@@ -82,24 +85,26 @@ export class SessionManager {
82
85
  this.nodeGatewayClientsMap.delete(sessionId);
83
86
  this.removeSession(sessionId);
84
87
  useClawLogger().info(
85
- `[yoyoclaw-channel] closed node gateway client for session: ${sessionId}`
88
+ `[yoyoclaw-channel] closed node gateway client for session: ${sessionId}`,
86
89
  );
87
90
  }
88
91
  }
89
92
 
90
93
  /**
91
- * 关闭硬件设备的所有前序 GatewayClient(timestamp 小于指定值)
92
- */
94
+ * 关闭硬件设备的所有前序 GatewayClient(timestamp 小于指定值)
95
+ */
93
96
  closePreviousNodeGatewayClients(hardwareDeviceId: string, newTimestamp: number): void {
94
97
  const sessions = this.deviceSessionsMap.get(hardwareDeviceId);
95
- if (!sessions || sessions.length === 0) return;
98
+ if (!sessions || sessions.length === 0) {
99
+ return;
100
+ }
96
101
 
97
102
  // 找出所有 timestamp 小于新 timestamp 的会话
98
103
  const previousSessions = sessions.filter((s) => s.timestamp < newTimestamp);
99
104
 
100
105
  if (previousSessions.length > 0) {
101
106
  useClawLogger().info(
102
- `[yoyoclaw-channel] closing ${previousSessions.length} previous node gateway client(s) for hardware device: ${hardwareDeviceId}, new timestamp: ${newTimestamp}`
107
+ `[yoyoclaw-channel] closing ${previousSessions.length} previous node gateway client(s) for hardware device: ${hardwareDeviceId}, new timestamp: ${newTimestamp}`,
103
108
  );
104
109
  for (const session of previousSessions) {
105
110
  this.closeNodeGatewayClient(session.sessionId);
@@ -114,7 +119,7 @@ export class SessionManager {
114
119
  for (const [sessionId, client] of this.nodeGatewayClientsMap.entries()) {
115
120
  client.stop();
116
121
  useClawLogger().info(
117
- `[yoyoclaw-channel] closed node gateway client for session: ${sessionId}`
122
+ `[yoyoclaw-channel] closed node gateway client for session: ${sessionId}`,
118
123
  );
119
124
  }
120
125
  this.nodeGatewayClientsMap.clear();