@ynhcj/xiaoyi-channel 0.0.163-beta → 0.0.165-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.
Files changed (40) hide show
  1. package/dist/src/cspl/call_api.d.ts +1 -1
  2. package/dist/src/cspl/call_api.js +2 -2
  3. package/dist/src/cspl/config.js +30 -10
  4. package/dist/src/cspl/constants.d.ts +2 -0
  5. package/dist/src/cspl/constants.js +3 -0
  6. package/dist/src/cspl/sentinel_hook.js +2 -2
  7. package/dist/src/cspl/utils.js +2 -2
  8. package/dist/src/reply-dispatcher.js +3 -2
  9. package/dist/src/tools/calendar-tool.js +1 -1
  10. package/dist/src/tools/call-phone-tool.js +1 -1
  11. package/dist/src/tools/create-alarm-tool.js +1 -1
  12. package/dist/src/tools/create-all-tools.js +4 -2
  13. package/dist/src/tools/delete-alarm-tool.js +1 -1
  14. package/dist/src/tools/device-tool-map.js +1 -0
  15. package/dist/src/tools/display-a2ui-card-tool.d.ts +2 -0
  16. package/dist/src/tools/display-a2ui-card-tool.js +82 -0
  17. package/dist/src/tools/location-tool.js +1 -1
  18. package/dist/src/tools/modify-alarm-tool.js +1 -1
  19. package/dist/src/tools/modify-note-tool.js +1 -1
  20. package/dist/src/tools/note-tool.js +1 -1
  21. package/dist/src/tools/query-app-message-tool.js +1 -1
  22. package/dist/src/tools/query-memory-data-tool.js +1 -1
  23. package/dist/src/tools/query-todo-task-tool.js +1 -1
  24. package/dist/src/tools/save-file-to-phone-tool.js +1 -1
  25. package/dist/src/tools/save-media-to-gallery-tool.js +1 -1
  26. package/dist/src/tools/search-alarm-tool.js +1 -1
  27. package/dist/src/tools/search-calendar-tool.js +1 -1
  28. package/dist/src/tools/search-contact-tool.js +1 -1
  29. package/dist/src/tools/search-email-tool.js +1 -1
  30. package/dist/src/tools/search-note-tool.js +1 -1
  31. package/dist/src/tools/search-photo-gallery-tool.js +1 -1
  32. package/dist/src/tools/send-email-tool.js +1 -1
  33. package/dist/src/tools/session-manager.d.ts +1 -0
  34. package/dist/src/tools/session-manager.js +13 -0
  35. package/dist/src/tools/upload-file-tool.js +1 -1
  36. package/dist/src/tools/upload-photo-tool.js +1 -1
  37. package/dist/src/tools/xiaoyi-add-collection-tool.js +1 -1
  38. package/dist/src/tools/xiaoyi-collection-tool.js +1 -1
  39. package/dist/src/tools/xiaoyi-delete-collection-tool.js +1 -1
  40. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
1
  import { ApiResponse } from './constants.js';
2
- export declare function callApi(questionText: string, api: any, sessionId: string): Promise<ApiResponse>;
2
+ export declare function callApi(questionText: string, api: any, sessionId: string, action: string): Promise<ApiResponse>;
@@ -78,13 +78,13 @@ function handleResponse(res, resolve, reject) {
78
78
  }
79
79
  });
80
80
  }
