@ynhcj/xiaoyi-channel 0.0.65-beta → 0.0.65-next
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 +7 -4
- package/dist/src/bot.js +1 -0
- package/dist/src/channel.js +14 -19
- package/dist/src/cspl/call-api.js +14 -11
- package/dist/src/cspl/config.js +3 -3
- package/dist/src/cspl/constants.d.ts +2 -0
- package/dist/src/cspl/constants.js +12 -0
- package/dist/src/cspl/utils.js +4 -2
- package/dist/src/file-download.js +3 -6
- package/dist/src/file-upload.js +52 -5
- package/dist/src/login-token-handler.d.ts +8 -0
- package/dist/src/login-token-handler.js +60 -0
- package/dist/src/monitor.js +15 -0
- package/dist/src/outbound.js +2 -7
- package/dist/src/provider.d.ts +2 -0
- package/dist/src/provider.js +368 -0
- package/dist/src/reply-dispatcher.js +6 -0
- package/dist/src/self-evolution-handler.d.ts +1 -0
- package/dist/src/self-evolution-handler.js +47 -0
- package/dist/src/skill-retriever/config.d.ts +4 -0
- package/dist/src/skill-retriever/config.js +23 -0
- package/dist/src/skill-retriever/hooks.d.ts +3 -0
- package/dist/src/skill-retriever/hooks.js +97 -0
- package/dist/src/skill-retriever/tool-search.d.ts +16 -0
- package/dist/src/skill-retriever/tool-search.js +166 -0
- package/dist/src/skill-retriever/types.d.ts +34 -0
- package/dist/src/skill-retriever/types.js +1 -0
- package/dist/src/tools/call-device-tool.d.ts +5 -0
- package/dist/src/tools/call-device-tool.js +130 -0
- package/dist/src/tools/create-alarm-tool.js +5 -16
- package/dist/src/tools/delete-alarm-tool.js +1 -4
- package/dist/src/tools/device-tool-map.js +6 -0
- package/dist/src/tools/find-pc-devices-tool.d.ts +5 -0
- package/dist/src/tools/find-pc-devices-tool.js +98 -0
- package/dist/src/tools/get-alarm-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-alarm-tool-schema.js +11 -0
- package/dist/src/tools/get-calendar-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-calendar-tool-schema.js +9 -0
- package/dist/src/tools/get-collection-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-collection-tool-schema.js +10 -0
- package/dist/src/tools/get-contact-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-contact-tool-schema.js +11 -0
- package/dist/src/tools/get-device-file-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-device-file-tool-schema.js +10 -0
- package/dist/src/tools/get-email-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-email-tool-schema.js +9 -0
- package/dist/src/tools/get-note-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-note-tool-schema.js +10 -0
- package/dist/src/tools/get-photo-tool-schema.d.ts +16 -0
- package/dist/src/tools/get-photo-tool-schema.js +10 -0
- package/dist/src/tools/image-reading-tool.js +4 -7
- package/dist/src/tools/login-token-tool.d.ts +5 -0
- package/dist/src/tools/login-token-tool.js +136 -0
- package/dist/src/tools/modify-alarm-tool.js +10 -23
- package/dist/src/tools/query-app-message-tool.d.ts +4 -0
- package/dist/src/tools/query-app-message-tool.js +138 -0
- package/dist/src/tools/query-memory-data-tool.d.ts +4 -0
- package/dist/src/tools/query-memory-data-tool.js +154 -0
- package/dist/src/tools/query-todo-task-tool.d.ts +4 -0
- package/dist/src/tools/query-todo-task-tool.js +133 -0
- package/dist/src/tools/save-file-to-phone-tool.d.ts +5 -0
- package/dist/src/tools/save-file-to-phone-tool.js +166 -0
- package/dist/src/tools/save-media-to-gallery-tool.d.ts +5 -0
- package/dist/src/tools/save-media-to-gallery-tool.js +174 -0
- package/dist/src/tools/schema-tool-factory.d.ts +27 -0
- package/dist/src/tools/schema-tool-factory.js +32 -0
- package/dist/src/tools/search-alarm-tool.js +6 -13
- package/dist/src/tools/search-calendar-tool.js +2 -0
- package/dist/src/tools/search-email-tool.d.ts +5 -0
- package/dist/src/tools/search-email-tool.js +137 -0
- package/dist/src/tools/search-file-tool.js +4 -4
- package/dist/src/tools/search-message-tool.js +1 -0
- package/dist/src/tools/search-photo-gallery-tool.js +2 -2
- package/dist/src/tools/send-email-tool.d.ts +4 -0
- package/dist/src/tools/send-email-tool.js +134 -0
- package/dist/src/tools/send-file-to-user-tool.js +2 -4
- package/dist/src/tools/upload-file-tool.js +4 -4
- package/dist/src/tools/upload-photo-tool.js +2 -2
- package/dist/src/tools/xiaoyi-add-collection-tool.d.ts +4 -0
- package/dist/src/tools/xiaoyi-add-collection-tool.js +192 -0
- package/dist/src/tools/xiaoyi-collection-tool.js +43 -7
- package/dist/src/tools/xiaoyi-delete-collection-tool.d.ts +4 -0
- package/dist/src/tools/xiaoyi-delete-collection-tool.js +163 -0
- package/dist/src/websocket.js +19 -0
- package/openclaw.plugin.json +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { getXYWebSocketManager } from "../client.js";
|
|
2
|
+
import { sendCommand } from "../formatter.js";
|
|
3
|
+
import { getCurrentSessionContext } from "./session-manager.js";
|
|
4
|
+
/**
|
|
5
|
+
* Duck-typed ToolInputError: openclaw 按 .name 字段匹配,不用 instanceof。
|
|
6
|
+
* 抛出此错误会让 openclaw 返回 HTTP 400 而非 500,
|
|
7
|
+
* LLM 会将其识别为参数错误而非瞬时故障,不会触发重试。
|
|
8
|
+
*/
|
|
9
|
+
class ToolInputError extends Error {
|
|
10
|
+
status = 400;
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "ToolInputError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* XY delete collection tool - deletes data from user's XiaoYi collection.
|
|
18
|
+
*/
|
|
19
|
+
export const xiaoyiDeleteCollectionTool = {
|
|
20
|
+
name: "delete_collection",
|
|
21
|
+
label: "Delete XiaoYi Collection",
|
|
22
|
+
description: `从小艺收藏中删除之前已保存的公共知识数据。任何用户希望删除已保存到个人知识库的数据都可以调用本技能。如果用户想更新之前的收藏数据,需要先query获取itemId然后再delete,最后执行Add,按照这个步骤完成收藏数据更新。
|
|
23
|
+
注意:
|
|
24
|
+
a. 操作超时时间为60秒,请勿重复调用此工具
|
|
25
|
+
b. 如果遇到各类调用失败场景,最多只能重试一次,不可以重复调用多次。
|
|
26
|
+
c. 调用工具前需认真检查调用参数是否满足工具要求
|
|
27
|
+
|
|
28
|
+
回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。
|
|
29
|
+
`,
|
|
30
|
+
parameters: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
itemIds: {
|
|
34
|
+
// 不指定 type,允许传入数组或 JSON 字符串
|
|
35
|
+
// 具体的类型验证和转换在 execute 函数内部进行
|
|
36
|
+
description: "准备删除的数据的itemId合集。itemId可以由用户指定,也可以从之前检索回来的收藏数据项的itemId字段获取。",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["itemIds"],
|
|
40
|
+
},
|
|
41
|
+
async execute(toolCallId, params) {
|
|
42
|
+
// ===== 参数规范化:兼容数组和 JSON 字符串 =====
|
|
43
|
+
let itemIds = null;
|
|
44
|
+
if (!params.itemIds) {
|
|
45
|
+
throw new ToolInputError("缺少必填参数: itemIds");
|
|
46
|
+
}
|
|
47
|
+
// 情况1: 已经是数组
|
|
48
|
+
if (Array.isArray(params.itemIds)) {
|
|
49
|
+
itemIds = params.itemIds;
|
|
50
|
+
}
|
|
51
|
+
// 情况2: 是字符串,尝试解析为 JSON 数组
|
|
52
|
+
else if (typeof params.itemIds === 'string') {
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(params.itemIds);
|
|
55
|
+
if (Array.isArray(parsed)) {
|
|
56
|
+
itemIds = parsed;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw new ToolInputError("itemIds must be an array or a JSON string representing an array");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (parseError) {
|
|
63
|
+
if (parseError instanceof ToolInputError)
|
|
64
|
+
throw parseError;
|
|
65
|
+
throw new ToolInputError(`itemIds must be a valid JSON array string. Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 情况3: 其他类型,报错
|
|
69
|
+
else {
|
|
70
|
+
throw new ToolInputError(`itemIds must be an array or a JSON string, got ${typeof params.itemIds}`);
|
|
71
|
+
}
|
|
72
|
+
// 验证数组非空
|
|
73
|
+
if (!itemIds || itemIds.length === 0) {
|
|
74
|
+
throw new ToolInputError("itemIds array cannot be empty");
|
|
75
|
+
}
|
|
76
|
+
// Get session context
|
|
77
|
+
const sessionContext = getCurrentSessionContext();
|
|
78
|
+
if (!sessionContext) {
|
|
79
|
+
throw new Error("No active XY session found. DeleteCollection tool can only be used during an active conversation.");
|
|
80
|
+
}
|
|
81
|
+
const { config, sessionId, taskId, messageId } = sessionContext;
|
|
82
|
+
// Get WebSocket manager
|
|
83
|
+
const wsManager = getXYWebSocketManager(config);
|
|
84
|
+
// Build DeleteCollection command
|
|
85
|
+
const command = {
|
|
86
|
+
header: {
|
|
87
|
+
namespace: "Common",
|
|
88
|
+
name: "Action",
|
|
89
|
+
},
|
|
90
|
+
payload: {
|
|
91
|
+
cardParam: {},
|
|
92
|
+
executeParam: {
|
|
93
|
+
executeMode: "background",
|
|
94
|
+
intentName: "DeleteCollection",
|
|
95
|
+
bundleName: "com.huawei.hmos.vassistant",
|
|
96
|
+
needUnlock: true,
|
|
97
|
+
actionResponse: true,
|
|
98
|
+
appType: "OHOS_APP",
|
|
99
|
+
timeOut: 5,
|
|
100
|
+
intentParam: {
|
|
101
|
+
itemIds,
|
|
102
|
+
},
|
|
103
|
+
permissionId: [],
|
|
104
|
+
achieveType: "INTENT",
|
|
105
|
+
},
|
|
106
|
+
responses: [
|
|
107
|
+
{
|
|
108
|
+
resultCode: "",
|
|
109
|
+
displayText: "",
|
|
110
|
+
ttsText: "",
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
needUploadResult: true,
|
|
114
|
+
noHalfPage: false,
|
|
115
|
+
pageControlRelated: false,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
// Send command and wait for response (60 second timeout)
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
const timeout = setTimeout(() => {
|
|
121
|
+
wsManager.off("data-event", handler);
|
|
122
|
+
reject(new Error("删除小艺收藏超时(60秒)"));
|
|
123
|
+
}, 60000);
|
|
124
|
+
// Listen for data events from WebSocket
|
|
125
|
+
const handler = (event) => {
|
|
126
|
+
if (event.intentName === "DeleteCollection") {
|
|
127
|
+
clearTimeout(timeout);
|
|
128
|
+
wsManager.off("data-event", handler);
|
|
129
|
+
if (event.status === "success" && event.outputs) {
|
|
130
|
+
resolve({
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: JSON.stringify(event.outputs),
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
reject(new Error(`删除小艺收藏失败: ${event.status}`));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
// Register event handler
|
|
145
|
+
wsManager.on("data-event", handler);
|
|
146
|
+
// Send the command
|
|
147
|
+
sendCommand({
|
|
148
|
+
config,
|
|
149
|
+
sessionId,
|
|
150
|
+
taskId,
|
|
151
|
+
messageId,
|
|
152
|
+
command,
|
|
153
|
+
})
|
|
154
|
+
.then(() => {
|
|
155
|
+
})
|
|
156
|
+
.catch((error) => {
|
|
157
|
+
clearTimeout(timeout);
|
|
158
|
+
wsManager.off("data-event", handler);
|
|
159
|
+
reject(error);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
};
|
package/dist/src/websocket.js
CHANGED
|
@@ -322,6 +322,7 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
322
322
|
const messageStr = data.toString();
|
|
323
323
|
console.log(`[WS-RECV] Raw message frame, size: ${messageStr.length} characters`);
|
|
324
324
|
const parsed = JSON.parse(messageStr);
|
|
325
|
+
console.log(`[WS-RECV] Raw message content: ${parsed}`);
|
|
325
326
|
// 提取并打印消息内容(只显示 text,data 只打印提示)
|
|
326
327
|
const parts = parsed.params?.message?.parts;
|
|
327
328
|
if (parts && Array.isArray(parts) && parts.length > 0) {
|
|
@@ -394,6 +395,18 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
394
395
|
taskId: a2aRequest.params?.id, // 新的 taskId(点击推送时生成)
|
|
395
396
|
});
|
|
396
397
|
}
|
|
398
|
+
else if (item.header?.namespace === "AgentEvent" && item.header?.name === "ClawSelfEvolutionState") {
|
|
399
|
+
console.log("[XY] ClawSelfEvolutionState event detected, emitting self-evolution-event");
|
|
400
|
+
this.emit("self-evolution-event", {
|
|
401
|
+
event: item,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
else if (item.header?.namespace === "LoginTokenEvent" && item.header?.name === "ClawAutoLogin") {
|
|
405
|
+
console.log("[XY] LoginTokenEvent.ClawAutoLogin detected, emitting login-token-event");
|
|
406
|
+
this.emit("login-token-event", {
|
|
407
|
+
event: item,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
397
410
|
}
|
|
398
411
|
}
|
|
399
412
|
return;
|
|
@@ -448,6 +461,12 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
448
461
|
taskId: inboundMsg.taskId || a2aRequest.params?.id,
|
|
449
462
|
});
|
|
450
463
|
}
|
|
464
|
+
else if (item.header?.namespace === "LoginTokenEvent" && item.header?.name === "ClawAutoLogin") {
|
|
465
|
+
console.log("[XY] LoginTokenEvent.ClawAutoLogin detected (wrapped format), emitting login-token-event");
|
|
466
|
+
this.emit("login-token-event", {
|
|
467
|
+
event: item,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
451
470
|
}
|
|
452
471
|
}
|
|
453
472
|
}
|
package/openclaw.plugin.json
CHANGED