@ynhcj/xiaoyi-channel 1.1.24 → 1.1.26

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 (141) hide show
  1. package/dist/index.d.ts +4 -5
  2. package/dist/index.js +102 -84
  3. package/dist/provider-discovery.d.ts +2 -0
  4. package/dist/provider-discovery.js +4 -0
  5. package/dist/src/bot.d.ts +13 -0
  6. package/dist/src/bot.js +345 -136
  7. package/dist/src/channel.js +2 -17
  8. package/dist/src/client.d.ts +1 -5
  9. package/dist/src/client.js +32 -37
  10. package/dist/src/cspl/call-api.d.ts +6 -0
  11. package/dist/src/cspl/call-api.js +37 -16
  12. package/dist/src/cspl/config.d.ts +11 -1
  13. package/dist/src/cspl/config.js +30 -0
  14. package/dist/src/cspl/middleware.d.ts +8 -0
  15. package/dist/src/cspl/middleware.js +90 -0
  16. package/dist/src/cspl/steer-context.d.ts +21 -0
  17. package/dist/src/cspl/steer-context.js +78 -0
  18. package/dist/src/file-download.js +4 -3
  19. package/dist/src/file-upload.js +19 -18
  20. package/dist/src/formatter.js +32 -44
  21. package/dist/src/heartbeat.js +4 -3
  22. package/dist/src/login-token-handler.js +13 -10
  23. package/dist/src/message-queue.js +2 -1
  24. package/dist/src/monitor.js +62 -41
  25. package/dist/src/outbound.js +22 -18
  26. package/dist/src/provider.d.ts +1 -1
  27. package/dist/src/provider.js +147 -71
  28. package/dist/src/push.js +16 -15
  29. package/dist/src/reply-dispatcher.d.ts +3 -1
  30. package/dist/src/reply-dispatcher.js +65 -63
  31. package/dist/src/runtime.d.ts +3 -11
  32. package/dist/src/runtime.js +6 -18
  33. package/dist/src/self-evolution-handler.js +11 -14
  34. package/dist/src/self-evolution-tool-result-nudge.d.ts +3 -0
  35. package/dist/src/self-evolution-tool-result-nudge.js +96 -0
  36. package/dist/src/skill-retriever/hooks.js +7 -16
  37. package/dist/src/skill-retriever/tool-search.js +16 -17
  38. package/dist/src/steer-injector.js +1 -1
  39. package/dist/src/task-manager.d.ts +4 -27
  40. package/dist/src/task-manager.js +19 -79
  41. package/dist/src/tools/calendar-tool.d.ts +2 -1
  42. package/dist/src/tools/calendar-tool.js +116 -116
  43. package/dist/src/tools/call-device-tool.d.ts +2 -1
  44. package/dist/src/tools/call-device-tool.js +126 -103
  45. package/dist/src/tools/call-phone-tool.d.ts +2 -1
  46. package/dist/src/tools/call-phone-tool.js +113 -113
  47. package/dist/src/tools/create-alarm-tool.d.ts +2 -1
  48. package/dist/src/tools/create-alarm-tool.js +231 -231
  49. package/dist/src/tools/create-all-tools.d.ts +16 -0
  50. package/dist/src/tools/create-all-tools.js +50 -0
  51. package/dist/src/tools/delete-alarm-tool.d.ts +2 -1
  52. package/dist/src/tools/delete-alarm-tool.js +135 -135
  53. package/dist/src/tools/get-alarm-tool-schema.d.ts +2 -1
  54. package/dist/src/tools/get-alarm-tool-schema.js +16 -10
  55. package/dist/src/tools/get-calendar-tool-schema.d.ts +2 -1
  56. package/dist/src/tools/get-calendar-tool-schema.js +12 -8
  57. package/dist/src/tools/get-collection-tool-schema.d.ts +2 -1
  58. package/dist/src/tools/get-collection-tool-schema.js +11 -9
  59. package/dist/src/tools/get-contact-tool-schema.d.ts +2 -1
  60. package/dist/src/tools/get-contact-tool-schema.js +16 -10
  61. package/dist/src/tools/get-device-file-tool-schema.d.ts +2 -1
  62. package/dist/src/tools/get-device-file-tool-schema.js +13 -9
  63. package/dist/src/tools/get-email-tool-schema.d.ts +2 -1
  64. package/dist/src/tools/get-email-tool-schema.js +11 -8
  65. package/dist/src/tools/get-note-tool-schema.d.ts +2 -1
  66. package/dist/src/tools/get-note-tool-schema.js +14 -9
  67. package/dist/src/tools/get-photo-tool-schema.d.ts +2 -1
  68. package/dist/src/tools/get-photo-tool-schema.js +12 -9
  69. package/dist/src/tools/image-reading-tool.d.ts +3 -2
  70. package/dist/src/tools/image-reading-tool.js +86 -165
  71. package/dist/src/tools/location-tool.d.ts +2 -1
  72. package/dist/src/tools/location-tool.js +91 -91
  73. package/dist/src/tools/login-token-tool.d.ts +2 -1
  74. package/dist/src/tools/login-token-tool.js +124 -116
  75. package/dist/src/tools/modify-alarm-tool.d.ts +2 -1
  76. package/dist/src/tools/modify-alarm-tool.js +236 -236
  77. package/dist/src/tools/modify-note-tool.d.ts +2 -1
  78. package/dist/src/tools/modify-note-tool.js +108 -108
  79. package/dist/src/tools/note-tool.d.ts +2 -1
  80. package/dist/src/tools/note-tool.js +107 -107
  81. package/dist/src/tools/query-app-message-tool.d.ts +2 -1
  82. package/dist/src/tools/query-app-message-tool.js +112 -111
  83. package/dist/src/tools/query-memory-data-tool.d.ts +2 -1
  84. package/dist/src/tools/query-memory-data-tool.js +113 -112
  85. package/dist/src/tools/query-todo-task-tool.d.ts +2 -1
  86. package/dist/src/tools/query-todo-task-tool.js +107 -106
  87. package/dist/src/tools/save-file-to-phone-tool.d.ts +2 -1
  88. package/dist/src/tools/save-file-to-phone-tool.js +131 -131
  89. package/dist/src/tools/save-media-to-gallery-tool.d.ts +2 -1
  90. package/dist/src/tools/save-media-to-gallery-tool.js +138 -138
  91. package/dist/src/tools/save-self-evolution-skill-tool.d.ts +2 -1
  92. package/dist/src/tools/save-self-evolution-skill-tool.js +194 -196
  93. package/dist/src/tools/search-alarm-tool.d.ts +2 -1
  94. package/dist/src/tools/search-alarm-tool.js +175 -175
  95. package/dist/src/tools/search-calendar-tool.d.ts +2 -1
  96. package/dist/src/tools/search-calendar-tool.js +149 -149
  97. package/dist/src/tools/search-contact-tool.d.ts +2 -1
  98. package/dist/src/tools/search-contact-tool.js +102 -102
  99. package/dist/src/tools/search-email-tool.d.ts +2 -1
  100. package/dist/src/tools/search-email-tool.js +111 -111
  101. package/dist/src/tools/search-file-tool.d.ts +2 -1
  102. package/dist/src/tools/search-file-tool.js +103 -103
  103. package/dist/src/tools/search-message-tool.d.ts +2 -1
  104. package/dist/src/tools/search-message-tool.js +104 -104
  105. package/dist/src/tools/search-note-tool.d.ts +2 -1
  106. package/dist/src/tools/search-note-tool.js +99 -99
  107. package/dist/src/tools/search-photo-gallery-tool.d.ts +2 -1
  108. package/dist/src/tools/search-photo-gallery-tool.js +38 -38
  109. package/dist/src/tools/send-email-tool.d.ts +2 -1
  110. package/dist/src/tools/send-email-tool.js +109 -108
  111. package/dist/src/tools/send-file-to-user-tool.d.ts +2 -1
  112. package/dist/src/tools/send-file-to-user-tool.js +157 -155
  113. package/dist/src/tools/send-message-tool.d.ts +2 -1
  114. package/dist/src/tools/send-message-tool.js +123 -123
  115. package/dist/src/tools/session-helper.d.ts +24 -0
  116. package/dist/src/tools/session-helper.js +45 -0
  117. package/dist/src/tools/session-manager.d.ts +29 -6
  118. package/dist/src/tools/session-manager.js +134 -19
  119. package/dist/src/tools/upload-file-tool.d.ts +2 -1
  120. package/dist/src/tools/upload-file-tool.js +82 -82
  121. package/dist/src/tools/upload-photo-tool.d.ts +2 -1
  122. package/dist/src/tools/upload-photo-tool.js +73 -73
  123. package/dist/src/tools/xiaoyi-add-collection-tool.d.ts +2 -1
  124. package/dist/src/tools/xiaoyi-add-collection-tool.js +147 -147
  125. package/dist/src/tools/xiaoyi-collection-tool.d.ts +2 -1
  126. package/dist/src/tools/xiaoyi-collection-tool.js +115 -115
  127. package/dist/src/tools/xiaoyi-delete-collection-tool.d.ts +2 -1
  128. package/dist/src/tools/xiaoyi-delete-collection-tool.js +128 -128
  129. package/dist/src/tools/xiaoyi-gui-tool.d.ts +2 -1
  130. package/dist/src/tools/xiaoyi-gui-tool.js +89 -88
  131. package/dist/src/trigger-handler.js +8 -9
  132. package/dist/src/utils/logger.js +105 -19
  133. package/dist/src/utils/self-evolution-manager.d.ts +5 -0
  134. package/dist/src/utils/self-evolution-manager.js +45 -23
  135. package/dist/src/utils/throw.d.ts +5 -0
  136. package/dist/src/utils/throw.js +10 -0
  137. package/dist/src/websocket.js +35 -31
  138. package/dist/src/xy-session-store.d.ts +79 -0
  139. package/dist/src/xy-session-store.js +153 -0
  140. package/openclaw.plugin.json +25 -0
  141. package/package.json +7 -6
