@ai-setting/roy-agent-core 1.5.91 → 1.5.93

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 (32) hide show
  1. package/dist/env/agent/index.js +4 -3
  2. package/dist/env/event-source/index.js +3 -3
  3. package/dist/env/index.js +12 -11
  4. package/dist/env/prompt/index.js +2 -2
  5. package/dist/env/task/delegate/index.js +2 -2
  6. package/dist/env/task/index.js +3 -3
  7. package/dist/env/task/plugins/index.js +2 -2
  8. package/dist/env/tool/built-in/index.js +11 -1
  9. package/dist/env/tool/index.js +14 -3
  10. package/dist/env/workflow/engine/index.js +2 -2
  11. package/dist/env/workflow/index.js +3 -3
  12. package/dist/index.js +29 -111
  13. package/dist/shared/@ai-setting/{roy-agent-core-spzb03na.js → roy-agent-core-09xaxtpf.js} +5 -2
  14. package/dist/shared/@ai-setting/{roy-agent-core-55br4t6v.js → roy-agent-core-27d4js2f.js} +34 -7
  15. package/dist/shared/@ai-setting/{roy-agent-core-9amq4epa.js → roy-agent-core-2pz9075g.js} +2 -2
  16. package/dist/shared/@ai-setting/{roy-agent-core-w1s8yrm5.js → roy-agent-core-2vnw9wbx.js} +59 -18
  17. package/dist/shared/@ai-setting/roy-agent-core-5h49ct1a.js +135 -0
  18. package/dist/shared/@ai-setting/{roy-agent-core-5j649pb1.js → roy-agent-core-8f37pvct.js} +1 -1
  19. package/dist/shared/@ai-setting/{roy-agent-core-snvsn60t.js → roy-agent-core-9z1mem2n.js} +44 -6
  20. package/dist/shared/@ai-setting/roy-agent-core-cy8azvpb.js +13 -0
  21. package/dist/shared/@ai-setting/{roy-agent-core-97tjdb2r.js → roy-agent-core-dj18eyyk.js} +29 -3
  22. package/dist/shared/@ai-setting/{roy-agent-core-q7ffkt1e.js → roy-agent-core-eqcbn89s.js} +1 -1
  23. package/dist/shared/@ai-setting/{roy-agent-core-vady4w02.js → roy-agent-core-hfgqwf5w.js} +1 -1
  24. package/dist/shared/@ai-setting/{roy-agent-core-jf865m5b.js → roy-agent-core-jhdv14ks.js} +11 -139
  25. package/dist/shared/@ai-setting/{roy-agent-core-7svhckhz.js → roy-agent-core-mwb6918x.js} +1 -1
  26. package/dist/shared/@ai-setting/{roy-agent-core-svcr4gjw.js → roy-agent-core-mx9vq7b2.js} +1 -1
  27. package/dist/shared/@ai-setting/{roy-agent-core-at05dk0z.js → roy-agent-core-ss92p0r6.js} +1 -1
  28. package/dist/shared/@ai-setting/roy-agent-core-t7rw68q8.js +185 -0
  29. package/dist/shared/@ai-setting/{roy-agent-core-b1vkkcbr.js → roy-agent-core-x65fyjaw.js} +1 -1
  30. package/dist/utils/temp-file-manager/index.js +10 -0
  31. package/package.json +1 -1
  32. /package/dist/shared/@ai-setting/{roy-agent-core-pt7as39r.js → roy-agent-core-wjmwwc4a.js} +0 -0
@@ -25,6 +25,28 @@ import {
25
25
  } from "./roy-agent-core-fs0mn2jk.js";
26
26
 
27
27
  // src/env/workflow/plugins/workflow-json-output-plugin.ts
