@honor-claw/yoyo 2026.6.9-beta.8 → 2026.7.1-alpha.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/dist/capabilities/node/directory.mjs +2 -2
  2. package/dist/capabilities/node/invoke.mjs +27 -22
  3. package/dist/channel/messaging.mjs +13 -13
  4. package/dist/cli/index.mjs +2 -2
  5. package/dist/cli/login/impl.mjs +1 -1
  6. package/dist/cli/logout/impl.mjs +17 -7
  7. package/dist/cloud-channel/dispatcher/impl.mjs +13 -19
  8. package/dist/cloud-channel/transport/cloud-socket.mjs +7 -4
  9. package/dist/command/diagnose.mjs +3 -4
  10. package/dist/command/doctor.mjs +3 -3
  11. package/dist/core/hooks/tool-trace.mjs +24 -18
  12. package/dist/core/prompt/cloud-tool.mjs +1 -1
  13. package/dist/diagnose/chat-id-resolver.mjs +42 -0
  14. package/dist/diagnose/index.mjs +2 -1
  15. package/dist/diagnose/report/diagnose.mjs +26 -21
  16. package/dist/diagnose/report/doctor/device-check.mjs +72 -0
  17. package/dist/diagnose/report/doctor/impl.mjs +95 -0
  18. package/dist/diagnose/report/doctor/index.mjs +1 -0
  19. package/dist/diagnose/report/formatter.mjs +1 -3
  20. package/dist/diagnose/report/index.mjs +2 -1
  21. package/dist/diagnose/report/status.mjs +21 -34
  22. package/dist/diagnose/report/trace.mjs +68 -21
  23. package/dist/honor-auth/browser/result-page.mjs +125 -75
  24. package/dist/honor-auth/logout.mjs +6 -6
  25. package/dist/index.mjs +1 -1
  26. package/dist/messaging/dispatchers/stream/controller.mjs +3 -0
  27. package/dist/messaging/dispatchers/stream/error.mjs +13 -0
  28. package/dist/messaging/inbound/context.mjs +18 -15
  29. package/dist/messaging/inbound/interrupt.mjs +1 -1
  30. package/dist/messaging/inbound/new-session.mjs +1 -1
  31. package/dist/messaging/index.mjs +1 -1
  32. package/dist/messaging/target/address.mjs +24 -13
  33. package/dist/messaging/target/index.mjs +1 -1
  34. package/dist/messaging/target/outbound.mjs +9 -9
  35. package/dist/messaging/trace/index.mjs +1 -0
  36. package/dist/messaging/trace/lifecycle.mjs +18 -12
  37. package/dist/messaging/trace/storage.mjs +26 -24
  38. package/dist/messaging/trace/tool-context.mjs +30 -0
  39. package/dist/modules/configs/channel.mjs +12 -3
  40. package/dist/modules/configs/plugin-init.mjs +35 -43
  41. package/dist/utils/object.mjs +8 -0
  42. package/dist/utils/version.mjs +21 -16
  43. package/package.json +1 -1
  44. package/skills/yoyo-phone-control/SKILL.md +3 -13
  45. package/skills/yoyo-phone-control/configs/sub-skills.json +1 -15
  46. package/skills/yoyo-phone-control/references/gui-task-create.md +12 -12
  47. package/skills/yoyo-phone-control/references/{local_user_data_qa.md → local-user-data-qa.md} +18 -34
  48. package/skills/yoyo-phone-control/references/{local_user_file_search.md → local-user-file-search.md} +10 -10
  49. package/skills/yoyo-phone-control/references/{task_result_query.md → task-result-query.md} +2 -2
  50. package/skills/yoyo-smart-home/mcptools/device_control.json +1 -1
  51. package/skills/yoyo-smart-home/mcptools/device_query.json +1 -1
  52. package/dist/command/context.mjs +0 -20
  53. package/dist/diagnose/report/doctor.mjs +0 -121
  54. package/dist/utils/array.mjs +0 -6
  55. package/skills/yoyo-phone-control/references/alarm-create.md +0 -356
  56. package/skills/yoyo-phone-control/references/alarm-delete.md +0 -301
  57. package/skills/yoyo-phone-control/references/alarm-disable.md +0 -309
  58. package/skills/yoyo-phone-control/references/alarm-enable.md +0 -309
  59. package/skills/yoyo-phone-control/references/alarm-query.md +0 -411
  60. package/skills/yoyo-phone-control/references/alarm-update.md +0 -386
  61. package/skills/yoyo-phone-control/references/file-upload.md +0 -283
  62. package/skills/yoyo-phone-control/references/local-search.md +0 -221
  63. package/skills/yoyo-phone-control/references/schedule-create.md +0 -483
  64. package/skills/yoyo-phone-control/references/schedule-delete.md +0 -507
  65. package/skills/yoyo-phone-control/references/schedule-search.md +0 -591
  66. package/skills/yoyo-phone-control/references/schedule-update.md +0 -556