package/dist/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- declare const plugin: {
1
+ declare const _default: {
3
2
  id: string;
4
3
  name: string;
5
4
  description: string;
6
5
  configSchema: import("openclaw/plugin-sdk").OpenClawPluginConfigSchema;
7
- register(api: OpenClawPluginApi): void;
8
- };
9
- export default plugin;
6
+ register: NonNullable<import("openclaw/plugin-sdk/core").OpenClawPluginDefinition["register"]>;
7
+ } & Pick<import("openclaw/plugin-sdk/core").OpenClawPluginDefinition, "kind" | "reload" | "nodeHostCommands" | "securityAuditCollectors">;
8
+ export default _default;
package/dist/index.js CHANGED
@@ -1,98 +1,116 @@
1
- import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
1
+ import { definePluginEntry } from "openclaw/plugin-sdk/core";
2
2
  import { xiaoyiProvider } from "./src/provider.js";
3
3
  import { xyPlugin } from "./src/channel.js";
4
- import { callCsplApi } from "./src/cspl/call-api.js";
4
+ import { callCsplApiWithConfig } from "./src/cspl/call-api.js";
5
+ import { getCsplConfig, initCsplConfigFromXYConfig } from "./src/cspl/config.js";
5
6
  import { ALLOWED_TOOLS, MAX_TEXT_LENGTH, MAX_TOTAL_LENGTH, MIN_TEXT_LENGTH, STEER_ABORT_MESSAGE, } from "./src/cspl/constants.js";