81
- export async function callApi(questionText, api, sessionId) {
81
+ export async function callApi(questionText, api, sessionId, action) {
82
82
  const config = getConfig(api);
83
83
  const headersForCelia = buildHeadersForCelia(config, sessionId);
84
84
  const payload = {
85
85
  questionText: questionText,
86
86
  textSource: config.textSource,
87
- action: config.action,
87
+ action: action,
88
88
  extra: `${JSON.stringify({ userId: config.uid })}`
89
89
  };
90
90
  const httpBody = JSON.stringify(payload);
@@ -2,9 +2,9 @@
2
2
  * 版权所有 (c) 华为技术有限公司 2026-2026
3
3
  */
4
4
  import fs from 'fs';
5
- import { ENV_FILE_PATH, REQUIRED_ENV_VARS } from './constants.js';
5
+ import path from 'path';
6
+ import { CONFIG_FILE_NAME, ENV_FILE_PATH, REQUIRED_ENV_VARS } from './constants.js';
6
7
  import { logger } from '../utils/logger.js';
7
- import defaultConfig from './configs.json' with { type: 'json' };
8
8
  let cachedConfig = null;
9
9
  function readEnvFile() {
10
10
  if (!fs.existsSync(ENV_FILE_PATH)) {
@@ -41,25 +41,45 @@ export function getConfig(api) {
41
41
  if (cachedConfig) {
42
42
  return cachedConfig;
43
43
  }
44
- // Use imported JSON (bundled at compile time, no runtime file read needed)
45
- const config = { ...defaultConfig };
44
+ const configPath = path.join(__dirname, CONFIG_FILE_NAME);
45
+ if (!fs.existsSync(configPath)) {
46
+ throw new Error(`Config file not found: ${CONFIG_FILE_NAME}`);
47
+ }
48
+ let configData;
49
+ try {
50
+ configData = fs.readFileSync(configPath, 'utf-8');
51
+ }
52
+ catch (error) {
53
+ throw new Error(`Failed to read config file: ${CONFIG_FILE_NAME}.`);
54
+ }
55
+ let parsedConfig;
56
+ try {
57
+ parsedConfig = JSON.parse(configData);
58
+ }
59
+ catch (error) {
60
+ throw new Error(`Failed to parse config file: ${CONFIG_FILE_NAME}.`);
61
+ }
62
+ if (!parsedConfig || typeof parsedConfig !== 'object') {
63
+ throw new Error(`Invalid config structure: ${CONFIG_FILE_NAME}. Expected an object.`);
64
+ }
65
+ const config = parsedConfig;
46
66
  if (!config.api || typeof config.api !== 'object') {
47
- throw new Error(`Invalid config: missing or invalid 'api' section`);
67
+ throw new Error(`Invalid config: missing or invalid 'api' section in ${CONFIG_FILE_NAME}`);
48
68
  }
49
69
  if (!config.api.timeout || typeof config.api.timeout !== 'number') {
50
- throw new Error(`Invalid config: missing or invalid 'api.timeout'`);
70
+ throw new Error(`Invalid config: missing or invalid 'api.timeout' in ${CONFIG_FILE_NAME}`);
51
71
  }
52
72
  if (!config.skillId || typeof config.skillId !== 'string') {
53
- throw new Error(`Invalid config: missing or invalid 'skillId'`);
73
+ throw new Error(`Invalid config: missing or invalid 'skillId' in ${CONFIG_FILE_NAME}`);
54
74
  }
55
75
  if (!config.requestFrom || typeof config.requestFrom !== 'string') {
56
- throw new Error(`Invalid config: missing or invalid 'requestFrom'`);
76
+ throw new Error(`Invalid config: missing or invalid 'requestFrom' in ${CONFIG_FILE_NAME}`);
57
77
  }
58
78
  if (!config.textSource || typeof config.textSource !== 'string') {
59
- throw new Error(`Invalid config: missing or invalid 'textSource'`);
79
+ throw new Error(`Invalid config: missing or invalid 'textSource' in ${CONFIG_FILE_NAME}`);
60
80
  }
61
81
  if (!config.action || typeof config.action !== 'string') {
62
- throw new Error(`Invalid config: missing or invalid 'action'`);
82
+ throw new Error(`Invalid config: missing or invalid 'action' in ${CONFIG_FILE_NAME}`);
63
83
  }
64
84
  let env;
65
85
  try {
@@ -43,6 +43,8 @@ export declare const TOOL_INPUT_DEFAULT: {
43
43
  readonly source: "";
44
44
  readonly content: "";
45
45
  };
46
+ export declare const TOOL_INPUT_ACTION = "TOOL_INPUT_SCAN";
47
+ export declare const TOOL_OUTPUT_ACTION = "TOOL_OUTPUT_SCAN";
46
48
  export declare const MAX_TIMES = 3;
47
49
  export declare const CONNECT_TIMEOUT = 15000;
48
50
  export declare const READ_TIMEOUT = 300000;
@@ -47,6 +47,9 @@ export const TOOL_INPUT_DEFAULT = {
47
47
  source: '',
48
48
  content: ''
49
49
  };
50
+ // 安全扫描 action 常量
51
+ export const TOOL_INPUT_ACTION = 'TOOL_INPUT_SCAN';
52
+ export const TOOL_OUTPUT_ACTION = 'TOOL_OUTPUT_SCAN';
50
53
  // OBS上传相关常量
51
54
  export const MAX_TIMES = 3;
52
55
  export const CONNECT_TIMEOUT = 15000;
@@ -4,7 +4,7 @@
4
4
  import crypto from 'crypto';
5
5
  import { callApi } from './call_api.js';
6
6
  import { processText, extractResultText, validateAndTruncateText, parseSecurityResult, handleExecToolInput, handleMessageToolInput, handleOtherToolInput } from './utils.js';
7
- import { ALLOWED_TOOLS, MAX_TEXT_LENGTH, MAX_TOTAL_LENGTH, MIN_TEXT_LENGTH, STEER_ABORT_MESSAGE } from './constants.js';
7
+ import { ALLOWED_TOOLS, MAX_TEXT_LENGTH, MAX_TOTAL_LENGTH, MIN_TEXT_LENGTH, STEER_ABORT_MESSAGE, TOOL_OUTPUT_ACTION } from './constants.js';
8
8
  import { logger } from '../utils/logger.js';
9
9
  import { getSessionContext } from '../tools/session-manager.js';
10
10
  import { tryInjectSteer } from './steer-context.js';
@@ -68,7 +68,7 @@ export default function register(api) {
68
68
  const postText = JSON.stringify(questionText);
69
69
  logger.log(`[SENTINEL HOOK] Content extracted successfully. Length: ${postText.length}`);
70
70
  try {
71
- const response = await callApi(postText, api, sessionId);
71
+ const response = await callApi(postText, api, sessionId, TOOL_OUTPUT_ACTION);
72
72
  const result = parseSecurityResult(response);
73
73
  logger.log(`[SENTINEL HOOK] TOOL_OUTPUT response: status=${result.status}.`);
74
74
  if (result.status === 'REJECT') {
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * 版权所有 (c) 华为技术有限公司 2026-2026
3
3
  */
4
- import { MAX_TEXT_LENGTH, regex, SECURITY_NOTICE, MAX_FILE_COUNT, MAX_COMMAND_LENGTH, CODE_FILE_EXTENSIONS, TOOL_INPUT_DEFAULT, FILE_EXTENSION_REGEX } from './constants.js';
4
+ import { MAX_TEXT_LENGTH, regex, SECURITY_NOTICE, MAX_FILE_COUNT, MAX_COMMAND_LENGTH, CODE_FILE_EXTENSIONS, TOOL_INPUT_DEFAULT, FILE_EXTENSION_REGEX, TOOL_INPUT_ACTION } from './constants.js';
5
5
  import crypto from 'crypto';
6
6
  import fs from 'fs';
7
7
  import path from 'path';
@@ -215,7 +215,7 @@ export function adjustContentLength(data, api, fields) {
215
215
  }
216
216
  // 发送TOOL_INPUT请求并处理响应
217
217
  async function sendToolInputRequest(postText, api, sessionId) {
218
- const response = await callApi(postText, api, sessionId);
218
+ const response = await callApi(postText, api, sessionId, TOOL_INPUT_ACTION);
219
219
  const result = parseSecurityResult(response);
220
220
  logger.log(`[SENTINEL HOOK] TOOL_INPUT response: status=${result.status}`);
221
221
  }
@@ -2,7 +2,7 @@ import { getXYRuntime } from "./runtime.js";
2
2
  import { sendA2AResponse, sendStatusUpdate, sendReasoningTextUpdate, sendCommand } from "./formatter.js";
3
3
  import { resolveXYConfig } from "./config.js";
4
4
  import { getCurrentTaskId, getCurrentMessageId } from "./task-manager.js";
5
- import { getCurrentSessionContext } from "./tools/session-manager.js";
5
+ import { clearRunCrossTaskSentFiles, getCurrentSessionContext } from "./tools/session-manager.js";
6
6
  import fs from "fs/promises";
7
7
  import path from "path";
8
8
  import { logger } from "./utils/logger.js";
@@ -48,7 +48,8 @@ async function sendRunCrossTaskResult(params) {
48
48
  messageId,
49
49
  commands: [statusCommand, resultCommand],
50
50
  });
51
- logger.log(`${RUN_CROSS_TASK_LOG_TAG} sent cross-task result, sessionId=${sessionId}, taskId=${taskId}, code=${resultCode}, sentFileCount=${sentFiles.length}, messageLength=${resultMessage.length}`);
51
+ clearRunCrossTaskSentFiles(context);
52
+ logger.log(`${RUN_CROSS_TASK_LOG_TAG} sent cross-task result, sessionId=${sessionId}, taskId=${taskId}, code=${resultCode}, sentFileCount=${sentFiles.length}, clearedSentFileCount=${sentFiles.length}, messageLength=${resultMessage.length}`);
52
53
  }
53
54
  /**
54
55
  * 清理 /tmp/xy_channel 目录中超过 24 小时的旧文件
@@ -106,7 +106,7 @@ export function createCalendarTool(ctx) {
106
106
  });
107
107
  }
108
108
  else {
109
- reject(new Error(`创建日程失败: ${event.status}`));
109
+ reject(new Error(`创建日程失败: ${JSON.stringify(event.outputs)}`));
110
110
  }
111
111
  }
112
112
  };
@@ -98,7 +98,7 @@ export function createCallPhoneTool(ctx) {
98
98
  });
99
99
  }
100
100
  else {
101
- reject(new Error(`拨打电话失败: ${event.status}`));
101
+ reject(new Error(`拨打电话失败: ${JSON.stringify(event.outputs)}`));
102
102
  }
103
103
  }
104
104
  };
@@ -244,7 +244,7 @@ b. 使用该工具之前需获取当前真实时间
244
244
  });
245
245
  }
246
246
  else {
247
- reject(new Error(`创建闹钟失败: ${event.status}`));
247
+ reject(new Error(`创建闹钟失败: ${JSON.stringify(event.outputs)}`));
248
248
  }
249
249
  }
250
250
  };
@@ -13,11 +13,12 @@ import { createGetPhotoToolSchemaTool } from "./get-photo-tool-schema.js";
13
13
  import { createGetDeviceFileToolSchemaTool } from "./get-device-file-tool-schema.js";
14
14
  import { createGetAlarmToolSchemaTool } from "./get-alarm-tool-schema.js";
15
15
  import { createGetCollectionToolSchemaTool } from "./get-collection-tool-schema.js";
16
- import { createGetEmailToolSchemaTool } from "./get-email-tool-schema.js";
16
+ // import { createGetEmailToolSchemaTool } from "./get-email-tool-schema.js";
17
17
  import { createLoginTokenTool } from "./login-token-tool.js";
18
18
  import { createAgentAsSkillTool } from "./agent-as-skill-tool.js";
19
19
  import { createDiscoverCrossDevicesTool } from "./discover-cross-devices-tool.js";
20
20
  import { createSendCrossDeviceTaskTool } from "./send-cross-device-task-tool.js";
21
+ import { createDisplayA2UICardTool } from "./display-a2ui-card-tool.js";
21
22
  import { logger } from "../utils/logger.js";
22
23
  /**
23
24
  * Create all XY channel tools for the given session context.
@@ -35,6 +36,7 @@ export function createAllTools(ctx) {
35
36
  createLocationTool(ctx),
36
37
  createDiscoverCrossDevicesTool(ctx),
37
38
  createSendCrossDeviceTaskTool(ctx),
39
+ createDisplayA2UICardTool(ctx),
38
40
  createCallDeviceTool(ctx),
39
41
  createGetNoteToolSchemaTool(ctx),
40
42
  createGetCalendarToolSchemaTool(ctx),
@@ -45,7 +47,7 @@ export function createAllTools(ctx) {
45
47
  createGetAlarmToolSchemaTool(ctx),
46
48
  createGetCollectionToolSchemaTool(ctx),
47
49
  createSendFileToUserTool(ctx),
48
- createGetEmailToolSchemaTool(ctx),
50
+ // createGetEmailToolSchemaTool(ctx),
49
51
  viewPushResultTool,
50
52
  createImageReadingTool(ctx),
51
53
  timestampToUtc8Tool,
@@ -143,7 +143,7 @@ export function createDeleteAlarmTool(ctx) {
143
143
  });
144
144
  }
145
145
  else {
146
- reject(new Error(`删除闹钟失败: ${event.status}`));
146
+ reject(new Error(`删除闹钟失败: ${JSON.stringify(event.outputs)}`));
147
147
  }
148
148
  }
149
149
  };
@@ -25,6 +25,7 @@ const DEVICE_TOOL_POLICY = {
25
25
  "image_reading",
26
26
  "convert_time_to_utc8_time",
27
27
  "save_self_evolution_skill",
28
+ "displayA2UICard",
28
29
  ],
29
30
  },
30
31
  };
@@ -0,0 +1,2 @@
1
+ import type { SessionContext } from "./session-manager.js";
2
+ export declare function createDisplayA2UICardTool(ctx: SessionContext): any;
@@ -0,0 +1,82 @@
1
+ import { sendCommand } from "../formatter.js";
2
+ import { getCurrentMessageId, getCurrentTaskId } from "../task-manager.js";
3
+ import { logger } from "../utils/logger.js";
4
+ class ToolInputError extends Error {
5
+ status = 400;
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = "ToolInputError";
9
+ }
10
+ }
11
+ function isPlainObject(value) {
12
+ return !!value && typeof value === "object" && !Array.isArray(value);
13
+ }
14
+ export function createDisplayA2UICardTool(ctx) {
15
+ const { config, sessionId, taskId, messageId } = ctx;
16
+ return {
17
+ name: "displayA2UICard",
18
+ label: "Display A2UI Card",
19
+ description: "当模型根据 MCP 工具返回结果判断需要向端侧下发 A2UI card 时调用。参数 cardId 和 cardData 由模型根据 MCP 工具返回结果传入,本工具只负责下发卡片展示指令。",
20
+ parameters: {
21
+ type: "object",
22
+ properties: {
23
+ cardId: {
24
+ type: "string",
25
+ description: "A2UI card 的唯一标识。",
26
+ },
27
+ cardData: {
28
+ type: "object",
29
+ description: "A2UI card 渲染所需的数据对象,由模型根据 MCP 工具返回结果填充。",
30
+ },
31
+ },
32
+ required: ["cardId", "cardData"],
33
+ },
34
+ async execute(toolCallId, params) {
35
+ const cardId = typeof params?.cardId === "string" ? params.cardId.trim() : "";
36
+ const cardData = params?.cardData;
37
+ if (!cardId) {
38
+ throw new ToolInputError("缺少必填参数: cardId");
39
+ }
40
+ if (!isPlainObject(cardData)) {
41
+ throw new ToolInputError("缺少必填参数: cardData,且必须是对象");
42
+ }
43
+ const currentTaskId = getCurrentTaskId(sessionId) ?? taskId;
44
+ const currentMessageId = getCurrentMessageId(sessionId) ?? messageId;
45
+ const command = {
46
+ header: {
47
+ namespace: "Common",
48
+ name: "DisplayFACard",
49
+ },
50
+ payload: {
51
+ isA2ui: true,
52
+ a2uiParam: {
53
+ cardId,
54
+ cardData,
55
+ },
56
+ },
57
+ };
58
+ logger.log(`[DISPLAY-A2UI-CARD] sending card, cardId=${cardId}`);
59
+ await sendCommand({
60
+ config,
61
+ sessionId,
62
+ taskId: currentTaskId,
63
+ messageId: currentMessageId,
64
+ command,
65
+ toolCallId,
66
+ });
67
+ logger.log(`[DISPLAY-A2UI-CARD] card sent successfully, cardId=${cardId}`);
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text: JSON.stringify({
73
+ success: true,
74
+ cardId,
75
+ message: "A2UI card display command sent successfully.",
76
+ }),
77
+ },
78
+ ],
79
+ };
80
+ },
81
+ };
82
+ }
@@ -75,7 +75,7 @@ export function createLocationTool(ctx) {
75
75
  });
76
76
  }
77
77
  else {
78
- reject(new Error(`获取位置失败: ${event.status}`));
78
+ reject(new Error(`获取位置失败: ${JSON.stringify(event.outputs)}`));
79
79
  }
80
80
  }
81
81
  };
@@ -256,7 +256,7 @@ export function createModifyAlarmTool(ctx) {
256
256
  });
257
257
  }
258
258
  else {
259
- reject(new Error(`修改闹钟失败: ${event.status}`));
259
+ reject(new Error(`修改闹钟失败: ${JSON.stringify(event.outputs)}`));
260
260
  }
261
261
  }
262
262
  };
@@ -97,7 +97,7 @@ export function createModifyNoteTool(ctx) {
97
97
  });
98
98
  }
99
99
  else {
100
- reject(new Error(`修改备忘录失败: ${event.status}`));
100
+ reject(new Error(`修改备忘录失败: ${JSON.stringify(event.outputs)}`));
101
101
  }
102
102
  }
103
103
  };
@@ -114,7 +114,7 @@ export function createNoteTool(ctx) {
114
114
  });
115
115
  }
116
116
  else {
117
- reject(new Error(`创建备忘录失败: ${event.status}`));
117
+ reject(new Error(`创建备忘录失败: ${JSON.stringify(event.outputs)}`));
118
118
  }
119
119
  }
120
120
  };
@@ -114,7 +114,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
114
114
  });
115
115
  }
116
116
  else {
117
- reject(new Error(`查询通知消息失败: ${event.status}`));
117
+ reject(new Error(`查询通知消息失败: ${JSON.stringify(event.outputs)}`));
118
118
  }
119
119
  }
120
120
  };
@@ -130,7 +130,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
130
130
  });
131
131
  }
132
132
  else {
133
- reject(new Error(`查询记忆数据失败: ${event.status}`));
133
+ reject(new Error(`查询记忆数据失败: ${JSON.stringify(event.outputs)}`));
134
134
  }
135
135
  }
136
136
  };
@@ -109,7 +109,7 @@ d. 当只传入 startTime 时,返回该时间点之后的所有任务;当只
109
109
  });
110
110
  }
111
111
  else {
112
- reject(new Error(`查询待办任务失败: ${event.status}`));
112
+ reject(new Error(`查询待办任务失败: ${JSON.stringify(event.outputs)}`));
113
113
  }
114
114
  }
115
115
  };
@@ -138,7 +138,7 @@ export function createSaveFileToPhoneTool(ctx) {
138
138
  });
139
139
  }
140
140
  else {
141
- reject(new Error(`保存文件到手机失败: ${event.status}`));
141
+ reject(new Error(`保存文件到手机失败: ${JSON.stringify(event.outputs)}`));
142
142
  }
143
143
  }
144
144
  };
@@ -146,7 +146,7 @@ export function createSaveMediaToGalleryTool(ctx) {
146
146
  });
147
147
  }
148
148
  else {
149
- reject(new Error(`保存媒体到图库失败: ${event.status}`));
149
+ reject(new Error(`保存媒体到图库失败: ${JSON.stringify(event.outputs)}`));
150
150
  }
151
151
  }
152
152
  };
@@ -188,7 +188,7 @@ b. 使用该工具之前需获取当前真实时间
188
188
  });
189
189
  }
190
190
  else {
191
- reject(new Error(`检索闹钟失败: ${event.status}`));
191
+ reject(new Error(`检索闹钟失败: ${JSON.stringify(event.outputs)}`));
192
192
  }
193
193
  }
194
194
  };
@@ -159,7 +159,7 @@ d. 如果查询结果返回-303,代表查询结果为空
159
159
  });
160
160
  }
161
161
  else {
162
- reject(new Error(`检索日程失败: ${event.status}`));
162
+ reject(new Error(`检索日程失败: ${JSON.stringify(event.outputs)}`));
163
163
  }
164
164
  }
165
165
  };
@@ -87,7 +87,7 @@ export function createSearchContactTool(ctx) {
87
87
  });
88
88
  }
89
89
  else {
90
- reject(new Error(`搜索联系人失败: ${event.status}`));
90
+ reject(new Error(`搜索联系人失败: ${JSON.stringify(event.outputs)}`));
91
91
  }
92
92
  }
93
93
  };
@@ -110,7 +110,7 @@ b. 使用该工具之前需获取当前真实时间
110
110
  });
111
111
  }
112
112
  else {
113
- reject(new Error(`检索邮件失败: ${event.status}`));
113
+ reject(new Error(`检索邮件失败: ${JSON.stringify(event.outputs)}`));
114
114
  }
115
115
  }
116
116
  };
@@ -86,7 +86,7 @@ export function createSearchNoteTool(ctx) {
86
86
  });
87
87
  }
88
88
  else {
89
- reject(new Error(`搜索备忘录失败: ${event.status}`));
89
+ reject(new Error(`搜索备忘录失败: ${JSON.stringify(event.outputs)}`));
90
90
  }
91
91
  }
92
92
  };
@@ -140,7 +140,7 @@ async function searchPhotos(wsManager, config, sessionId, taskId, messageId, too
140
140
  resolve(event.outputs);
141
141
  }
142
142
  else {
143
- reject(new Error(`搜索照片失败: ${event.status}`));
143
+ reject(new Error(`搜索照片失败: ${JSON.stringify(event.outputs)}`));
144
144
  }
145
145
  }
146
146
  };
@@ -110,7 +110,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
110
110
  });
111
111
  }
112
112
  else {
113
- reject(new Error(`发送邮件失败: ${event.status}`));
113
+ reject(new Error(`发送邮件失败: ${JSON.stringify(event.outputs)}`));
114
114
  }
115
115
  }
116
116
  };
@@ -77,4 +77,5 @@ export declare function cleanupStaleSessions(): number;
77
77
  */
78
78
  export declare function getActiveSessionCount(): number;
79
79
  export declare function appendRunCrossTaskSentFiles(sentFiles: SentFileParams[], explicitRunCrossTaskContext?: RunCrossTaskContext): SentFileParams[];
80
+ export declare function clearRunCrossTaskSentFiles(explicitRunCrossTaskContext?: RunCrossTaskContext): void;
80
81
  export {};
@@ -274,6 +274,19 @@ export function appendRunCrossTaskSentFiles(sentFiles, explicitRunCrossTaskConte
274
274
  }
275
275
  return merged;
276
276
  }
277
+ export function clearRunCrossTaskSentFiles(explicitRunCrossTaskContext) {
278
+ const context = asyncLocalStorage.getStore() ?? null;
279
+ const runCrossTaskContext = explicitRunCrossTaskContext ?? context?.runCrossTaskContext;
280
+ if (!runCrossTaskContext) {
281
+ return;
282
+ }
283
+ runCrossTaskContext.sentFiles = [];
284
+ for (const sessionWithRef of activeSessions.values()) {
285
+ if (sessionWithRef.runCrossTaskContext === runCrossTaskContext) {
286
+ sessionWithRef.runCrossTaskContext.sentFiles = [];
287
+ }
288
+ }
289
+ }
277
290
  /**
278
291
  * Enrich a base session context with the latest taskId/messageId
279
292
  * from task-manager (supports interruption scenarios).
@@ -194,7 +194,7 @@ async function getFileUrls(wsManager, config, sessionId, taskId, messageId, tool
194
194
  resolve(fileUrls);
195
195
  }
196
196
  else {
197
- reject(new Error(`获取文件URL失败: ${event.status}`));
197
+ reject(new Error(`获取文件URL失败: ${JSON.stringify(event.outputs)}`));
198
198
  }
199
199
  }
200
200
  };
@@ -158,7 +158,7 @@ async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, too
158
158
  resolve(imageUrls);
159
159
  }
160
160
  else {
161
- reject(new Error(`获取照片URL失败: ${event.status}`));
161
+ reject(new Error(`获取照片URL失败: ${JSON.stringify(event.outputs)}`));
162
162
  }
163
163
  }
164
164
  };
@@ -165,7 +165,7 @@ export function createXiaoyiAddCollectionTool(ctx) {
165
165
  });
166
166
  }
167
167
  else {
168
- reject(new Error(`添加小艺收藏失败: ${event.status}`));
168
+ reject(new Error(`添加小艺收藏失败: ${JSON.stringify(event.outputs)}`));
169
169
  }
170
170
  }
171
171
  };
@@ -120,7 +120,7 @@ export function createXiaoyiCollectionTool(ctx) {
120
120
  });
121
121
  }
122
122
  else {
123
- reject(new Error(`查询小艺收藏失败: ${event.status}`));
123
+ reject(new Error(`查询小艺收藏失败: ${JSON.stringify(event.outputs)}`));
124
124
  }
125
125
  }
126
126
  };
@@ -135,7 +135,7 @@ export function createXiaoyiDeleteCollectionTool(ctx) {
135
135
  });
136
136
  }
137
137
  else {
138
- reject(new Error(`删除小艺收藏失败: ${event.status}`));
138
+ reject(new Error(`删除小艺收藏失败: ${JSON.stringify(event.outputs)}`));
139
139
  }
140
140
  }
141
141
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.163-beta",
3
+ "version": "0.0.165-beta",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",