@honor-claw/yoyo 1.1.4-beta.5 → 1.1.4-beta.6

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.
@@ -26,7 +26,19 @@
26
26
  "device": {
27
27
  "type": "object",
28
28
  "properties": {
29
- "deviceType": {
29
+ "type": {
30
+ "type": "string"
31
+ },
32
+ "manufacture": {
33
+ "type": "string"
34
+ },
35
+ "brand": {
36
+ "type": "string"
37
+ },
38
+ "name": {
39
+ "type": "string"
40
+ },
41
+ "model": {
30
42
  "type": "string"
31
43
  }
32
44
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honor-claw/yoyo",
3
- "version": "1.1.4-beta.5",
3
+ "version": "1.1.4-beta.6",
4
4
  "description": "OpenClaw Honor Yoyo connection plugin",
5
5
  "keywords": [
6
6
  "ai",
@@ -56,8 +56,8 @@ export class ClawCloudClient {
56
56
  role: "yoyoclaw",
57
57
  deviceInfo: {
58
58
  ...deviceInfo,
59
- manufacture: "unknown",
60
- brand: deviceInfo.brand || "unknown",
59
+ manufacture: deviceInfo.manufacture,
60
+ brand: deviceInfo.brand,
61
61
  bizExtInfo: gatewayAuthConfig,
62
62
  },
63
63
  };
@@ -444,7 +444,7 @@ export class MessageHandler {
444
444
  this.sendContextResponse(msgType, sourceDeviceId, traceInfo, reqContext, {
445
445
  ok: false,
446
446
  error: result.error,
447
- ...(result?.data || {}),
447
+ ...result?.data,
448
448
  ...(isUpdate && { name: contextName }),
449
449
  });
450
450
  }
@@ -8,7 +8,7 @@ import { wrapError } from "../../utils/error.js";
8
8
  import { useClawLogger } from "../../utils/logger.js";
9
9
  import { isBetaVersion } from "../../utils/version.js";
10
10
  import { detectProvidersToRename, updateProviderReferences } from "./provider.js";
11
- import type { GatewayAuthConfig, UserConfig } from "./types.ts";
11
+ import type { DeviceConfig, GatewayAuthConfig, UserConfig } from "./types.ts";
12
12
 
13
13
  const PLUGIN_YOYO_ID = "yoyo";
14
14
  const YOYO_ALLOW_COMMANDS = [
@@ -167,6 +167,60 @@ export class ConfigManager {
167
167
  }
168
168
  }
169
169
 
170
+ /**
171
+ * 获取设备配置
172
+ */
173
+ getDeviceConfig(): DeviceConfig | undefined {
174
+ try {
175
+ const config = this.loadConfig();
176
+ const deviceConfig = config.plugins?.entries?.[PLUGIN_YOYO_ID]?.config?.device as
177
+ | DeviceConfig
178
+ | undefined;
179
+ return deviceConfig;
180
+ } catch (error) {
181
+ console.error(`[claw-configs] Failed to read device config: ${error}`);
182
+ return undefined;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * 更新设备配置
188
+ */
189
+ async updateDeviceConfig(deviceConfig: DeviceConfig): Promise<void> {
190
+ try {
191
+ const currentConfig = this.loadConfig();
192
+
193
+ // 合并现有设备配置
194
+ const existingDeviceConfig =
195
+ (currentConfig.plugins?.entries?.[PLUGIN_YOYO_ID]?.config?.device as DeviceConfig | undefined) || {};
196
+
197
+ const updatedConfig: OpenClawConfig = {
198
+ ...currentConfig,
199
+ plugins: {
200
+ ...currentConfig.plugins,
201
+ entries: {
202
+ ...currentConfig.plugins?.entries,
203
+ [PLUGIN_YOYO_ID]: {
204
+ ...currentConfig.plugins?.entries?.[PLUGIN_YOYO_ID],
205
+ enabled: true,
206
+ config: {
207
+ ...currentConfig.plugins?.entries?.[PLUGIN_YOYO_ID]?.config,
208
+ device: {
209
+ ...existingDeviceConfig,
210
+ ...deviceConfig,
211
+ },
212
+ },
213
+ },
214
+ },
215
+ },
216
+ };
217
+
218
+ await this.saveConfig(updatedConfig);
219
+ } catch (error) {
220
+ throw wrapError(error, "Failed to update device config");
221
+ }
222
+ }
223
+
170
224
  /**
171
225
  * 更新运行环境配置
172
226
  */
@@ -33,5 +33,18 @@ export interface YoyoClawPluginConfig {
33
33
  env?: "dev" | "test" | "production";
34
34
  /** 灰度标签 */
35
35
  gray?: string;
36
+ /** 设备配置 */
37
+ device?: DeviceConfig;
36
38
  };
37
39
  }
40
+
41
+ /**
42
+ * 设备配置信息
43
+ */
44
+ export interface DeviceConfig {
45
+ brand?: string;
46
+ type?: string;
47
+ manufacture?: string;
48
+ name?: string;
49
+ model?: string;
50
+ }
@@ -2,6 +2,7 @@
2
2
  * 设备信息获取模块
3
3
  */
4
4
  import type { DeviceInfo } from "../../types.js";
5
+ import { getDeviceEnvVars } from "../../utils/env.js";
5
6
  import { useClawLogger } from "../../utils/logger.js";
6
7
  import { getConfigManager } from "../configs/config-manager.js";
7
8
  import { loadOrCreateDeviceIdentity } from "./identity.js";
@@ -9,6 +10,7 @@ import { getDeviceInfoProvider } from "./providers/index.js";
9
10
 
10
11
  /**
11
12
  * 获取设备信息(异步版本)
13
+ * 优先级: env > config > provider
12
14
  */
13
15
  export async function getDeviceInfo(): Promise<DeviceInfo> {
14
16
  const provider = getDeviceInfoProvider();
@@ -31,17 +33,57 @@ export async function getDeviceInfo(): Promise<DeviceInfo> {
31
33
  deviceId = await provider.getDeviceIdAsync();
32
34
  }
33
35
 
36
+ // 获取设备信息,优先级: env > config > provider
37
+ const envVars = getDeviceEnvVars();
38
+ const deviceConfig = configManager.getDeviceConfig();
39
+
40
+ useClawLogger().debug?.(`[yoyoclaw-device] env: ${JSON.stringify(envVars)}, config: ${JSON.stringify(deviceConfig)}`);
41
+
42
+ // 按优先级获取,并限制 128 字符
43
+ const brand = envVars.brand || deviceConfig?.brand || provider.getDeviceBrand() || "unknown";
44
+ const deviceType = (envVars.deviceType ||
45
+ deviceConfig?.type ||
46
+ provider.getDeviceType()) as DeviceInfo["deviceType"];
47
+ const manufacture = (envVars.manufacture || deviceConfig?.manufacture || brand).slice(0, 128);
48
+ const deviceName = (deviceConfig?.name || provider.getDeviceName()).slice(0, 128);
49
+ const deviceModel = (deviceConfig?.model || provider.getDeviceModel()).slice(0, 128);
50
+
34
51
  const deviceInfo: DeviceInfo = {
35
52
  deviceId,
36
- deviceName: provider.getDeviceName().slice(0, 128),
37
- deviceType: provider.getDeviceType(),
38
- deviceModel: provider.getDeviceModel().slice(0, 128),
39
- brand: provider.getDeviceBrand(),
53
+ deviceName,
54
+ deviceType,
55
+ deviceModel,
56
+ brand,
57
+ manufacture,
40
58
  port: configManager.getGatewayPort(),
41
59
  };
42
60
 
43
- useClawLogger().debug?.(
44
- `[yoyoclaw-device] device info: ${JSON.stringify(deviceInfo)} (deviceId source: ${deviceIdSource})`,
61
+ // 记录 deviceInfo 整体来源
62
+ const source = envVars.brand || envVars.deviceType || envVars.manufacture ? "env" : "config";
63
+ useClawLogger().info(
64
+ `[yoyoclaw-device] device info: ${JSON.stringify(deviceInfo)} (deviceId source: ${deviceIdSource}, source: ${source})`,
65
+ );
66
+
67
+ // env 与 config 的差异检测(key 映射: brand, manufacture, deviceType -> type)
68
+ const hasEnvDiff = !!(
69
+ (envVars.brand && envVars.brand !== deviceConfig?.brand) ||
70
+ (envVars.manufacture && envVars.manufacture !== deviceConfig?.manufacture) ||
71
+ (envVars.deviceType && envVars.deviceType !== deviceConfig?.type)
45
72
  );
73
+
74
+ if (!deviceConfig || hasEnvDiff) {
75
+ const configUpdate = {
76
+ brand,
77
+ type: deviceType,
78
+ manufacture,
79
+ name: deviceName,
80
+ model: deviceModel,
81
+ };
82
+
83
+ configManager.updateDeviceConfig(configUpdate).catch((error) => {
84
+ useClawLogger().warn(`[yoyoclaw-device] failed to persist device config: ${String(error)}`);
85
+ });
86
+ }
87
+
46
88
  return deviceInfo;
47
89
  }
package/src/schemas.ts CHANGED
@@ -14,7 +14,11 @@ const UserInfoSchema = z.object({
14
14
  * 设备信息配置
15
15
  */
16
16
  const DeviceInfoSchema = z.object({
17
- deviceType: z.string().optional(),
17
+ type: z.string().optional(),
18
+ manufacture: z.string().optional(),
19
+ brand: z.string().optional(),
20
+ name: z.string().optional(),
21
+ model: z.string().optional(),
18
22
  });
19
23
 
20
24
  /**
package/src/types.ts CHANGED
@@ -22,6 +22,10 @@ export interface DeviceInfo {
22
22
  * 品牌信息
23
23
  */
24
24
  brand: string;
25
+ /**
26
+ * 制造商信息
27
+ */
28
+ manufacture: string;
25
29
  port: number;
26
30
  }
27
31
 
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 环境变量工具模块
3
+ */
4
+
5
+ const DEVICE_ENV_VARS = {
6
+ brand: "YOYO_CLAW_BRAND",
7
+ manufacture: "YOYO_CLAW_MANUFACTURER",
8
+ deviceType: "YOYO_CLAW_DEVICE_TYPE",
9
+ } as const;
10
+
11
+ /**
12
+ * 设备相关的环境变量
13
+ */
14
+ export interface DeviceEnvVars {
15
+ brand?: string;
16
+ manufacture?: string;
17
+ deviceType?: string;
18
+ }
19
+
20
+ /**
21
+ * 批量获取所有设备相关的环境变量
22
+ */
23
+ export function getDeviceEnvVars(): DeviceEnvVars {
24
+ return {
25
+ brand: process.env[DEVICE_ENV_VARS.brand],
26
+ manufacture: process.env[DEVICE_ENV_VARS.manufacture],
27
+ deviceType: process.env[DEVICE_ENV_VARS.deviceType],
28
+ };
29
+ }