@@ -4,7 +4,7 @@ async function t() {
4
4
  return (await e()).devices;
5
5
  }
6
6
  async function n(t) {
7
- return (await e({ deviceIdList: [t] })).devices.find((e) => e.deviceId === t)?.online ?? !1;
7
+ return (await e({ deviceIdList: [t] })).devices.find((e) => e.deviceId === t);
8
8
  }
9
9
  //#endregion
10
- export { n as isDeviceReachable, t as listDevicesWithStatus };
10
+ export { n as getDeviceWithStatus, t as listDevicesWithStatus };
@@ -2,10 +2,12 @@ import { clawLogger as e } from "../../utils/claw-logger.mjs";
2
2
  import { buildEndpoint as t } from "../../cloud-channel/protocol/target.mjs";
3
3
  import { resolveEnabledYoyoAccountId as n } from "../../modules/configs/channel.mjs";
4
4
  import { ClawClient as r } from "../../connection/registry.mjs";
5
+ import { getToolCallContext as i } from "../../messaging/trace/tool-context.mjs";
6
+ import "../../messaging/trace/index.mjs";
5
7
  //#region src/capabilities/node/invoke.ts
6
- var i = e("capabilities");
7
- async function a(e) {
8
- let i = {
8
+ var a = e("capabilities");
9
+ async function o(e) {
10
+ let a = i(e.toolCallId) ?? void 0, o = {
9
11
  to: t("node", e.nodeId),
10
12
  msgType: "nodeInvokeRequest",
11
13
  data: { node: {
@@ -13,28 +15,31 @@ async function a(e) {
13
15
  nodeId: e.nodeId,
14
16
  name: e.name,
15
17
  ...e.params ? { params: { arguments: JSON.stringify(e.params) } } : {}
16
- } }
17
- }, a = n();
18
- return r.forAccount(a).request(i, {
18
+ } },
19
+ ...a ? { traceInfo: a } : {}
20
+ }, c = n();
21
+ return r.forAccount(c).request(o, {
19
22
  timeoutMs: e.timeoutMs,
20
- matchResult: o
23
+ matchResult: s(e.toolCallId)
21
24
  });
22
25
  }
23
- function o(e) {
24
- if (e.payload.msgType !== "nodeInvokeResult") return { matched: !1 };
25
- let t = e.data?.node;
26
- return !t || typeof t.runStatus != "number" || !t.nodeId || !t.toolCallId ? (i.warn("nodeInvokeResult missing required fields", { node: t }), {
27
- matched: !0,
28
- error: "missing required fields in invoke result"
29
- }) : {
30
- matched: !0,
31
- result: {
32
- nodeId: t.nodeId,
33
- toolCallId: t.toolCallId,
34
- runStatus: t.runStatus,
35
- result: t.result
36
- }
26
+ function s(e) {
27
+ return (t) => {
28
+ if (t.payload.msgType !== "nodeInvokeResult") return { matched: !1 };
29
+ let n = t.data?.node;
30
+ return !n || n.toolCallId !== e ? { matched: !1 } : typeof n.runStatus != "number" || !n.nodeId ? (a.warn("nodeInvokeResult missing required fields", { node: n }), {
31
+ matched: !0,
32
+ error: "missing required fields in invoke result"
33
+ }) : {
34
+ matched: !0,
35
+ result: {
36
+ nodeId: n.nodeId,
37
+ toolCallId: e,
38
+ runStatus: n.runStatus,
39
+ result: n.result
40
+ }
41
+ };
37
42
  };
38
43
  }
39
44
  //#endregion
40
- export { a as invokeNodeTool };
45
+ export { o as invokeNodeTool };
@@ -1,6 +1,6 @@
1
1
  import { YOYO_CHANNEL_ID as e } from "../consts.mjs";
2
- import { buildChatTo as t, buildFrom as n, readChatIdFromTo as r, readDeviceIdFromTo as i } from "../messaging/target/address.mjs";
3
- import { buildChatId as a, looksLikeChatId as o } from "../messaging/target/chat-id.mjs";
2
+ import { buildChatId as t, looksLikeChatId as n } from "../messaging/target/chat-id.mjs";
3
+ import { buildChatTo as r, buildFrom as i, readChatIdFromTo as a, readDeviceIdFromTo as o } from "../messaging/target/address.mjs";
4
4
  import { resolveOutboundTarget as s } from "../messaging/target/outbound.mjs";
5
5
  import { buildChannelOutboundSessionRoute as c, stripChannelTargetPrefix as l } from "openclaw/plugin-sdk/channel-core";
6
6
  //#region src/channel/messaging.ts
@@ -9,25 +9,25 @@ function u(t) {
9
9
  return d(n) ? n : void 0;
10
10
  }
11
11
  function d(e) {
12
- let t = r(e);
13
- if (t !== void 0) return t.length > 0 && o(t);
14
- let n = i(e);
15
- return n !== void 0 && n.length > 0;
12
+ let t = a(e);
13
+ if (t !== void 0) return t.length > 0 && n(t);
14
+ let r = o(e);
15
+ return r !== void 0 && r.length > 0;
16
16
  }
17
- async function f(r, i, o) {
18
- let s = await a(i, o);
17
+ async function f(n, a, o) {
18
+ let s = await t(a, o);
19
19
  return c({
20
- cfg: r.cfg,
21
- agentId: r.agentId,
20
+ cfg: n.cfg,
21
+ agentId: n.agentId,
22
22
  channel: e,
23
- accountId: i,
23
+ accountId: a,
24
24
  peer: {
25
25
  kind: "direct",
26
26
  id: s
27
27
  },
28
28
  chatType: "direct",
29
- from: n(s),
30
- to: t(s)
29
+ from: i(s),
30
+ to: r(s)
31
31
  });
32
32
  }
33
33
  async function p(e) {
@@ -10,8 +10,8 @@ import "./logout/index.mjs";
10
10
  //#region src/cli/index.ts
11
11
  function a(a) {
12
12
  a.registerCli((o) => {
13
- let s = o.program.command("honor").description("Commands for honor yoyoclaw");
14
- r(a, s), i(a, s), t(a, s), e() && n(a, s);
13
+ let s = o.program.command("honor").description("Commands for Honor yoyoclaw");
14
+ r(a, s), i(a, s), e() && (n(a, s), t(a, s));
15
15
  }, { commands: ["honor"] });
16
16
  }
17
17
  //#endregion
@@ -8,7 +8,7 @@ import "../../honor-auth/index.mjs";
8
8
  //#region src/cli/login/impl.ts
9
9
  var l = t("login-cli");
10
10
  function u(t, u) {
11
- u.command("login").description("login to yoyoclaw and register devices").option("-u, --uid <userId>", "login with a specific user ID").option("--token <token>", "login with a specific token").action(async (u) => e(t.runtime, async () => {
11
+ u.command("login").description("login to Honor and register devices").option("-u, --uid <userId>", "login with a specific user ID").option("--token <token>", "login with a specific token").action(async (u) => e(t.runtime, async () => {
12
12
  let { token: e } = u;
13
13
  l.debug("login CLI command called");
14
14
  let t = a(), d = await c({ token: e });
@@ -1,14 +1,24 @@
1
1
  import { withCommandRuntime as e } from "../../core/runtime.mjs";
2
2
  import { toErrorMessage as t } from "../../utils/error.mjs";
3
3
  import { clawLogger as n } from "../../utils/claw-logger.mjs";
4
- import { performLogout as r } from "../../honor-auth/logout.mjs";
4
+ import { loadConfig as r, saveConfig as i } from "../../modules/configs/config-store.mjs";
5
+ import { removeYoyoChannelAccount as a, resolveEnabledYoyoAccountId as o } from "../../modules/configs/channel.mjs";
6
+ import "../../modules/configs/index.mjs";
7
+ import { performLogout as s } from "../../honor-auth/logout.mjs";
5
8
  //#region src/cli/logout/impl.ts
6
- var i = n("logout-cli");
7
- function a(n, a) {
8
- a.command("logout").description("Logout and clear user configuration").action(async () => e(n.runtime, async () => {
9
- i.info("logout CLI command called");
9
+ var c = n("logout-cli");
10
+ function l(n, l) {
11
+ l.command("logout").description("Logout and clear user configuration").action(async () => e(n.runtime, async () => {
12
+ c.info("logout CLI command called");
13
+ let e = o();
10
14
  try {
11
- await r(), console.log("✅ Logout successful, gateway will automatically restart to handle new configuration");
15
+ await s(e);
16
+ try {
17
+ await i(a(r(), e));
18
+ } catch (t) {
19
+ c.error("failed to remove channel account after logout", t, { userId: e });
20
+ }
21
+ console.log("✅ Logout successful, gateway will automatically stop the account connection");
12
22
  } catch (e) {
13
23
  let n = t(e);
14
24
  console.error("🚫 Logout failed:", n);
@@ -16,4 +26,4 @@ function a(n, a) {
16
26
  }));
17
27
  }
18
28
  //#endregion
19
- export { a as registerLogoutCommand };
29
+ export { l as registerLogoutCommand };
@@ -21,13 +21,10 @@ function s(e) {
21
21
  send: u,
22
22
  async request(e, t) {
23
23
  let { matchResult: r, timeoutMs: i } = t, s = n();
24
- if (!await u({
25
- ...e,
26
- traceInfo: { traceId: s }
27
- })) throw Error("send failed");
24
+ if (!await u(e)) throw Error("send failed");
28
25
  return new Promise((e, t) => {
29
26
  let n = setTimeout(() => {
30
- l.has(s) && (l.delete(s), o.warn("request timeout", { traceId: s }), t(/* @__PURE__ */ Error("request timeout")));
27
+ l.has(s) && (l.delete(s), o.warn("request timeout", { requestId: s }), t(/* @__PURE__ */ Error("request timeout")));
31
28
  }, a(i));
32
29
  l.set(s, {
33
30
  timeout: n,
@@ -38,25 +35,22 @@ function s(e) {
38
35
  });
39
36
  },
40
37
  consume(e) {
41
- let t = e.payload.traceInfo?.traceId;
42
- if (!t) return;
43
- let n = l.get(t);
44
- if (n) {
38
+ for (let [t, n] of l) {
39
+ let r;
45
40
  try {
46
- let r = n.matchResult(e);
47
- if (r.matched) {
48
- if (l.delete(t), clearTimeout(n.timeout), "error" in r) {
49
- n.reject(r.error);
50
- return;
51
- }
52
- n.resolve(r.result);
53
- return;
54
- }
41
+ r = n.matchResult(e);
55
42
  } catch (e) {
56
43
  o.error("match request result failed", e);
44
+ continue;
45
+ }
46
+ if (r?.matched) {
47
+ if (l.delete(t), clearTimeout(n.timeout), "error" in r) {
48
+ n.reject(r.error);
49
+ return;
50
+ }
51
+ n.resolve(r.result);
57
52
  return;
58
53
  }
59
- o.warn("response shape not matched, keep pending", { traceId: t });
60
54
  }
61
55
  },
62
56
  destroy() {
@@ -13,6 +13,7 @@ var u = e("cloud-transport"), d = 3e4, f = 16e3, p = 1e3, m = 2, h = 5, g = clas
13
13
  isConnecting = !1;
14
14
  pingTimer = new c("recurring");
15
15
  currentTraceId = "";
16
+ lastErrorMessage = "";
16
17
  constructor(e) {
17
18
  this.options = e;
18
19
  }
@@ -43,7 +44,7 @@ var u = e("cloud-transport"), d = 3e4, f = 16e3, p = 1e3, m = 2, h = 5, g = clas
43
44
  }
44
45
  handleOpen = (e) => {
45
46
  let t = this.retryCount > 0 ? "reconnected" : "connected", r = e.slice(0, 15), i = /\/(v\d+)\//.exec(e)?.[1] ?? "", a = i ? `${r}.../${i}` : r;
46
- u.report(`${t} to ${a}`, { traceId: this.currentTraceId }), this.retryTimer.stop(), this.retryCount = 0, this.pingTimer.start(this.sendPing, d), n(), this.options.onOpen?.();
47
+ u.report(`${t} to ${a}`, { traceId: this.currentTraceId }), this.retryTimer.stop(), this.retryCount = 0, this.lastErrorMessage = "", this.pingTimer.start(this.sendPing, d), n(), this.options.onOpen?.();
47
48
  };
48
49
  handlePong = () => {};
49
50
  handleClose = (e, n) => {
@@ -58,7 +59,7 @@ var u = e("cloud-transport"), d = 3e4, f = 16e3, p = 1e3, m = 2, h = 5, g = clas
58
59
  u.report("connect errored", {
59
60
  traceId: this.currentTraceId,
60
61
  error: e
61
- }), e.message.includes("401") ? (o(e.message), this.options.onError?.({ type: "unauthorized" })) : i(e.message);
62
+ }), this.lastErrorMessage = e.message, e.message.includes("401") ? (o(e.message), this.options.onError?.({ type: "unauthorized" })) : i(e.message);
62
63
  };
63
64
  send(e, t = !1) {
64
65
  if (!this.ws || this.ws.readyState !== l.OPEN) return u.error("cannot send message: connection not open"), !1;
@@ -81,7 +82,9 @@ var u = e("cloud-transport"), d = 3e4, f = 16e3, p = 1e3, m = 2, h = 5, g = clas
81
82
  u.report("retry attempts exhausted, giving up", {
82
83
  traceId: this.currentTraceId,
83
84
  retryCount: this.retryCount
84
- }), e && i(`重试耗尽:${e}`, this.retryCount);
85
+ });
86
+ let t = e || this.lastErrorMessage;
87
+ t && i(`重试耗尽:${t}`, this.retryCount);
85
88
  return;
86
89
  }
87
90
  this.retryTimer.stop();
@@ -89,7 +92,7 @@ var u = e("cloud-transport"), d = 3e4, f = 16e3, p = 1e3, m = 2, h = 5, g = clas
89
92
  this.retryCount += 1, u.report("scheduling reconnect attempt", {
90
93
  retryCount: this.retryCount,
91
94
  delay: t
92
- }), a(e ?? "连接断开,重连中", this.retryCount), this.retryTimer.start(() => void this.connect(), t);
95
+ }), a(e || this.lastErrorMessage || "连接断开,重连中", this.retryCount), this.retryTimer.start(() => void this.connect(), t);
93
96
  }
94
97
  calculateRetryDelay() {
95
98
  let e = p * m ** Math.min(this.retryCount, 4);
@@ -1,10 +1,9 @@
1
- import { renderTraceReport as e, runTrace as t } from "../diagnose/report/trace.mjs";
1
+ import { resolveCommandCtx as e } from "../diagnose/chat-id-resolver.mjs";
2
+ import { renderTraceReport as t, runTrace as n } from "../diagnose/report/trace.mjs";
2
3
  import "../diagnose/index.mjs";
3
- import { resolveCommandChatId as n } from "./context.mjs";
4
4
  //#region src/command/diagnose.ts
5
5
  async function r(r, i) {
6
- let a = await n(r);
7
- return a ? e(t(a, i)) : "YOYO 控虾消息分析异常\n\n[WARN] 缺少可用的 chatId";
6
+ return t(n(await e(r), i));
8
7
  }
9
8
  //#endregion
10
9
  export { r as handleDiagnoseCommand };
@@ -1,9 +1,9 @@
1
- import { renderDoctorReport as e, runDoctor as t } from "../diagnose/report/doctor.mjs";
1
+ import { resolveCommandCtx as e } from "../diagnose/chat-id-resolver.mjs";
2
+ import { renderDoctorReport as t, runDoctor as n } from "../diagnose/report/doctor/impl.mjs";
2
3
  import "../diagnose/index.mjs";
3
- import { resolveCommandChatId as n } from "./context.mjs";
4
4
  //#region src/command/doctor.ts
5
5
  async function r(r) {
6
- return e(await t(await n(r), r.accountId));
6
+ return t(await n(await e(r), r.accountId));
7
7
  }
8
8
  //#endregion
9
9
  export { r as handleDoctorCommand };
@@ -1,26 +1,32 @@
1
- import { recordToolCallEnd as e, recordToolCallStart as t } from "../../messaging/dispatchers/stream/hooks.mjs";
1
+ import { bindToolCallContext as e, releaseToolCallContext as t } from "../../messaging/trace/tool-context.mjs";
2
+ import { resolveTurnSessionBySessionKey as n } from "../../messaging/trace/lifecycle.mjs";
3
+ import "../../messaging/trace/index.mjs";
4
+ import { recordToolCallEnd as r, recordToolCallStart as i } from "../../messaging/dispatchers/stream/hooks.mjs";
2
5
  //#region src/core/hooks/tool-trace.ts
3
- function n(n) {
4
- n.on("before_tool_call", (e, n) => {
5
- t({
6
+ function a(a) {
7
+ a.on("before_tool_call", (t, r) => {
8
+ let a = t.toolCallId ?? r.toolCallId;
9
+ i({
10
+ sessionKey: r.sessionKey,
11
+ toolName: t.toolName,
12
+ params: t.params,
13
+ toolCallId: a,
14
+ runId: t.runId ?? r.runId
15
+ });
16
+ let o = n(r.sessionKey);
17
+ a && o && e(a, o);
18
+ }), a.on("after_tool_call", (e, n) => {
19
+ r({
6
20
  sessionKey: n.sessionKey,
7
21
  toolName: e.toolName,
8
22
  params: e.params,
9
23
  toolCallId: e.toolCallId ?? n.toolCallId,
10
- runId: e.runId ?? n.runId
11
- });
12
- }), n.on("after_tool_call", (t, n) => {
13
- e({
14
- sessionKey: n.sessionKey,
15
- toolName: t.toolName,
16
- params: t.params,
17
- toolCallId: t.toolCallId ?? n.toolCallId,
18
- runId: t.runId ?? n.runId,
19
- result: t.result,
20
- error: typeof t.error == "string" ? t.error : void 0,
21
- durationMs: typeof t.durationMs == "number" ? t.durationMs : void 0
22
- });
24
+ runId: e.runId ?? n.runId,
25
+ result: e.result,
26
+ error: typeof e.error == "string" ? e.error : void 0,
27
+ durationMs: typeof e.durationMs == "number" ? e.durationMs : void 0
28
+ }), t(e.toolCallId ?? n.toolCallId);
23
29
  });
24
30
  }
25
31
  //#endregion
26
- export { n as registerToolTraceHooks };
32
+ export { a as registerToolTraceHooks };
@@ -1,5 +1,5 @@
1
1
  //#region src/core/prompt/cloud-tool.ts
2
- var e = "## Skill 使用云工具调用规则\n\n当已读取的 SKILL.md frontmatter 包含 allowed-tools 声明时:\n\n1. 根据用户意图从 allowed-tools 选择工具。\n2. 调用前必须读取当前 skill 目录下对应的 mcptools/<name>.json。\n3. JSON id 获取 toolId,按 inputSchema 提取 params。\n4. 调用 cloud_invoke,传入 { toolId, params }。\n\n不得猜测 toolId,不得使用未在 allowed-tools 中声明的工具。\n明确属于 yoyo-phone-control 等设备控制 Skill(走 node_invoke 通道)的工具,不得通过 cloud_invoke 调用。";
2
+ var e = "## Skill 使用云工具调用规则\n\n当已读取的 SKILL.md frontmatter 包含 allowed-tools 声明时:\n\n1. 根据用户意图和 SKILL.md 正文,从 allowed-tools 中选定工具名。\n2. 工具名对应当前 Skill 目录下的 mcptools/<工具名>.json;选定后直接使用 read 读取该文件,无需先查看 mcptools 目录。\n3. 使用 JSON 顶层 id 作为 cloud_invoke.toolId,并按 inputSchema 提取 params。allowed-tools 中的名称、<tool> 信息中的 toolName 和 JSON 的 name 仅用于定位工具,不作为 toolId。\n4. 若工具定义说明不可实际调用,则按其说明处理;否则调用 cloud_invoke,传入 { toolId: JSON.id, params }。\n\n例如,选中 demo_tool 后直接读取 mcptools/demo_tool.json;若其中 id 为 service-123,则 cloud_invoke.toolId 使用 service-123。\n\n明确属于 yoyo-phone-control 等设备控制 Skill(走 node_invoke 通道)的工具,不得通过 cloud_invoke 调用。";
3
3
  function t() {
4
4
  return { prependSystemContext: e };
5
5
  }
@@ -0,0 +1,42 @@
1
+ import { clawLogger as e } from "../utils/claw-logger.mjs";
2
+ import { looksLikeChatId as t, parseChatId as n } from "../messaging/target/chat-id.mjs";
3
+ import { readChatIdFromSessionKey as r, readChatIdFromTo as i } from "../messaging/target/address.mjs";
4
+ import "../messaging/target/index.mjs";
5
+ //#region src/diagnose/chat-id-resolver.ts
6
+ var a = {
7
+ problem: "当前会话不是 YOYO 控虾会话",
8
+ remedy: "请切到 yoyo: 开头的会话后再执行该命令"
9
+ }, o = e("command");
10
+ async function s(e) {
11
+ o.info("resolve command ctx input", {
12
+ channel: e.channel,
13
+ to: e.to,
14
+ from: e.from,
15
+ sessionKey: e.sessionKey,
16
+ sessionId: e.sessionId
17
+ });
18
+ let s = e.to ? i(e.to) : void 0;
19
+ if (s && !t(s) && (s = void 0), !s && e.from) {
20
+ let n = i(e.from);
21
+ n && t(n) && (s = n);
22
+ }
23
+ if (s ??= r(e.sessionKey), !s) return {
24
+ ok: !1,
25
+ ...a
26
+ };
27
+ try {
28
+ let { deviceId: e } = await n(s);
29
+ return {
30
+ ok: !0,
31
+ chatId: s,
32
+ deviceId: e
33
+ };
34
+ } catch {
35
+ return {
36
+ ok: !1,
37
+ ...a
38
+ };
39
+ }
40
+ }
41
+ //#endregion
42
+ export { s as resolveCommandCtx };
@@ -1,6 +1,7 @@
1
+ import "./chat-id-resolver.mjs";
1
2
  import "./collector.mjs";
2
3
  import "./report/diagnose.mjs";
3
- import "./report/doctor.mjs";
4
+ import "./report/doctor/impl.mjs";
4
5
  import "./report/status.mjs";
5
6
  import "./report/trace.mjs";
6
7
  import "./report/index.mjs";
@@ -15,7 +15,7 @@ var n = {
15
15
  connecting: "连接中",
16
16
  connected: "已连接",
17
17
  reconnecting: "断开重连中",
18
- unauthorized: "认证失败(token 过期或无效)",
18
+ unauthorized: "认证失败",
19
19
  error: "异常",
20
20
  authenticating: "认证中",
21
21
  authenticated: "已认证",
@@ -30,38 +30,43 @@ function r(e) {
30
30
  default: return "warn";
31
31
  }
32
32
  }
33
- function i(t, i) {
33
+ function i(t, i, a) {
34
34
  if (!i) return null;
35
- let a = r(i.phase), o = n[i.phase];
36
- return e(t, a, i.lastError ? o + "(" + i.lastError + ")" : o, "检查网络、登录状态和云服务可用性");
35
+ if (a) return e(t, "skip", `${n[i.phase]}(${a})`);
36
+ let o = r(i.phase), s = n[i.phase];
37
+ return e(t, o, i.lastError ? s + "(" + i.lastError + ")" : s, ["请检查设备网络、代理是否正常后重试", "网络无异常,则云服务可能出现问题,请反馈给工作人员"]);
37
38
  }
38
39
  function a(t) {
39
40
  let { enabledAccountIds: n, channelEnabled: r } = t;
40
- return r ? n.length === 0 ? [e("account_config", "fail", "没有有效启用的账号", "运行 openclaw honor login 并启用账号")] : n.length > 1 ? [e("account_config", "warn", "发现 " + n.length + " 个启用账号,当前只支持单账号连接", "仅保留一个启用账号")] : [e("account_config", "pass", "已启用账号 " + n[0])] : [e("channel_config", "fail", "yoyo channel 已被全局禁用", "启用 channels.yoyo.enabled")];
41
+ return r ? n.length === 0 ? [e("account_config", "fail", "没有有效启用的账号", ["启用已登录账号", "重新运行 openclaw honor login"])] : n.length > 1 ? [e("account_config", "warn", "发现 " + n.length + " 个启用账号,当前只支持单账号连接", "仅保留一个启用账号")] : [e("account_config", "pass", "已启用账号 " + n[0])] : [e("channel_config", "fail", "yoyo channel 已被全局禁用", "启用 channels.yoyo.enabled")];
41
42
  }
42
- function o(n) {
43
- let { account: r, configuration: o, connectionStates: s } = n, c = r.selected, l = [], u = [];
44
- l.push(...a(o));
45
- let d = i("cloud_socket", s.get("cloud"));
46
- d && l.push(d);
47
- let f = i("admin_gateway", s.get("admin"));
48
- if (f && l.push(f), c) {
43
+ function o(e, t) {
44
+ if (!e.channelEnabled) return "yoyo channel 未启用";
45
+ if (!t) return "账号未登录";
46
+ }
47
+ function s(n) {
48
+ let { account: r, configuration: s, connectionStates: c } = n, l = r.selected, u = [], d = [];
49
+ u.push(...a(s));
50
+ let f = o(s, l), p = i("cloud_socket", c.get("cloud"), f);
51
+ p && u.push(p);
52
+ let m = i("admin_gateway", c.get("admin"), f);
53
+ if (m && u.push(m), l) {
49
54
  let t = {
50
55
  valid: e("token", "pass", "Token 有效"),
51
- needs_refresh: e("token", "warn", "Token 已进入刷新窗口", "等待云侧刷新;持续不恢复时运行 openclaw honor login"),
52
- expired: e("token", "fail", "Token 已过期", "运行 openclaw honor login"),
53
- absent: e("token", "fail", "未找到登录凭证", "运行 openclaw honor login")
56
+ needs_refresh: e("token", "warn", "认证凭证已进入刷新窗口", "等待云侧刷新,无需操作"),
57
+ expired: e("token", "fail", "Token 已过期", ["可在 YOYO 控虾端发起对话并重新授权", "可运行 openclaw honor login 重新登录荣耀账号"]),
58
+ absent: e("token", "fail", "未找到登录凭证", "请运行 openclaw honor login 登录荣耀账号")
54
59
  };
55
- u.push(t[c.token.status]), u.push(c.registration.registered ? c.registration.matchesCurrent ? e("registration", "pass", "注册信息与当前 Gateway 认证及插件版本一致") : e("registration", "fail", "注册信息已过期", "重新登录或触发设备重新注册") : e("registration", "fail", "没有本地设备注册记录", "重新登录以注册设备"));
60
+ d.push(t[l.token.status]), d.push(l.registration.registered ? l.registration.matchesCurrent ? e("registration", "pass", "注册信息与当前插件版本一致") : e("registration", "fail", "注册信息已过期", "请运行 openclaw honor login 重新登录荣耀账号") : e("registration", "fail", "没有本地设备注册记录", "请运行 openclaw honor login 登录荣耀账号"));
56
61
  }
57
- let p = t([...l, ...u]);
62
+ let h = t([...u, ...d]);
58
63
  return {
59
64
  timestamp: n.timestamp,
60
- overallStatus: p,
61
- globalChecks: l,
62
- accountChecks: u,
65
+ overallStatus: h,
66
+ globalChecks: u,
67
+ accountChecks: d,
63
68
  snapshot: n
64
69
  };
65
70
  }
66
71
  //#endregion
67
- export { o as evaluateDiagnostics, t as resolveOverallStatus };
72
+ export { s as evaluateDiagnostics, t as resolveOverallStatus };
@@ -0,0 +1,72 @@
1
+ import { toErrorMessage as e } from "../../../utils/error.mjs";
2
+ import { ToolError as t } from "../../../tools/error.mjs";
3
+ import { getDeviceWithStatus as n } from "../../../capabilities/node/directory.mjs";
4
+ import "../../../capabilities/node/index.mjs";
5
+ import { maskAccountId as r } from "../formatter.mjs";
6
+ //#region src/diagnose/report/doctor/device-check.ts
7
+ function i(n) {
8
+ if (n instanceof t) switch (n.code) {
9
+ case "unauthorized": return {
10
+ message: "当前账号未登录,无法查询设备",
11
+ remedy: "请先完成荣耀账号登录"
12
+ };
13
+ case "device_info": return {
14
+ message: "无法获取本地设备信息",
15
+ remedy: ["请重启 OpenClaw 网关后重试"]
16
+ };
17
+ case "api_failed": return {
18
+ message: `查询设备列表失败:${n.message}`,
19
+ remedy: ["云服务异常,请反馈给工作人员"]
20
+ };
21
+ case "network_error": return {
22
+ message: "查询设备列表失败:网络异常",
23
+ remedy: ["请检查设备网络、代理是否正常后重试"]
24
+ };
25
+ default: return {
26
+ message: `查询设备列表失败(${n.code}):${n.message}`,
27
+ remedy: ["云服务异常,请反馈给工作人员"]
28
+ };
29
+ }
30
+ return {
31
+ message: `设备列表查询失败:${e(n)}`,
32
+ remedy: ["云服务异常,请反馈给工作人员"]
33
+ };
34
+ }
35
+ async function a(e) {
36
+ if (!e.ok) return {
37
+ id: "current_device_unknown",
38
+ status: "warn",
39
+ message: e.problem,
40
+ remedy: e.remedy
41
+ };
42
+ let t = e.deviceId;
43
+ try {
44
+ let e = await n(t);
45
+ if (!e) return {
46
+ id: "current_device_not_found",
47
+ status: "fail",
48
+ message: `未找到设备(ID:${t})`,
49
+ remedy: "请确认当前荣耀账号已使用过 YOYO控虾端,确认后请重新发起对话"
50
+ };
51
+ let i = `${e.deviceName ?? "未知设备"}(${r(e.deviceId)})`;
52
+ return e.online ? {
53
+ status: "pass",
54
+ message: `设备 ${i} 在线可达`
55
+ } : {
56
+ id: "current_device_offline",
57
+ status: "fail",
58
+ message: `设备 ${i} 已离线`,
59
+ remedy: "请在手机上打开 YOYO 控虾应用"
60
+ };
61
+ } catch (e) {
62
+ let { message: t, remedy: n } = i(e);
63
+ return {
64
+ id: "current_device_unknown",
65
+ status: "warn",
66
+ message: t,
67
+ remedy: n
68
+ };
69
+ }
70
+ }
71
+ //#endregion
72
+ export { a as checkCurrentDeviceReachable };