6
7
  import { extractResultText, parseSecurityResult, processText, validateAndTruncateText, } from "./src/cspl/utils.js";
8
+ import { tryInjectSteer } from "./src/cspl/steer-context.js";
9
+ import { getSessionContext } from "./src/tools/session-manager.js";
10
+ import { logger } from "./src/utils/logger.js";
7
11
  import { setXYRuntime } from "./src/runtime.js";
8
- import { tryInjectSteer } from "./src/steer-injector.js";
9
- import { selfEvolutionManager } from "./src/utils/self-evolution-manager.js";
10
- import { TOOL_CALL_NUDGE_THRESHOLD, toolCallNudgeManager, } from "./src/utils/tool-call-nudge-manager.js";
12
+ import { registerSelfEvolutionToolResultNudge } from "./src/self-evolution-tool-result-nudge.js";
11
13
  import { createBeforePromptBuildHandler } from "./src/skill-retriever/hooks.js";
12
14
  import { normalizeToolRetrieverConfig } from "./src/skill-retriever/config.js";
13
- const SELF_EVOLUTION_NUDGE_MESSAGE = "[系统消息,非用户发言,无需主动告知用户] 当前任务已经调用了较多次数的工具。请先完成用户主要任务。完成后,如果这些工具调用暴露出稳定、通用、可复用的流程、排错经验或踩坑点,再考虑阅读 xiaoyi-self-evolution 技能进行评估;如果没有高价值候选经验,请忽略本提醒。";
14
- function shouldCountToolCall(toolName) {
15
- if (toolName === "save_self_evolution_skill") {
16
- return false;
17
- }
18
- if (toolName === "call_device_tool") {
19
- return false;
20
- }
21
- if (toolName.endsWith("_tool_schema")) {
22
- return false;
23
- }
24
- return true;
15
+ function registerFullHooks(api) {
16
+ // SKILL RETRIEVER HOOK: before_prompt_build hook
17
+ const pluginConfig = api.pluginConfig || {};
18
+ const skillRetrieverConfig = normalizeToolRetrieverConfig({
19
+ enabled: pluginConfig.skillRetrieverEnabled ?? true,
20
+ maxTools: pluginConfig.skillRetrieverMaxTools ?? 2,
21
+ includeUninstalledOnly: true,
22
+ envFilePath: "~/.openclaw/.xiaoyienv",
23
+ timeoutMs: pluginConfig.skillRetrieverTimeoutMs ?? 1000,
24
+ });
25
+ const beforePromptBuildHandler = createBeforePromptBuildHandler(skillRetrieverConfig);
26
+ api.on("before_prompt_build", beforePromptBuildHandler);
27
+ registerSelfEvolutionToolResultNudge(api);
25
28
  }
26
- const plugin = {
27
- id: "xiaoyi-channel",
28
- name: "Xiaoyi Channel",
29
- description: "Xiaoyi channel plugin - Xiaoyi A2A protocol integration",
30
- configSchema: emptyPluginConfigSchema(),
31
- register(api) {
32
- setXYRuntime(api.runtime);
33
- api.registerChannel({ plugin: xyPlugin });
34
- api.registerProvider(xiaoyiProvider);
35
- // SKILL RETRIEVER HOOK: before_prompt_build hook
36
- const pluginConfig = api.pluginConfig || {};
37
- const skillRetrieverConfig = normalizeToolRetrieverConfig({
38
- enabled: pluginConfig.skillRetrieverEnabled ?? true,
39
- maxTools: pluginConfig.skillRetrieverMaxTools ?? 2,
40
- includeUninstalledOnly: true,
41
- envFilePath: "~/.openclaw/.xiaoyienv",
42
- timeoutMs: pluginConfig.skillRetrieverTimeoutMs ?? 1000,
43
- });
44
- const beforePromptBuildHandler = createBeforePromptBuildHandler(skillRetrieverConfig);
45
- api.on("before_prompt_build", beforePromptBuildHandler);
46
- api.on("after_tool_call", async (event, ctx) => {
47
- const selfEvolutionEnabled = await selfEvolutionManager.isEnabled();
48
- if (ctx.sessionKey && selfEvolutionEnabled && shouldCountToolCall(event.toolName)) {
49
- try {
50
- const { count, shouldNudge } = toolCallNudgeManager.recordToolCall(ctx.sessionKey);
51
- api.logger.debug?.(`[SELF_EVOLUTION] Tool call counted: tool=${event.toolName}, count=${count}, threshold=${TOOL_CALL_NUDGE_THRESHOLD}, sessionKey=${ctx.sessionKey}`);
52
- if (shouldNudge) {
53
- api.logger.info?.(`[SELF_EVOLUTION] Tool call threshold reached, injecting nudge: count=${count}, sessionKey=${ctx.sessionKey}`);
54
- await tryInjectSteer(ctx.sessionKey, SELF_EVOLUTION_NUDGE_MESSAGE);
55
- }
56
- }
57
- catch (err) {
58
- api.logger.error(`[SELF_EVOLUTION] after_tool_call nudge error: ${err}`);
59
- }
60
- }
61
- if (!ALLOWED_TOOLS.includes(event.toolName)) {
29
+ function registerCsplHook(api) {
30
+ // CSPL security scanning via after_tool_call hook.
31
+ // When CSPL returns REJECT, injects a steer message via tryInjectSteer
32
+ // to interrupt the agent. Uses skipRegistration to avoid refCount leaks
33
+ // and taskId overwrites.
34
+ // Only registered in "full" mode because it depends on handleXYMessage
35
+ // having cached cfg/runtime via setCsplSteerContext.
36
+ api.on("after_tool_call", async (event, ctx) => {
37
+ if (!ALLOWED_TOOLS.includes(event.toolName)) {
38
+ return;
39
+ }
40
+ try {
41
+ const resultText = extractResultText(event, event.toolName);
42
+ const resultLength = resultText.length;
43
+ if (resultLength <= MIN_TEXT_LENGTH || resultLength > MAX_TOTAL_LENGTH) {
62
44
  return;
63
45
  }
64
- console.log(`[SENTINEL HOOK] after_tool_call triggered: toolName=${event.toolName}, sessionKey=${ctx.sessionKey ?? "none"}`);
65
- try {
66
- const resultText = extractResultText(event, event.toolName);
67
- const resultLength = resultText.length;
68
- if (resultLength <= MIN_TEXT_LENGTH || resultLength > MAX_TOTAL_LENGTH) {
69
- return;
70
- }
71
- const questionText = {
72
- subSceneID: "TOOL_OUTPUT",
73
- tool: event.toolName,
74
- output: [{ content: "" }],
75
- };
76
- const originText = processText(resultText);
77
- questionText.output[0].content = originText;
78
- let finalJson = JSON.stringify(questionText);
79
- if (finalJson.length > MAX_TEXT_LENGTH) {
80
- const diff = finalJson.length - MAX_TEXT_LENGTH;
81
- const { text: trimmed } = validateAndTruncateText(originText, MAX_TEXT_LENGTH - diff);
82
- questionText.output[0].content = trimmed;
83
- finalJson = JSON.stringify(questionText);
46
+ logger.log(`[SENTINEL HOOK] after_tool_call: toolName=${event.toolName}, textLength=${resultLength}`);
47
+ const questionText = {
48
+ subSceneID: "TOOL_OUTPUT",
49
+ tool: event.toolName,
50
+ output: [{ content: "" }],
51
+ };
52
+ const originText = processText(resultText);
53
+ questionText.output[0].content = originText;
54
+ let finalJson = JSON.stringify(questionText);
55
+ if (finalJson.length > MAX_TEXT_LENGTH) {
56
+ const diff = finalJson.length - MAX_TEXT_LENGTH;
57
+ const { text: trimmed } = validateAndTruncateText(originText, MAX_TEXT_LENGTH - diff);
58
+ questionText.output[0].content = trimmed;
59
+ finalJson = JSON.stringify(questionText);
60
+ }
61
+ const sessionCtx = getSessionContext(ctx.sessionKey ?? "");
62
+ const csplConfig = sessionCtx
63
+ ? initCsplConfigFromXYConfig(sessionCtx.config)
64
+ : getCsplConfig();
65
+ const csplStartTime = Date.now();
66
+ const response = await callCsplApiWithConfig(finalJson, csplConfig);
67
+ const csplElapsed = Date.now() - csplStartTime;
68
+ const result = parseSecurityResult(response);
69
+ logger.log(`[SENTINEL HOOK] Security result: status=${result.status}, toolName=${event.toolName}, elapsed=${csplElapsed}ms`);
70
+ if (result.status === "REJECT") {
71
+ logger.log(`[SENTINEL HOOK] REJECT - injecting steer via tryInjectSteer`);
72
+ if (sessionCtx) {
73
+ await tryInjectSteer({
74
+ sessionId: sessionCtx.sessionId,
75
+ taskId: sessionCtx.taskId,
76
+ message: STEER_ABORT_MESSAGE,
77
+ source: "cspl",
78
+ });
84
79
  }
85
- const response = await callCsplApi(finalJson, api.config);
86
- const result = parseSecurityResult(response);
87
- console.log(`[SENTINEL HOOK] Security result: status=${result.status}`);
88
- if (result.status === "REJECT") {
89
- await tryInjectSteer(ctx.sessionKey, STEER_ABORT_MESSAGE);
80
+ else {
81
+ logger.error("[SENTINEL HOOK] No session context, cannot inject steer");
90
82
  }
91
83
  }
92
- catch (err) {
93
- api.logger.error(`[SENTINEL HOOK] after_tool_call error: ${err}`);
94
- }
95
- });
84
+ }
85
+ catch (err) {
86
+ logger.error(`[SENTINEL HOOK] after_tool_call error: ${err}`);
87
+ }
88
+ });
89
+ }
90
+ export default definePluginEntry({
91
+ id: "xiaoyi-channel",
92
+ name: "Xiaoyi Channel",
93
+ description: "Xiaoyi channel plugin - Xiaoyi A2A protocol integration",
94
+ register(api) {
95
+ // Always register the provider so wrapStreamFn/prepareExtraParams work
96
+ // in ALL registration modes (not just "full").
97
+ api.registerProvider(xiaoyiProvider);
98
+ if (api.registrationMode === "cli-metadata") {
99
+ return;
100
+ }
101
+ if (api.registrationMode === "tool-discovery") {
102
+ registerFullHooks(api);
103
+ return;
104
+ }
105
+ // Register channel plugin and set runtime
106
+ api.registerChannel({ plugin: xyPlugin });
107
+ setXYRuntime(api.runtime);
108
+ if (api.registrationMode === "discovery") {
109
+ return;
110
+ }
111
+ if (api.registrationMode === "full") {
112
+ registerFullHooks(api);
113
+ registerCsplHook(api);
114
+ }
96
115
  },
97
- };
98
- export default plugin;
116
+ });
@@ -0,0 +1,2 @@
1
+ import { xiaoyiProvider } from "./src/provider.js";
2
+ export default xiaoyiProvider;
@@ -0,0 +1,4 @@
1
+ // Provider discovery entry for fast-path provider resolution.
2
+ // Exported as default so normalizeDiscoveryModule can unwrap it via .default.
3
+ import { xiaoyiProvider } from "./src/provider.js";
4
+ export default xiaoyiProvider;
package/dist/src/bot.d.ts CHANGED
@@ -9,6 +9,14 @@ export interface HandleXYMessageParams {
9
9
  message: A2AJsonRpcRequest;
10
10
  accountId: string;
11
11
  webSocketSessionId?: string;
12
+ /** Called after dispatch init is complete (agentTools/wrapStreamFn done). */
13
+ onInitComplete?: () => void;
14
+ /**
15
+ * When true, skip taskId/session registration. Used by tryInjectSteer to
16
+ * inject a steer message without overwriting the active taskId or leaking
17
+ * session refCount.
18
+ */
19
+ skipRegistration?: boolean;
12
20
  }
13
21
  /**
14
22
  * Handle an incoming A2A message.
@@ -16,3 +24,8 @@ export interface HandleXYMessageParams {
16
24
  * Runtime is expected to be validated before calling this function.
17
25
  */
18
26
  export declare function handleXYMessage(params: HandleXYMessageParams): Promise<void>;
27
+ /**
28
+ * 由 provider.ts 在 wrapStreamFn 调用时触发。
29
+ * 这是模型 API 被调用的精确时刻,此时 isStreaming 一定为 true。
30
+ */
31
+ export declare function notifyModelStreaming(sessionId: string): void;