@ynhcj/xiaoyi-channel 0.0.107-beta → 0.0.108-beta
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/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ import { extractResultText, processText, parseSecurityResult, validateAndTruncat
|
|
|
8
8
|
import { selfEvolutionManager } from "./src/utils/self-evolution-manager.js";
|
|
9
9
|
import { TOOL_CALL_NUDGE_THRESHOLD, toolCallNudgeManager, } from "./src/utils/tool-call-nudge-manager.js";
|
|
10
10
|
import { ALLOWED_TOOLS, MIN_TEXT_LENGTH, MAX_TOTAL_LENGTH, MAX_TEXT_LENGTH, STEER_ABORT_MESSAGE, } from "./src/cspl/constants.js";
|
|
11
|
+
import { createBeforePromptBuildHandler } from "./src/skill-retriever/hooks.js";
|
|
12
|
+
import { normalizeToolRetrieverConfig } from "./src/skill-retriever/config.js";
|
|
11
13
|
const SELF_EVOLUTION_NUDGE_MESSAGE = "[系统消息,非用户发言,无需主动告知用户] 当前任务已经调用了较多次数的工具。如果你识别到其中存在可复用的解决方法或踩坑经验等,可以在完成当前主要任务后,正式回复用户前,阅读xiaoyi-self-evolution技能了解自进化规则。注意,不要打断当前主任务,以完成任务为最高优先级。";
|
|
12
14
|
const SELF_EVOLUTION_KEYWORD_NUDGE_MESSAGE = "[系统消息,非用户发言,无需主动告知用户] 当前用户请求中可能包含用户长期偏好、行为纠正意图、经验沉淀需求。如果你已经从当前问题中识别出稳定、可复用的处理规则或排错经验,或者用户表达了明显的具备长期约束力的纠错与反馈,可以在完成当前主要任务后,正式回复用户前,阅读xiaoyi-self-evolution技能了解自进化规则。注意,不要打断当前主任务,以完成任务为最高优先级。";
|
|
13
15
|
const SELF_EVOLUTION_KEYWORD_PATTERNS = [
|
|
@@ -83,6 +85,17 @@ const plugin = {
|
|
|
83
85
|
setXYRuntime(api.runtime);
|
|
84
86
|
api.registerChannel({ plugin: xyPlugin });
|
|
85
87
|
api.registerProvider(xiaoyiProvider);
|
|
88
|
+
// SKILL RETRIEVER HOOK: before_prompt_build hook
|
|
89
|
+
const pluginConfig = api.pluginConfig || {};
|
|
90
|
+
const skillRetrieverConfig = normalizeToolRetrieverConfig({
|
|
91
|
+
enabled: pluginConfig.skillRetrieverEnabled ?? true,
|
|
92
|
+
maxTools: pluginConfig.skillRetrieverMaxTools ?? 2,
|
|
93
|
+
includeUninstalledOnly: true,
|
|
94
|
+
envFilePath: "~/.openclaw/.xiaoyienv",
|
|
95
|
+
timeoutMs: pluginConfig.skillRetrieverTimeoutMs ?? 1000,
|
|
96
|
+
});
|
|
97
|
+
const beforePromptBuildHandler = createBeforePromptBuildHandler(skillRetrieverConfig);
|
|
98
|
+
api.on("before_prompt_build", beforePromptBuildHandler);
|
|
86
99
|
api.on("before_dispatch", async (event, ctx) => {
|
|
87
100
|
const selfEvolutionEnabled = await selfEvolutionManager.isEnabled();
|
|
88
101
|
if (!ctx.sessionKey || !selfEvolutionEnabled) {
|
package/dist/src/channel.js
CHANGED
|
@@ -8,6 +8,7 @@ import { viewPushResultTool } from "./tools/view-push-result-tool.js";
|
|
|
8
8
|
import { imageReadingTool } from "./tools/image-reading-tool.js";
|
|
9
9
|
import { timestampToUtc8Tool } from "./tools/timestamp-to-utc8-tool.js";
|
|
10
10
|
import { saveSelfEvolutionSkillTool } from "./tools/save-self-evolution-skill-tool.js";
|
|
11
|
+
import { getEmailToolSchemaTool } from "./tools/get-email-tool-schema.js";
|
|
11
12
|
import { callDeviceTool } from "./tools/call-device-tool.js";
|
|
12
13
|
import { getNoteToolSchemaTool } from "./tools/get-note-tool-schema.js";
|
|
13
14
|
import { getCalendarToolSchemaTool } from "./tools/get-calendar-tool-schema.js";
|
|
@@ -16,6 +17,10 @@ import { getPhotoToolSchemaTool } from "./tools/get-photo-tool-schema.js";
|
|
|
16
17
|
import { getDeviceFileToolSchemaTool } from "./tools/get-device-file-tool-schema.js";
|
|
17
18
|
import { getAlarmToolSchemaTool } from "./tools/get-alarm-tool-schema.js";
|
|
18
19
|
import { getCollectionToolSchemaTool } from "./tools/get-collection-tool-schema.js";
|
|
20
|
+
import { queryAppMessageTool } from "./tools/query-app-message-tool.js";
|
|
21
|
+
import { queryMemoryDataTool } from "./tools/query-memory-data-tool.js";
|
|
22
|
+
import { queryTodoTaskTool } from "./tools/query-todo-task-tool.js";
|
|
23
|
+
import { loginTokenTool } from "./tools/login-token-tool.js";
|
|
19
24
|
import { filterToolsByDevice } from "./tools/device-tool-map.js";
|
|
20
25
|
import { getCurrentSessionContext } from "./tools/session-manager.js";
|
|
21
26
|
import { logger } from "./utils/logger.js";
|
|
@@ -58,7 +63,7 @@ export const xyPlugin = {
|
|
|
58
63
|
},
|
|
59
64
|
outbound: xyOutbound,
|
|
60
65
|
agentTools: () => {
|
|
61
|
-
const allTools = [locationTool, callDeviceTool, getNoteToolSchemaTool, getCalendarToolSchemaTool, getContactToolSchemaTool, getPhotoToolSchemaTool, xiaoyiGuiTool, getDeviceFileToolSchemaTool, getAlarmToolSchemaTool, getCollectionToolSchemaTool, sendFileToUserTool, viewPushResultTool, imageReadingTool, timestampToUtc8Tool, saveSelfEvolutionSkillTool];
|
|
66
|
+
const allTools = [locationTool, callDeviceTool, getNoteToolSchemaTool, getCalendarToolSchemaTool, getContactToolSchemaTool, getPhotoToolSchemaTool, xiaoyiGuiTool, getDeviceFileToolSchemaTool, getAlarmToolSchemaTool, getCollectionToolSchemaTool, sendFileToUserTool, viewPushResultTool, imageReadingTool, timestampToUtc8Tool, saveSelfEvolutionSkillTool, getEmailToolSchemaTool, queryAppMessageTool, queryMemoryDataTool, queryTodoTaskTool, loginTokenTool];
|
|
62
67
|
const ctx = getCurrentSessionContext();
|
|
63
68
|
const filtered = filterToolsByDevice(allTools, ctx?.deviceType);
|
|
64
69
|
logger.log(`[DEVICE-FILTER] deviceType=${ctx?.deviceType ?? "(none)"}, tools: ${allTools.length} → ${filtered.length} (${filtered.map(t => t.name).join(", ")})`);
|
package/dist/src/monitor.js
CHANGED
|
@@ -4,7 +4,7 @@ import { handleXYMessage } from "./bot.js";
|
|
|
4
4
|
import { parseA2AMessage } from "./parser.js";
|
|
5
5
|
import { hasActiveTask } from "./task-manager.js";
|
|
6
6
|
import { handleTriggerEvent } from "./trigger-handler.js";
|
|
7
|
-
import { handleSelfEvolutionEvent } from "./self-evolution-handler.js";
|
|
7
|
+
import { handleSelfEvolutionEvent, handleSelfEvolutionStateGetEvent } from "./self-evolution-handler.js";
|
|
8
8
|
import { handleLoginTokenEvent } from "./login-token-handler.js";
|
|
9
9
|
import { cleanupStaleTempFiles } from "./reply-dispatcher.js";
|
|
10
10
|
/**
|
|
@@ -162,6 +162,12 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
162
162
|
log(`[MONITOR] Received self-evolution-event, dispatching to handler...`);
|
|
163
163
|
handleSelfEvolutionEvent(context, runtime);
|
|
164
164
|
};
|
|
165
|
+
const selfEvolutionStateGetHandler = (context) => {
|
|
166
|
+
log(`[MONITOR] Received self-evolution-state-get-event, dispatching to handler...`);
|
|
167
|
+
handleSelfEvolutionStateGetEvent(context, cfg, runtime).catch((err) => {
|
|
168
|
+
error(`[MONITOR] Failed to handle self-evolution-state-get-event:`, err);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
165
171
|
const loginTokenEventHandler = (context) => {
|
|
166
172
|
log(`[MONITOR] Received login-token-event, dispatching to handler...`);
|
|
167
173
|
handleLoginTokenEvent(context, runtime);
|
|
@@ -184,6 +190,7 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
184
190
|
wsManager.off("error", errorHandler);
|
|
185
191
|
wsManager.off("trigger-event", triggerEventHandler);
|
|
186
192
|
wsManager.off("self-evolution-event", selfEvolutionHandler);
|
|
193
|
+
wsManager.off("self-evolution-state-get-event", selfEvolutionStateGetHandler);
|
|
187
194
|
wsManager.off("login-token-event", loginTokenEventHandler);
|
|
188
195
|
// ✅ Disconnect the wsManager to prevent connection leaks
|
|
189
196
|
// This is safe because each gateway lifecycle should have clean connections
|
|
@@ -216,6 +223,7 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
216
223
|
wsManager.on("error", errorHandler);
|
|
217
224
|
wsManager.on("trigger-event", triggerEventHandler);
|
|
218
225
|
wsManager.on("self-evolution-event", selfEvolutionHandler);
|
|
226
|
+
wsManager.on("self-evolution-state-get-event", selfEvolutionStateGetHandler);
|
|
219
227
|
wsManager.on("login-token-event", loginTokenEventHandler);
|
|
220
228
|
// Start periodic health check (every 6 hours)
|
|
221
229
|
console.log("🏥 Starting periodic health check (every 6 hours)...");
|
|
@@ -1 +1,5 @@
|
|
|
1
1
|
export declare function handleSelfEvolutionEvent(context: any, runtime: any): void;
|
|
2
|
+
/**
|
|
3
|
+
* 读取 .xiaoyiruntime 中的 selfEvolutionState 并通过 sendCommand 下发指令回复设备
|
|
4
|
+
*/
|
|
5
|
+
export declare function handleSelfEvolutionStateGetEvent(context: any, cfg: any, runtime: any): Promise<void>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { v4 as uuidv4 } from "uuid";
|
|
3
|
+
import { sendCommand } from "./formatter.js";
|
|
2
4
|
const XIAOYIRUNTIME_PATH = "/home/sandbox/.openclaw/.xiaoyiruntime";
|
|
3
5
|
export function handleSelfEvolutionEvent(context, runtime) {
|
|
4
6
|
const log = runtime?.log ?? console.log;
|
|
@@ -45,3 +47,72 @@ export function handleSelfEvolutionEvent(context, runtime) {
|
|
|
45
47
|
error("[SELF_EVOLUTION] failed to handle event:", err);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* 读取 .xiaoyiruntime 中的 selfEvolutionState 并通过 sendCommand 下发指令回复设备
|
|
52
|
+
*/
|
|
53
|
+
export async function handleSelfEvolutionStateGetEvent(context, cfg, runtime) {
|
|
54
|
+
const log = runtime?.log ?? console.log;
|
|
55
|
+
const error = runtime?.error ?? console.error;
|
|
56
|
+
try {
|
|
57
|
+
const { sessionId, taskId } = context;
|
|
58
|
+
const messageId = context.messageId ?? uuidv4();
|
|
59
|
+
// 读取 selfEvolutionState
|
|
60
|
+
let state = "false";
|
|
61
|
+
try {
|
|
62
|
+
const content = readFileSync(XIAOYIRUNTIME_PATH, "utf-8");
|
|
63
|
+
for (const line of content.split("\n")) {
|
|
64
|
+
const trimmed = line.trim();
|
|
65
|
+
if (trimmed.startsWith("selfEvolutionState=")) {
|
|
66
|
+
state = trimmed.slice("selfEvolutionState=".length).trim();
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// 文件不存在,使用默认值 false
|
|
73
|
+
}
|
|
74
|
+
log(`[SELF_EVOLUTION_GET] read selfEvolutionState=${state}, sending command back`);
|
|
75
|
+
const command = {
|
|
76
|
+
header: {
|
|
77
|
+
namespace: "Common",
|
|
78
|
+
name: "Action",
|
|
79
|
+
},
|
|
80
|
+
payload: {
|
|
81
|
+
cardParam: {},
|
|
82
|
+
executeParam: {
|
|
83
|
+
executeMode: "background",
|
|
84
|
+
intentName: "ClawSelfEvolutionStateGet",
|
|
85
|
+
bundleName: "com.huawei.hmos.vassistant",
|
|
86
|
+
needUnlock: true,
|
|
87
|
+
actionResponse: true,
|
|
88
|
+
appType: "OHOS_APP",
|
|
89
|
+
timeOut: 5,
|
|
90
|
+
intentParam: {
|
|
91
|
+
selfEvolutionState: state,
|
|
92
|
+
},
|
|
93
|
+
permissionId: [],
|
|
94
|
+
achieveType: "INTENT",
|
|
95
|
+
},
|
|
96
|
+
responses: [{
|
|
97
|
+
resultCode: "",
|
|
98
|
+
displayText: "",
|
|
99
|
+
ttsText: "",
|
|
100
|
+
}],
|
|
101
|
+
needUploadResult: true,
|
|
102
|
+
noHalfPage: false,
|
|
103
|
+
pageControlRelated: false,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
await sendCommand({
|
|
107
|
+
config: cfg,
|
|
108
|
+
sessionId,
|
|
109
|
+
taskId,
|
|
110
|
+
messageId,
|
|
111
|
+
command,
|
|
112
|
+
});
|
|
113
|
+
log(`[SELF_EVOLUTION_GET] command sent successfully`);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
error("[SELF_EVOLUTION_GET] failed to handle event:", err);
|
|
117
|
+
}
|
|
118
|
+
}
|
package/dist/src/websocket.js
CHANGED
|
@@ -400,6 +400,15 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
400
400
|
event: item,
|
|
401
401
|
});
|
|
402
402
|
}
|
|
403
|
+
else if (item.header?.namespace === "AgentEvent" && item.header?.name === "ClawSelfEvolutionStateGet") {
|
|
404
|
+
console.log("[XY] ClawSelfEvolutionStateGet event detected, emitting self-evolution-state-get-event");
|
|
405
|
+
this.emit("self-evolution-state-get-event", {
|
|
406
|
+
event: item,
|
|
407
|
+
sessionId: sessionId,
|
|
408
|
+
taskId: a2aRequest.params?.id,
|
|
409
|
+
messageId: a2aRequest.id,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
403
412
|
else if (item.header?.namespace === "LoginTokenEvent" && item.header?.name === "ClawAutoLogin") {
|
|
404
413
|
console.log("[XY] LoginTokenEvent.ClawAutoLogin detected, emitting login-token-event");
|
|
405
414
|
this.emit("login-token-event", {
|