@ynhcj/xiaoyi-channel 0.0.52-beta → 0.0.52-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.d.ts +0 -2
- package/dist/index.js +7 -6
- package/dist/src/bot.d.ts +1 -0
- package/dist/src/bot.js +44 -32
- package/dist/src/channel.js +32 -4
- package/dist/src/client.js +0 -6
- package/dist/src/cspl/call-api.js +19 -9
- package/dist/src/cspl/config.js +3 -3
- package/dist/src/cspl/constants.d.ts +2 -1
- package/dist/src/cspl/constants.js +1 -1
- package/dist/src/file-download.js +1 -1
- package/dist/src/file-upload.js +1 -11
- package/dist/src/formatter.d.ts +2 -0
- package/dist/src/formatter.js +11 -6
- package/dist/src/monitor.js +8 -10
- package/dist/src/onboarding.d.ts +3 -4
- package/dist/src/onboarding.js +2 -2
- package/dist/src/outbound.d.ts +2 -1
- package/dist/src/outbound.js +1 -19
- package/dist/src/parser.d.ts +6 -0
- package/dist/src/parser.js +16 -0
- package/dist/src/provider.d.ts +2 -0
- package/dist/src/provider.js +124 -0
- package/dist/src/push.js +0 -21
- package/dist/src/reply-dispatcher.d.ts +4 -0
- package/dist/src/reply-dispatcher.js +21 -13
- package/dist/src/thread-bindings.d.ts +54 -0
- package/dist/src/thread-bindings.js +214 -0
- package/dist/src/tools/call-phone-tool.js +2 -18
- package/dist/src/tools/create-alarm-tool.js +3 -7
- package/dist/src/tools/device-tool-map.d.ts +4 -0
- package/dist/src/tools/device-tool-map.js +35 -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/image-reading-tool.js +3 -3
- package/dist/src/tools/modify-alarm-tool.js +3 -7
- package/dist/src/tools/save-file-to-phone-tool.d.ts +5 -0
- package/dist/src/tools/save-file-to-phone-tool.js +170 -0
- package/dist/src/tools/save-media-to-gallery-tool.d.ts +5 -0
- package/dist/src/tools/save-media-to-gallery-tool.js +178 -0
- package/dist/src/tools/send-command-to-car-tool.d.ts +5 -0
- package/dist/src/tools/send-command-to-car-tool.js +85 -0
- package/dist/src/tools/send-file-to-user-tool.js +1 -0
- package/dist/src/tools/session-manager.d.ts +1 -0
- package/dist/src/tools/timestamp-to-utc8-tool.d.ts +12 -0
- package/dist/src/tools/timestamp-to-utc8-tool.js +104 -0
- package/dist/src/tools/upload-file-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 +188 -0
- package/dist/src/tools/xiaoyi-collection-tool.js +42 -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/utils/runtime-manager.d.ts +7 -0
- package/dist/src/utils/runtime-manager.js +42 -0
- package/dist/src/websocket.js +15 -9
- package/openclaw.plugin.json +1 -0
- package/package.json +3 -4
- package/dist/src/tools/search-photo-tool.d.ts +0 -9
- package/dist/src/tools/search-photo-tool.js +0 -270
- package/dist/src/utils/session.d.ts +0 -34
- package/dist/src/utils/session.js +0 -50
|
@@ -1,26 +1,54 @@
|
|
|
1
1
|
import { getXYWebSocketManager } from "../client.js";
|
|
2
2
|
import { sendCommand } from "../formatter.js";
|
|
3
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
|
+
}
|
|
4
16
|
/**
|
|
5
17
|
* XY collection tool - retrieves user's collection data from XiaoYi.
|
|
6
18
|
* Returns personalized knowledge data saved in user's collection.
|
|
7
19
|
*/
|
|
8
20
|
export const xiaoyiCollectionTool = {
|
|
9
|
-
name: "
|
|
21
|
+
name: "query_collection",
|
|
10
22
|
label: "XiaoYi Collection",
|
|
11
|
-
description:
|
|
23
|
+
description: `检索用户在小艺收藏中记下来的公共知识数据,本技能支持查询用户收藏的公共知识数据,也可以根据特定语义化描述进行特定内容的检索,通过参数进行控制。本技能返回结果中,linkTitle是收藏内容的标题,description是对收藏内容的总结,label是收藏内容的标签,linkUrl是可以直接访问的原始内容链接。如果你认为某条数据对用户交互有用,可以通过linkUrl抓取更加丰富的原始数据。
|
|
24
|
+
注意:
|
|
25
|
+
a. 操作超时时间为60秒,请勿重复调用此工具
|
|
26
|
+
b. 如果遇到各类调用失败场景,最多只能重试一次,不可以重复调用多次。
|
|
27
|
+
c. 调用工具前需认真检查调用参数是否满足工具要求
|
|
28
|
+
|
|
29
|
+
回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。
|
|
30
|
+
`,
|
|
12
31
|
parameters: {
|
|
13
32
|
type: "object",
|
|
14
33
|
properties: {
|
|
15
34
|
queryAll: {
|
|
16
35
|
type: "string",
|
|
17
|
-
description: "
|
|
18
|
-
|
|
36
|
+
description: "非必填参数,描述是否需要查询用户所有收藏数据。如果填入true则表示获取用户所有公共知识数据,其他参数无效。",
|
|
37
|
+
},
|
|
38
|
+
query: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "非必填参数,queryAll不填或者为false则必填。用户的查询条件,可按照用户query进行检索。",
|
|
19
41
|
},
|
|
20
42
|
},
|
|
21
43
|
required: [],
|
|
22
44
|
},
|
|
23
45
|
async execute(toolCallId, params) {
|
|
46
|
+
// Validate parameters
|
|
47
|
+
const queryAll = params.queryAll;
|
|
48
|
+
const query = params.query;
|
|
49
|
+
if (queryAll !== "true" && (!query || typeof query !== "string")) {
|
|
50
|
+
throw new ToolInputError("queryAll不为true时,query参数必填");
|
|
51
|
+
}
|
|
24
52
|
// Get session context
|
|
25
53
|
const sessionContext = getCurrentSessionContext();
|
|
26
54
|
if (!sessionContext) {
|
|
@@ -29,6 +57,15 @@ export const xiaoyiCollectionTool = {
|
|
|
29
57
|
const { config, sessionId, taskId, messageId } = sessionContext;
|
|
30
58
|
// Get WebSocket manager
|
|
31
59
|
const wsManager = getXYWebSocketManager(config);
|
|
60
|
+
// Build intentParam
|
|
61
|
+
const intentParam = {};
|
|
62
|
+
if (queryAll === "true") {
|
|
63
|
+
intentParam.queryAll = "true";
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
intentParam.queryAll = "false";
|
|
67
|
+
intentParam.query = query;
|
|
68
|
+
}
|
|
32
69
|
// Build QueryCollection command
|
|
33
70
|
const command = {
|
|
34
71
|
header: {
|
|
@@ -45,9 +82,7 @@ export const xiaoyiCollectionTool = {
|
|
|
45
82
|
actionResponse: true,
|
|
46
83
|
appType: "OHOS_APP",
|
|
47
84
|
timeOut: 5,
|
|
48
|
-
intentParam
|
|
49
|
-
queryAll: params.queryAll || "true",
|
|
50
|
-
},
|
|
85
|
+
intentParam,
|
|
51
86
|
permissionId: [],
|
|
52
87
|
achieveType: "INTENT",
|
|
53
88
|
},
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 保存 runtime 信息到 .xiaoyiruntime 文件
|
|
3
|
+
* @param webSocketSessionId - WebSocket 层级的 sessionId (SESSION_ID)
|
|
4
|
+
* @param conversationId - param 里的 sessionId (CONVERSATION_ID)
|
|
5
|
+
* @param taskId - 任务 ID (param.id)
|
|
6
|
+
*/
|
|
7
|
+
export declare function saveRuntimeInfo(webSocketSessionId: string, conversationId: string, taskId: string): Promise<void>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// xiaoyi runtime 持久化管理器
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { logger } from "./logger.js";
|
|
5
|
+
const RUNTIME_FILE = "/home/sandbox/.openclaw/.xiaoyiruntime";
|
|
6
|
+
/**
|
|
7
|
+
* 确保目录存在
|
|
8
|
+
*/
|
|
9
|
+
async function ensureDirectoryExists(filePath) {
|
|
10
|
+
const dir = path.dirname(filePath);
|
|
11
|
+
try {
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
logger.error(`[RuntimeManager] Failed to create directory ${dir}:`, error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 保存 runtime 信息到 .xiaoyiruntime 文件
|
|
20
|
+
* @param webSocketSessionId - WebSocket 层级的 sessionId (SESSION_ID)
|
|
21
|
+
* @param conversationId - param 里的 sessionId (CONVERSATION_ID)
|
|
22
|
+
* @param taskId - 任务 ID (param.id)
|
|
23
|
+
*/
|
|
24
|
+
export async function saveRuntimeInfo(webSocketSessionId, conversationId, taskId) {
|
|
25
|
+
if (!webSocketSessionId || !conversationId || !taskId) {
|
|
26
|
+
logger.warn(`[RuntimeManager] Invalid params: SESSION_ID=${webSocketSessionId}, CONVERSATION_ID=${conversationId}, TASK_ID=${taskId}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
await ensureDirectoryExists(RUNTIME_FILE);
|
|
31
|
+
const content = `SESSION_ID=${webSocketSessionId}\nCONVERSATION_ID=${conversationId}\nTASK_ID=${taskId}\n`;
|
|
32
|
+
await fs.writeFile(RUNTIME_FILE, content, "utf-8");
|
|
33
|
+
logger.log(`[RuntimeManager] ✅ Saved runtime info to .xiaoyiruntime`);
|
|
34
|
+
logger.log(`[RuntimeManager] - SESSION_ID: ${webSocketSessionId}`);
|
|
35
|
+
logger.log(`[RuntimeManager] - CONVERSATION_ID: ${conversationId}`);
|
|
36
|
+
logger.log(`[RuntimeManager] - TASK_ID: ${taskId}`);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
logger.error(`[RuntimeManager] Failed to save runtime info:`, error);
|
|
40
|
+
// 不抛出异常,避免影响主流程
|
|
41
|
+
}
|
|
42
|
+
}
|
package/dist/src/websocket.js
CHANGED
|
@@ -318,30 +318,37 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
318
318
|
* Handle incoming message from server.
|
|
319
319
|
*/
|
|
320
320
|
handleMessage(data) {
|
|
321
|
-
console.log("[WEBSOCKET-HANDLE] >>>>>>> Receiving message... <<<<<<<");
|
|
322
321
|
try {
|
|
323
322
|
const messageStr = data.toString();
|
|
324
|
-
console.log(`[WS-RECV] Raw message frame, size: ${messageStr.length}
|
|
323
|
+
console.log(`[WS-RECV] Raw message frame, size: ${messageStr.length} characters`);
|
|
325
324
|
const parsed = JSON.parse(messageStr);
|
|
326
325
|
// 提取并打印消息内容(只显示 text,data 只打印提示)
|
|
327
326
|
const parts = parsed.params?.message?.parts;
|
|
328
327
|
if (parts && Array.isArray(parts) && parts.length > 0) {
|
|
329
328
|
const textParts = parts.filter((p) => p?.kind === "text");
|
|
330
329
|
const dataParts = parts.filter((p) => p?.kind === "data");
|
|
331
|
-
// 打印 text
|
|
330
|
+
// 打印 text 内容(隐藏敏感信息)
|
|
332
331
|
if (textParts.length > 0) {
|
|
333
332
|
const textContents = textParts
|
|
334
333
|
.map((p) => p?.text || "")
|
|
335
334
|
.filter((text) => text.length > 0)
|
|
336
335
|
.join(" ");
|
|
337
336
|
if (textContents.length > 0) {
|
|
338
|
-
|
|
337
|
+
// 隐藏中间内容,只保留前后各5个字符
|
|
338
|
+
let maskedText;
|
|
339
|
+
if (textContents.length <= 8) {
|
|
340
|
+
// 如果长度 <= 8,显示前2个 + *** + 后2个
|
|
341
|
+
maskedText = textContents.length >= 4
|
|
342
|
+
? `${textContents.slice(0, 2)}***${textContents.slice(-2)}`
|
|
343
|
+
: `${textContents.slice(0, 1)}***${textContents.slice(-1)}`;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
// 如果长度 > 8,显示前5个 + *** + 后5个
|
|
347
|
+
maskedText = `${textContents.slice(0, 5)}***${textContents.slice(-5)}`;
|
|
348
|
+
}
|
|
349
|
+
console.log("[WS-RECV] Text:", maskedText);
|
|
339
350
|
}
|
|
340
351
|
}
|
|
341
|
-
// 打印 data 提示
|
|
342
|
-
if (dataParts.length > 0) {
|
|
343
|
-
console.log("[WS-RECV] Data: received data message(s)");
|
|
344
|
-
}
|
|
345
352
|
}
|
|
346
353
|
// Check if message is in direct A2A JSON-RPC format (server push)
|
|
347
354
|
if (parsed.jsonrpc === "2.0") {
|
|
@@ -392,7 +399,6 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
392
399
|
return;
|
|
393
400
|
}
|
|
394
401
|
// Emit message event for non-data-only messages
|
|
395
|
-
console.log("[XY] *** EMITTING message event (Direct A2A path) ***");
|
|
396
402
|
this.emit("message", a2aRequest, sessionId);
|
|
397
403
|
return;
|
|
398
404
|
}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ynhcj/xiaoyi-channel",
|
|
3
|
-
"version": "0.0.52-
|
|
3
|
+
"version": "0.0.52-next",
|
|
4
4
|
"description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"openclaw": ">=2026.3.
|
|
52
|
+
"openclaw": ">=2026.3.24"
|
|
53
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|
|
55
55
|
"openclaw": {
|
|
@@ -59,13 +59,12 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"ws": "^8.14.2",
|
|
61
61
|
"uuid": "^9.0.0",
|
|
62
|
-
"node-fetch": "^
|
|
62
|
+
"node-fetch": "^3.3.2"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@types/ws": "^8.5.8",
|
|
66
66
|
"@types/uuid": "^9.0.5",
|
|
67
67
|
"@types/node": "^20.8.0",
|
|
68
|
-
"@types/node-fetch": "^2.6.2",
|
|
69
68
|
"typescript": "^5.9.2"
|
|
70
69
|
}
|
|
71
70
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* XY search photo tool - searches photos in user's gallery.
|
|
3
|
-
* Returns publicly accessible URLs of matching photos based on query description.
|
|
4
|
-
*
|
|
5
|
-
* This tool performs a two-step operation:
|
|
6
|
-
* 1. Search for photos using query description
|
|
7
|
-
* 2. Upload found photos to get publicly accessible URLs
|
|
8
|
-
*/
|
|
9
|
-
export declare const searchPhotoTool: any;
|