@honor-claw/yoyo 1.2.0-beta.6 → 1.2.0-beta.8
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/package.json
CHANGED
package/src/apis/claw-cloud.ts
CHANGED
|
@@ -109,10 +109,11 @@ export class ClawCloudClient {
|
|
|
109
109
|
params: ExchangeTokenParams,
|
|
110
110
|
): Promise<TokenResponseV2> {
|
|
111
111
|
// 构建请求头
|
|
112
|
+
const traceId = uuid();
|
|
112
113
|
const headers: ExchangeTokenHeaders = {
|
|
113
114
|
"Content-Type": "application/json",
|
|
114
115
|
"x-device-id": deviceInfo.deviceId,
|
|
115
|
-
"x-trace-id":
|
|
116
|
+
"x-trace-id": traceId,
|
|
116
117
|
};
|
|
117
118
|
|
|
118
119
|
let data: ExchangeTokenRequest = {};
|
|
@@ -142,7 +143,7 @@ export class ClawCloudClient {
|
|
|
142
143
|
return response.data.data;
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
throw new Error(`failed to get token: ${response.data
|
|
146
|
+
throw new Error(`failed to get token: ${JSON.stringify(response.data)}, traceId: ${traceId}`);
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
|
|
@@ -32,7 +32,7 @@ export class ClawChannel {
|
|
|
32
32
|
config: {
|
|
33
33
|
deviceInfo: config.deviceInfo,
|
|
34
34
|
onStatusEvent: this.handleStatusEvent,
|
|
35
|
-
onReply: (message
|
|
35
|
+
onReply: (message) => this.cloudClient.send(message),
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -151,7 +151,7 @@ export class ClawCloudSocketClient {
|
|
|
151
151
|
/**
|
|
152
152
|
* 发送消息
|
|
153
153
|
*/
|
|
154
|
-
send(message: YOYOClawServiceEvent
|
|
154
|
+
send(message: YOYOClawServiceEvent): boolean {
|
|
155
155
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
156
156
|
useClawLogger().error("[claw-cloud-socket] cannot send message: connection not open");
|
|
157
157
|
return false;
|
|
@@ -165,7 +165,7 @@ export class ClawCloudSocketClient {
|
|
|
165
165
|
} catch (error) {
|
|
166
166
|
useClawLogger().error(
|
|
167
167
|
`[claw-cloud-socket] failed to send message to cloud session ${message.targetDeviceId},
|
|
168
|
-
|
|
168
|
+
${error instanceof Error ? error.message : String(error)}`,
|
|
169
169
|
);
|
|
170
170
|
return false;
|
|
171
171
|
}
|
|
@@ -254,7 +254,7 @@ export class MessageHandler {
|
|
|
254
254
|
}
|
|
255
255
|
} catch (error) {
|
|
256
256
|
useClawLogger().error(
|
|
257
|
-
`${LOG_PREFIX} failed to send gateway message to
|
|
257
|
+
`${LOG_PREFIX} failed to send gateway message to device: ${hardwareDeviceId}, session: ${sourceDeviceId}, ${String(error)}`,
|
|
258
258
|
);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
@@ -356,43 +356,40 @@ export class MessageHandler {
|
|
|
356
356
|
try {
|
|
357
357
|
// 使用当前接收到的socket对应deviceId的来源信息
|
|
358
358
|
const targetDeviceId = sessionInfo.sourceInfo.sourceDeviceId;
|
|
359
|
-
const gatewayRawData = JSON.parse(data);
|
|
360
|
-
let cloudData = data;
|
|
361
359
|
|
|
362
360
|
// 收到NOT_PAIRED错误时,自动获取待配对设备并审批
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
useClawLogger().
|
|
375
|
-
|
|
376
|
-
|
|
361
|
+
let rawData: Record<string, any>;
|
|
362
|
+
try {
|
|
363
|
+
rawData = JSON.parse(data);
|
|
364
|
+
} catch {
|
|
365
|
+
useClawLogger().warn(`${LOG_PREFIX} gateway message is not valid JSON`);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (!rawData.ok && rawData.error?.code === "NOT_PAIRED") {
|
|
370
|
+
const requestId = rawData.error?.details?.requestId;
|
|
371
|
+
if (!requestId) {
|
|
372
|
+
useClawLogger().warn(`${LOG_PREFIX} NOT_PAIRED without requestId, ignoring...`);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const success = await this.handleAutoPair(requestId);
|
|
376
|
+
if (success) {
|
|
377
|
+
const bizExtInfo = { id: rawData.id, type: "reconnect-required" };
|
|
378
|
+
this.sendMessage("deviceControl", targetDeviceId, traceInfo, "", undefined, bizExtInfo);
|
|
379
|
+
useClawLogger().info(`${LOG_PREFIX} auto pair is completed, requestId: ${requestId}`);
|
|
380
|
+
return;
|
|
377
381
|
}
|
|
378
382
|
}
|
|
379
383
|
|
|
380
384
|
useClawLogger().debug?.(
|
|
381
|
-
`${LOG_PREFIX} trans gateway msg to cloud
|
|
385
|
+
`${LOG_PREFIX} trans gateway msg to cloud, session: ${targetDeviceId}, data: ${data.slice(0, 1000)}`,
|
|
382
386
|
);
|
|
383
387
|
|
|
384
|
-
const result = this.sendMessage(
|
|
385
|
-
"userMessage",
|
|
386
|
-
targetDeviceId,
|
|
387
|
-
traceInfo,
|
|
388
|
-
cloudData,
|
|
389
|
-
undefined,
|
|
390
|
-
deviceId,
|
|
391
|
-
);
|
|
388
|
+
const result = this.sendMessage("userMessage", targetDeviceId, traceInfo, data);
|
|
392
389
|
if (!result) {
|
|
393
|
-
// 云socket挂了,这个gateway连接就需要取消掉,最好不要一次性把所有的gateway
|
|
390
|
+
// 云socket挂了,这个gateway连接就需要取消掉,最好不要一次性把所有的gateway连接都干掉,让惰性关闭,以及设备ID的打印放到这里了
|
|
394
391
|
useClawLogger().error(
|
|
395
|
-
`${LOG_PREFIX} failed to send message, cloud socket closed,
|
|
392
|
+
`${LOG_PREFIX} failed to send message, cloud socket closed, session ${targetDeviceId}, device ${deviceId}`,
|
|
396
393
|
);
|
|
397
394
|
this.sessionManager.closeNodeGatewayClient(targetDeviceId);
|
|
398
395
|
}
|
|
@@ -401,26 +398,25 @@ export class MessageHandler {
|
|
|
401
398
|
}
|
|
402
399
|
};
|
|
403
400
|
|
|
404
|
-
private async handleAutoPair(): Promise<
|
|
401
|
+
private async handleAutoPair(requestId: string): Promise<boolean> {
|
|
405
402
|
const adminClient = this.adminClientManager.getClient();
|
|
406
403
|
if (!adminClient) {
|
|
407
404
|
useClawLogger().warn(`${LOG_PREFIX} admin client not available for auto pair`);
|
|
408
|
-
return;
|
|
405
|
+
return false;
|
|
409
406
|
}
|
|
410
407
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
408
|
+
try {
|
|
409
|
+
useClawLogger().info(`${LOG_PREFIX} auto pair approve, requestId: ${requestId}`);
|
|
410
|
+
const res = await adminClient.devicePairApprove(requestId);
|
|
411
|
+
if (!res.ok) {
|
|
412
|
+
throw new Error(JSON.stringify(res.error));
|
|
413
|
+
}
|
|
414
|
+
return true;
|
|
415
|
+
} catch (error) {
|
|
416
|
+
useClawLogger().error(
|
|
417
|
+
`${LOG_PREFIX} auto pair approve failed, requestId: ${requestId}, error: ${String(error)}`,
|
|
418
418
|
);
|
|
419
|
-
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
if (pendingDevices.length === 0) {
|
|
423
|
-
useClawLogger().info(`${LOG_PREFIX} no pending devices found for auto pair`);
|
|
419
|
+
return false;
|
|
424
420
|
}
|
|
425
421
|
}
|
|
426
422
|
|
|
@@ -502,9 +498,9 @@ export class MessageHandler {
|
|
|
502
498
|
msgType: YOYOClawServiceEvent["msgType"],
|
|
503
499
|
targetDeviceId: string,
|
|
504
500
|
traceInfo: YOYOClawServiceEvent["traceInfo"],
|
|
505
|
-
data
|
|
501
|
+
data?: string | Record<string, unknown>,
|
|
506
502
|
contexts?: YOYOClawServiceEvent["contexts"],
|
|
507
|
-
|
|
503
|
+
bizExtInfo?: Record<string, unknown>,
|
|
508
504
|
): boolean {
|
|
509
505
|
const message: YOYOClawServiceEvent = {
|
|
510
506
|
msgType,
|
|
@@ -516,8 +512,9 @@ export class MessageHandler {
|
|
|
516
512
|
port: this.config.deviceInfo.port,
|
|
517
513
|
data: typeof data === "string" ? data : JSON.stringify(data),
|
|
518
514
|
contexts,
|
|
515
|
+
bizExtInfo,
|
|
519
516
|
};
|
|
520
|
-
return this.config.onReply(message,
|
|
517
|
+
return this.config.onReply(message, targetDeviceId);
|
|
521
518
|
}
|
|
522
519
|
|
|
523
520
|
private validateContext(context?: YOYOClawServiceContext): {
|
|
@@ -27,7 +27,8 @@ export interface YOYOClawServiceEvent {
|
|
|
27
27
|
| "devicePairMessage"
|
|
28
28
|
| "deviceUnPairMessage"
|
|
29
29
|
| "fetchContexts"
|
|
30
|
-
| "updateContexts"
|
|
30
|
+
| "updateContexts"
|
|
31
|
+
| "deviceControl";
|
|
31
32
|
/**
|
|
32
33
|
* 会话轮次等追加信息,只有配对消息有
|
|
33
34
|
*/
|
|
@@ -38,6 +39,10 @@ export interface YOYOClawServiceEvent {
|
|
|
38
39
|
* 上下文信息
|
|
39
40
|
*/
|
|
40
41
|
contexts?: YOYOClawServiceContext[];
|
|
42
|
+
/**
|
|
43
|
+
* 业务扩展信息
|
|
44
|
+
*/
|
|
45
|
+
bizExtInfo?: Record<string, any>;
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
/**
|