28
+ function extractLastAssistantText(messages) {
29
+ if (!messages || messages.length === 0) {
30
+ return;
31
+ }
32
+ for (let i = messages.length - 1;i >= 0; i--) {
33
+ const msg = messages[i];
34
+ if (msg.role !== "assistant") {
35
+ continue;
36
+ }
37
+ const content = msg.content;
38
+ if (typeof content === "string") {
39
+ return content.trim() || undefined;
40
+ }
41
+ if (Array.isArray(content)) {
42
+ const textParts = content.filter((p) => typeof p === "object" && p !== null && p.type === "text").map((p) => p.text);
43
+ const combined = textParts.join(`
44
+ `).trim();
45
+ return combined || undefined;
46
+ }
47
+ }
48
+ return;
49
+ }
28
50
  function registerWorkflowJsonOutputPlugin(options = undefined) {
29
51
  if (registered) {
30
52
  return;
@@ -61,34 +83,53 @@ async function runWorkflowJsonOutputExtraction(hookCtx) {
61
83
  logger.warn("Workflow JSON extraction: agentComponent not registered. " + "Plugin cannot invoke json-extract sub-agent. " + "Ensure registerWorkflowJsonOutputPlugin({ agentComponent }) was called.");
62
84
  return;
63
85
  }
64
- const sessionId = hookCtx.context.sessionId;
65
- if (!sessionId) {
66
- logger.warn("Workflow JSON extraction: no sessionId in hookCtx.context. " + "Cannot reuse main session history for json-extract sub-agent.");
86
+ const assistantText = extractLastAssistantText(hookCtx.messages);
87
+ if (!assistantText) {
88
+ logger.warn("Workflow JSON extraction: no assistant text found in main agent output. " + "The agent must produce a final text response (plain or markdown).");
67
89
  return;
68
90
  }
91
+ const submitTool = createSubmitJsonOutputTool(schema, hookCtx);
92
+ const submitToolAsExtra = {
93
+ name: submitTool.name,
94
+ description: submitTool.description ?? "",
95
+ parameters: submitTool.parameters,
96
+ execute: submitTool.execute
97
+ };
98
+ const userQuery = [
99
+ "The main agent has produced the following final response.",
100
+ "Extract the structured JSON from it and submit via workflow_submit_output.",
101
+ "",
102
+ "--- START of main agent response ---",
103
+ assistantText,
104
+ "--- END of main agent response ---",
105
+ "",
106
+ "Your ONLY job: call workflow_submit_output with the extracted JSON.",
107
+ "Do NOT output any text — just call the tool."
108
+ ].join(`
109
+ `);
110
+ const messagesOverride = [
111
+ {
112
+ role: "user",
113
+ content: userQuery
114
+ }
115
+ ];
116
+ const extractContext = {
117
+ messages: messagesOverride,
118
+ extraTools: [submitToolAsExtra],
119
+ persistSession: false,
120
+ abort: hookCtx.context.abort,
121
+ toolChoice: "required"
122
+ };
69
123
  try {
70
- const submitTool = createSubmitJsonOutputTool(schema, hookCtx);
71
- const submitToolAsExtra = {
72
- name: submitTool.name,
73
- description: submitTool.description ?? "",
74
- parameters: submitTool.parameters,
75
- execute: submitTool.execute
76
- };
77
- const extractContext = {
78
- sessionId,
79
- extraTools: [submitToolAsExtra],
80
- persistSession: false,
81
- abort: hookCtx.context.abort
82
- };
83
124
  const result = await agentComponentRef.run("json-extract", "", extractContext);
84
125
  if (result.error) {
85
126
  logger.warn(`Workflow JSON extraction: json-extract sub-agent returned error: ${result.error}`);
86
127
  return;
87
128
  }
88
129
  if (hookCtx.structuredOutputExtracted) {
89
- logger.info("Workflow JSON output extracted via json-extract sub-agent " + `(iterations=${result.iterations}, toolCalls=${result.toolCalls?.length ?? 0})`);
130
+ logger.info("Workflow JSON output extracted via json-extract sub-agent (clean override) " + `(iterations=${result.iterations}, toolCalls=${result.toolCalls?.length ?? 0})`);
90
131
  } else {
91
- logger.warn("Workflow JSON extraction: json-extract sub-agent did not call workflow_submit_output. " + "Check that the model supports tool calls.");
132
+ logger.warn("Workflow JSON extraction: json-extract sub-agent did not call workflow_submit_output. " + "toolChoice=required failed to force tool call — investigate provider support.");
92
133
  }
93
134
  } catch (error) {
94
135
  logger.error(`Workflow JSON extraction: json-extract sub-agent threw: ${error instanceof Error ? error.message : String(error)}`);
@@ -0,0 +1,135 @@
1
+ import {
2
+ createLogger,
3
+ init_logger
4
+ } from "./roy-agent-core-vyygk314.js";
5
+
6
+ // src/utils/temp-file-manager/index.ts
7
+ init_logger();
8
+ import * as fs from "node:fs";
9
+ import * as path from "node:path";
10
+ import * as os from "node:os";
11
+ import * as crypto from "node:crypto";
12
+ var logger = createLogger("temp-file-manager");
13
+
14
+ class TempFileManager {
15
+ static _instance = null;
16
+ _files = new Set;
17
+ _hooksRegistered = false;
18
+ static FILE_PREFIX = "roy-agent-truncation";
19
+ static FILE_EXT = ".txt";
20
+ static LARGE_FILE_THRESHOLD = 10 * 1024 * 1024;
21
+ static STALE_FILE_AGE_MS = 24 * 60 * 60 * 1000;
22
+ constructor() {
23
+ this.sweepStaleFiles().catch((err) => {
24
+ logger.warn(`[TempFileManager] Stale file sweep failed: ${err}`);
25
+ });
26
+ }
27
+ static getInstance() {
28
+ if (!TempFileManager._instance) {
29
+ TempFileManager._instance = new TempFileManager;
30
+ }
31
+ return TempFileManager._instance;
32
+ }
33
+ static _resetForTesting() {
34
+ if (TempFileManager._instance) {
35
+ TempFileManager._instance.cleanupAll().catch(() => {});
36
+ }
37
+ TempFileManager._instance = null;
38
+ }
39
+ async writeTempFile(content, prefix = "default") {
40
+ this.ensureHooksRegistered();
41
+ if (content.length > TempFileManager.LARGE_FILE_THRESHOLD) {
42
+ logger.warn(`[TempFileManager] Writing large temp file: ${content.length} bytes (> ${TempFileManager.LARGE_FILE_THRESHOLD} bytes). Consider increasing maxOutputSize or filtering output.`);
43
+ }
44
+ const sanitizedPrefix = this.sanitizePrefix(prefix);
45
+ const uuid = crypto.randomUUID();
46
+ const filename = `${TempFileManager.FILE_PREFIX}-${process.pid}-${uuid}-${sanitizedPrefix}${TempFileManager.FILE_EXT}`;
47
+ const filePath = path.join(os.tmpdir(), filename);
48
+ await fs.promises.writeFile(filePath, content, "utf-8");
49
+ this._files.add(filePath);
50
+ logger.debug(`[TempFileManager] Created temp file: ${filePath} (${content.length} bytes)`);
51
+ return filePath;
52
+ }
53
+ async cleanupAll() {
54
+ const files = Array.from(this._files);
55
+ this._files.clear();
56
+ const results = await Promise.allSettled(files.map(async (filePath) => {
57
+ try {
58
+ await fs.promises.unlink(filePath);
59
+ } catch (err) {
60
+ if (err.code !== "ENOENT") {
61
+ logger.warn(`[TempFileManager] Failed to delete ${filePath}: ${err.message}`);
62
+ }
63
+ }
64
+ }));
65
+ const succeeded = results.filter((r) => r.status === "fulfilled").length;
66
+ logger.debug(`[TempFileManager] Cleanup complete: ${succeeded}/${files.length} files deleted`);
67
+ }
68
+ getActiveFileCount() {
69
+ return this._files.size;
70
+ }
71
+ async sweepStaleFiles(maxAgeMs = TempFileManager.STALE_FILE_AGE_MS) {
72
+ const tmpDir = os.tmpdir();
73
+ const now = Date.now();
74
+ let deletedCount = 0;
75
+ let entries;
76
+ try {
77
+ entries = await fs.promises.readdir(tmpDir);
78
+ } catch (err) {
79
+ logger.warn(`[TempFileManager] Failed to read tmpdir ${tmpDir}: ${err.message}`);
80
+ return 0;
81
+ }
82
+ for (const entry of entries) {
83
+ if (!entry.startsWith(`${TempFileManager.FILE_PREFIX}-`))
84
+ continue;
85
+ const filePath = path.join(tmpDir, entry);
86
+ try {
87
+ const stat = await fs.promises.stat(filePath);
88
+ const age = now - stat.mtimeMs;
89
+ if (age > maxAgeMs) {
90
+ await fs.promises.unlink(filePath);
91
+ deletedCount++;
92
+ }
93
+ } catch (err) {
94
+ if (err.code !== "ENOENT") {
95
+ logger.warn(`[TempFileManager] Failed to sweep ${filePath}: ${err.message}`);
96
+ }
97
+ }
98
+ }
99
+ if (deletedCount > 0) {
100
+ logger.info(`[TempFileManager] Swept ${deletedCount} stale files from ${tmpDir}`);
101
+ }
102
+ return deletedCount;
103
+ }
104
+ ensureHooksRegistered() {
105
+ if (this._hooksRegistered)
106
+ return;
107
+ if (typeof process === "undefined" || !process.on) {
108
+ return;
109
+ }
110
+ const cleanup = () => {
111
+ for (const filePath of this._files) {
112
+ try {
113
+ fs.unlinkSync(filePath);
114
+ } catch (err) {}
115
+ }
116
+ this._files.clear();
117
+ };
118
+ process.on("exit", cleanup);
119
+ process.on("SIGINT", () => {
120
+ cleanup();
121
+ process.exit(130);
122
+ });
123
+ process.on("SIGTERM", () => {
124
+ cleanup();
125
+ process.exit(143);
126
+ });
127
+ this._hooksRegistered = true;
128
+ logger.debug("[TempFileManager] Process exit hooks registered");
129
+ }
130
+ sanitizePrefix(prefix) {
131
+ return prefix.replace(/[\/\\<>:"|?*\x00-\x1f]/g, "-").replace(/\s+/g, "-").substring(0, 32) || "default";
132
+ }
133
+ }
134
+
135
+ export { TempFileManager };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TaskTagPlugin,
3
3
  createLarkCliTaskNotifyHook
4
- } from "./roy-agent-core-svcr4gjw.js";
4
+ } from "./roy-agent-core-mx9vq7b2.js";
5
5
  import {
6
6
  envKeyToConfigKey
7
7
  } from "./roy-agent-core-qxhq8ven.js";
@@ -1,13 +1,13 @@
1
- import {
2
- AgentComponentAdapter,
3
- init_agent_component_adapter
4
- } from "./roy-agent-core-w1s8yrm5.js";
5
1
  import {
6
2
  buildWorkflowNodeMetadata,
7
3
  getWorkflowNodeIdFromMetadata,
8
4
  init_workflow_message_metadata,
9
5
  patchAgentSessionIdOnMessage
10
6
  } from "./roy-agent-core-6atd905e.js";
7
+ import {
8
+ AgentComponentAdapter,
9
+ init_agent_component_adapter
10
+ } from "./roy-agent-core-2vnw9wbx.js";
11
11
  import {
12
12
  TemplateResolver,
13
13
  init_template_resolver
@@ -892,6 +892,32 @@ var init_extract_agent_json_output = __esm(() => {
892
892
  });
893
893
 
894
894
  // src/env/workflow/utils/build-agent-node-output.ts
895
+ function extractSchemaFieldNames(schema) {
896
+ if (!schema)
897
+ return [];
898
+ const props = schema.properties;
899
+ if (!props || typeof props !== "object")
900
+ return [];
901
+ return Object.keys(props);
902
+ }
903
+ function defaultValueForField(fieldName) {
904
+ const lower = fieldName.toLowerCase();
905
+ if (lower === "score" || lower.endsWith("_score"))
906
+ return 0;
907
+ if (lower === "findings" || lower.endsWith("_list") || lower.endsWith("s"))
908
+ return [];
909
+ if (lower.includes("count") || lower.includes("total"))
910
+ return 0;
911
+ if (lower === "dimension")
912
+ return "unknown";
913
+ if (lower === "verdict")
914
+ return "unknown";
915
+ if (lower.includes("summary") || lower.includes("description") || lower.includes("report"))
916
+ return "";
917
+ if (lower.includes("markdown"))
918
+ return "";
919
+ return "";
920
+ }
895
921
  function buildAgentNodeOutput(agentResult, outputConfig) {
896
922
  if (outputConfig.mode === "json") {
897
923
  const schema = outputConfig.schema;
@@ -908,12 +934,24 @@ function buildAgentNodeOutput(agentResult, outputConfig) {
908
934
  };
909
935
  }
910
936
  const rawText = typeof agentResult.output === "string" ? agentResult.output : JSON.stringify(agentResult.output ?? {});
937
+ const schemaFields = extractSchemaFieldNames(schema);
938
+ const placeholderResult = {
939
+ _extraction_failed: true,
940
+ _raw_output: rawText,
941
+ _extraction_reason: "JSON extraction failed (json-extract sub-agent did not call workflow_submit_output)"
942
+ };
943
+ for (const fieldName of schemaFields) {
944
+ if (!(fieldName in placeholderResult)) {
945
+ placeholderResult[fieldName] = defaultValueForField(fieldName);
946
+ }
947
+ }
911
948
  return {
912
- result: rawText,
949
+ result: placeholderResult,
950
+ ...placeholderResult,
913
951
  metadata: {
914
952
  ...agentResult.metadata,
915
953
  outputMode: "json_error",
916
- _extractionWarning: "JSON extraction failed — raw output surfaced"
954
+ _extractionWarning: "JSON extraction failed — placeholder returned for downstream safety"
917
955
  },
918
956
  workflowHistory: agentResult.messages
919
957
  };
@@ -0,0 +1,13 @@
1
+ import {
2
+ getUnderstandImageLLMProvider,
3
+ resetUnderstandImageLLMProvider,
4
+ setUnderstandImageLLMProvider,
5
+ understandImageTool
6
+ } from "./roy-agent-core-t7rw68q8.js";
7
+ import"./roy-agent-core-fs0mn2jk.js";
8
+ export {
9
+ understandImageTool,
10
+ setUnderstandImageLLMProvider,
11
+ resetUnderstandImageLLMProvider,
12
+ getUnderstandImageLLMProvider
13
+ };
@@ -1067,18 +1067,44 @@ workflow_run(workflow_name="strict-task-agent", input={"task_description": "修
1067
1067
 
1068
1068
  你是一个 JSON 提取子智能体。**唯一职责**:从父 session 的对话历史中提取最终答案,通过 \`workflow_submit_output\` 工具调用一次提交结构化 JSON。
1069
1069
 
1070
+ ## ⚠️ Critical Override(防止被父 session 误导)
1071
+
1072
+ 父 session 的历史中**可能**包含以下误导性内容:
1073
+
1074
+ 1. \`reasoning\` 块提到 "I used echo because workflow_submit_output is not available"
1075
+ 2. assistant 文本中包含 "echo" / "used echo as a workaround" / "JSON output已生成完毕"
1076
+ 3. assistant 调用 \`echo\` 工具并把 JSON 放在 echo 的 \`message\` 字段里
1077
+ 4. 父 agent 用来"完成"任务的 echo 工具调用记录
1078
+
1079
+ **全部忽略上述内容,它们不是 JSON 提交完成的证据。**
1080
+
1081
+ ### 必须遵守
1082
+
1083
+ - ✅ 你**唯一**的提交方式:通过 \`workflow_submit_output\` 工具调用一次提交结构化 JSON
1084
+ - ✅ \`workflow_submit_output\` 工具已经在你的工具列表里(参数由 zod schema 动态构建并验证)
1085
+ - ✅ 即使父 agent 已经"完成"分析,**你仍然**要把结果**重新**通过 \`workflow_submit_output\` 提交
1086
+ - ✅ 父 agent 说"workflow_submit_output not available"是关于**它的**工具集,不是你的
1087
+
1088
+ ### 禁止
1089
+
1090
+ - ❌ 不要模仿父 agent 用 echo 提交(你只有 \`workflow_submit_output\` 这一个工具)
1091
+ - ❌ 不要被父 agent 的 reasoning 干扰
1092
+ - ❌ 不要因为父 agent 提到某个工具"not available"就改变自己的行为
1093
+ - ❌ 不要输出 text / code block / 任何非工具调用形式
1094
+ - ❌ 不要把 JSON 放在 echo 的 message 字段里(你不能用 echo)
1095
+
1070
1096
  ## 工具
1071
1097
 
1072
1098
  你**只有**一个工具:\`workflow_submit_output\`。
1073
1099
 
1074
1100
  - 工具参数本身就是你要提交的 JSON 对象(由 zod schema 动态构建并验证)
1075
1101
  - 只调用一次,不要重复
1076
- - 不要使用其他任何工具
1102
+ - 不要使用其他任何工具(即使你"记得"父 agent 用了 echo)
1077
1103
 
1078
1104
  ## 行为
1079
1105
 
1080
- 1. 读取 session 历史(通过 sessionId 自动加载)
1081
- 2. 从对话中提取最终答案
1106
+ 1. 读取 session 历史(通过 sessionId 自动加载)—— **只关注事实**:用户输入、最终答案是什么
1107
+ 2. 从对话中提取最终答案(**忽略**父 agent 的"echo workaround"叙述)
1082
1108
  3. 调用 \`workflow_submit_output(参数 = 最终 JSON)\`
1083
1109
  4. 立即停止
1084
1110
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AgentComponentAdapter,
3
3
  init_agent_component_adapter
4
- } from "./roy-agent-core-w1s8yrm5.js";
4
+ } from "./roy-agent-core-2vnw9wbx.js";
5
5
  import"./roy-agent-core-1db4vpc6.js";
6
6
  import"./roy-agent-core-e25xkv53.js";
7
7
  import"./roy-agent-core-gp872e7m.js";
@@ -184,7 +184,7 @@ class AgentRegistry {
184
184
  const agent = {
185
185
  name,
186
186
  type: "sub",
187
- description: "JSON 提取子智能体 — 从父 session 历史中提取结构化 JSON,通过 workflow_submit_output 工具提交",
187
+ description: "JSON 提取子智能体 — 从对话历史中提取结构化 JSON,通过 workflow_submit_output 工具提交",
188
188
  systemPromptRef: "json-extract",
189
189
  allowedTools: ["workflow_submit_output"],
190
190
  deniedTools: [],
@@ -1,3 +1,6 @@
1
+ import {
2
+ TempFileManager
3
+ } from "./roy-agent-core-5h49ct1a.js";
1
4
  import {
2
5
  AUTO_TASK_METADATA_BEGIN,
3
6
  AUTO_TASK_METADATA_END
@@ -181,138 +184,7 @@ var TOOL_CONFIG_REGISTRATION = {
181
184
  // src/env/tool/tool-component.ts
182
185
  init_workflow_hil();
183
186
  init_env_context();
184
-
185
- // src/utils/temp-file-manager.ts
186
- init_logger();
187
- import * as fs from "node:fs";
188
- import * as path from "node:path";
189
- import * as os from "node:os";
190
- import * as crypto from "node:crypto";
191
- var logger = createLogger("temp-file-manager");
192
-
193
- class TempFileManager {
194
- static _instance = null;
195
- _files = new Set;
196
- _hooksRegistered = false;
197
- static FILE_PREFIX = "roy-agent-truncation";
198
- static FILE_EXT = ".txt";
199
- static LARGE_FILE_THRESHOLD = 10 * 1024 * 1024;
200
- static STALE_FILE_AGE_MS = 24 * 60 * 60 * 1000;
201
- constructor() {
202
- this.sweepStaleFiles().catch((err) => {
203
- logger.warn(`[TempFileManager] Stale file sweep failed: ${err}`);
204
- });
205
- }
206
- static getInstance() {
207
- if (!TempFileManager._instance) {
208
- TempFileManager._instance = new TempFileManager;
209
- }
210
- return TempFileManager._instance;
211
- }
212
- static _resetForTesting() {
213
- if (TempFileManager._instance) {
214
- TempFileManager._instance.cleanupAll().catch(() => {});
215
- }
216
- TempFileManager._instance = null;
217
- }
218
- async writeTempFile(content, prefix = "default") {
219
- this.ensureHooksRegistered();
220
- if (content.length > TempFileManager.LARGE_FILE_THRESHOLD) {
221
- logger.warn(`[TempFileManager] Writing large temp file: ${content.length} bytes (> ${TempFileManager.LARGE_FILE_THRESHOLD} bytes). Consider increasing maxOutputSize or filtering output.`);
222
- }
223
- const sanitizedPrefix = this.sanitizePrefix(prefix);
224
- const uuid = crypto.randomUUID();
225
- const filename = `${TempFileManager.FILE_PREFIX}-${process.pid}-${uuid}-${sanitizedPrefix}${TempFileManager.FILE_EXT}`;
226
- const filePath = path.join(os.tmpdir(), filename);
227
- await fs.promises.writeFile(filePath, content, "utf-8");
228
- this._files.add(filePath);
229
- logger.debug(`[TempFileManager] Created temp file: ${filePath} (${content.length} bytes)`);
230
- return filePath;
231
- }
232
- async cleanupAll() {
233
- const files = Array.from(this._files);
234
- this._files.clear();
235
- const results = await Promise.allSettled(files.map(async (filePath) => {
236
- try {
237
- await fs.promises.unlink(filePath);
238
- } catch (err) {
239
- if (err.code !== "ENOENT") {
240
- logger.warn(`[TempFileManager] Failed to delete ${filePath}: ${err.message}`);
241
- }
242
- }
243
- }));
244
- const succeeded = results.filter((r) => r.status === "fulfilled").length;
245
- logger.debug(`[TempFileManager] Cleanup complete: ${succeeded}/${files.length} files deleted`);
246
- }
247
- getActiveFileCount() {
248
- return this._files.size;
249
- }
250
- async sweepStaleFiles(maxAgeMs = TempFileManager.STALE_FILE_AGE_MS) {
251
- const tmpDir = os.tmpdir();
252
- const now = Date.now();
253
- let deletedCount = 0;
254
- let entries;
255
- try {
256
- entries = await fs.promises.readdir(tmpDir);
257
- } catch (err) {
258
- logger.warn(`[TempFileManager] Failed to read tmpdir ${tmpDir}: ${err.message}`);
259
- return 0;
260
- }
261
- for (const entry of entries) {
262
- if (!entry.startsWith(`${TempFileManager.FILE_PREFIX}-`))
263
- continue;
264
- const filePath = path.join(tmpDir, entry);
265
- try {
266
- const stat = await fs.promises.stat(filePath);
267
- const age = now - stat.mtimeMs;
268
- if (age > maxAgeMs) {
269
- await fs.promises.unlink(filePath);
270
- deletedCount++;
271
- }
272
- } catch (err) {
273
- if (err.code !== "ENOENT") {
274
- logger.warn(`[TempFileManager] Failed to sweep ${filePath}: ${err.message}`);
275
- }
276
- }
277
- }
278
- if (deletedCount > 0) {
279
- logger.info(`[TempFileManager] Swept ${deletedCount} stale files from ${tmpDir}`);
280
- }
281
- return deletedCount;
282
- }
283
- ensureHooksRegistered() {
284
- if (this._hooksRegistered)
285
- return;
286
- if (typeof process === "undefined" || !process.on) {
287
- return;
288
- }
289
- const cleanup = () => {
290
- for (const filePath of this._files) {
291
- try {
292
- fs.unlinkSync(filePath);
293
- } catch (err) {}
294
- }
295
- this._files.clear();
296
- };
297
- process.on("exit", cleanup);
298
- process.on("SIGINT", () => {
299
- cleanup();
300
- process.exit(130);
301
- });
302
- process.on("SIGTERM", () => {
303
- cleanup();
304
- process.exit(143);
305
- });
306
- this._hooksRegistered = true;
307
- logger.debug("[TempFileManager] Process exit hooks registered");
308
- }
309
- sanitizePrefix(prefix) {
310
- return prefix.replace(/[\/\\<>:"|?*\x00-\x1f]/g, "-").replace(/\s+/g, "-").substring(0, 32) || "default";
311
- }
312
- }
313
-
314
- // src/env/tool/tool-component.ts
315
- var logger2 = createLogger("tool");
187
+ var logger = createLogger("tool");
316
188
  var configComponentInstance = null;
317
189
  function setToolConfigComponent(component) {
318
190
  configComponentInstance = component;
@@ -438,7 +310,7 @@ class ToolComponent extends BaseComponent {
438
310
  if (this.config?.builtInTools?.enabled !== false) {
439
311
  await this.loadBuiltInTools();
440
312
  }
441
- logger2.info(`ToolComponent initialized with ${this.getToolCount()} tools`);
313
+ logger.info(`ToolComponent initialized with ${this.getToolCount()} tools`);
442
314
  }
443
315
  async registerConfig(options) {
444
316
  const configComponent = options.configComponent;
@@ -536,7 +408,7 @@ class ToolComponent extends BaseComponent {
536
408
  });
537
409
  }
538
410
  onConfigChange(event) {
539
- logger2.info(`Tool config changed: ${event.key}`, {
411
+ logger.info(`Tool config changed: ${event.key}`, {
540
412
  oldValue: event.oldValue,
541
413
  newValue: event.newValue
542
414
  });
@@ -554,7 +426,7 @@ class ToolComponent extends BaseComponent {
554
426
  source,
555
427
  enabled: true
556
428
  });
557
- logger2.debug(`Registered tool: ${tool.name}`);
429
+ logger.debug(`Registered tool: ${tool.name}`);
558
430
  globalHookManager.execute(ToolHookPoints.AFTER_REGISTER, { tool });
559
431
  }
560
432
  registerMany(tools, source = "dynamic") {
@@ -643,9 +515,9 @@ class ToolComponent extends BaseComponent {
643
515
  ⚠️ 输出被截断(原 ${truncationMeta.original_output_size} 字符,截断到 ${truncationMeta.truncated_output_size} 字符)
644
516
  \uD83D\uDCC1 完整内容保存到: ${tempFilePath}
645
517
  \uD83D\uDD0D 使用 read_file 工具按需读取`;
646
- logger2.debug(`[tool-component] Truncated output saved to temp file: ${tempFilePath} (${truncationMeta.original_output_size} bytes)`);
518
+ logger.debug(`[tool-component] Truncated output saved to temp file: ${tempFilePath} (${truncationMeta.original_output_size} bytes)`);
647
519
  } catch (err) {
648
- logger2.warn(`[tool-component] Failed to write temp file for truncated output: ${err}`);
520
+ logger.warn(`[tool-component] Failed to write temp file for truncated output: ${err}`);
649
521
  }
650
522
  }
651
523
  }
@@ -690,9 +562,9 @@ class ToolComponent extends BaseComponent {
690
562
  const { getAllBuiltInTools } = await import("../../env/tool/built-in/index.js");
691
563
  const tools = getAllBuiltInTools();
692
564
  this.registerMany(tools, "built-in");
693
- logger2.info(`Loaded ${tools.length} built-in tools`);
565
+ logger.info(`Loaded ${tools.length} built-in tools`);
694
566
  } catch (err) {
695
- logger2.warn(`Failed to load built-in tools: ${err.message}`);
567
+ logger.warn(`Failed to load built-in tools: ${err.message}`);
696
568
  }
697
569
  }
698
570
  getHookPoints() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtInPrompts
3
- } from "./roy-agent-core-97tjdb2r.js";
3
+ } from "./roy-agent-core-dj18eyyk.js";
4
4
  import {
5
5
  getXDGPath
6
6
  } from "./roy-agent-core-qxnbvgwe.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  WORKFLOW_EXTRACT_PROMPT
3
- } from "./roy-agent-core-97tjdb2r.js";
3
+ } from "./roy-agent-core-dj18eyyk.js";
4
4
  import {
5
5
  BasePlugin
6
6
  } from "./roy-agent-core-az13yzmc.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./roy-agent-core-hvdfgvfz.js";
5
5
  import {
6
6
  DEFAULT_SUBAGENT_PROMPT
7
- } from "./roy-agent-core-vady4w02.js";
7
+ } from "./roy-agent-core-hfgqwf5w.js";
8
8
  import {
9
9
  TaskHookPoints
10
10
  } from "./roy-agent-core-92z6t4he.js";