@ai-setting/roy-agent-core 1.5.88 → 1.5.90

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 (48) hide show
  1. package/dist/env/agent/index.js +8 -8
  2. package/dist/env/event-source/index.js +12 -4
  3. package/dist/env/index.js +20 -15
  4. package/dist/env/llm/index.js +4 -2
  5. package/dist/env/prompt/index.js +2 -1
  6. package/dist/env/session/index.js +3 -4
  7. package/dist/env/session/storage/index.js +2 -2
  8. package/dist/env/task/delegate/index.js +3 -2
  9. package/dist/env/task/index.js +4 -3
  10. package/dist/env/task/plugins/index.js +7 -4
  11. package/dist/env/tool/built-in/index.js +2 -1
  12. package/dist/env/tool/index.js +11 -8
  13. package/dist/env/workflow/engine/index.js +5 -3
  14. package/dist/env/workflow/index.js +6 -4
  15. package/dist/env/workflow/nodes/index.js +1 -1
  16. package/dist/env/workflow/tools/index.js +7 -1
  17. package/dist/env/workflow/utils/index.js +5 -0
  18. package/dist/index.js +144 -32
  19. package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-0r4ndyn9.js} +119 -7
  20. package/dist/shared/@ai-setting/{roy-agent-core-jymz9fzp.js → roy-agent-core-2c8eraxq.js} +126 -41
  21. package/dist/shared/@ai-setting/{roy-agent-core-0y64qaac.js → roy-agent-core-32m0nb9j.js} +119 -30
  22. package/dist/shared/@ai-setting/roy-agent-core-4yq23m5g.js +421 -0
  23. package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-5ykms33a.js} +1 -1
  24. package/dist/shared/@ai-setting/{roy-agent-core-mmkyydw7.js → roy-agent-core-83d035pp.js} +91 -579
  25. package/dist/shared/@ai-setting/roy-agent-core-8wd3qwx5.js +35 -0
  26. package/dist/shared/@ai-setting/{roy-agent-core-yx0vw1aw.js → roy-agent-core-8zjntsbb.js} +102 -32
  27. package/dist/shared/@ai-setting/{roy-agent-core-29fh9mxg.js → roy-agent-core-bwjpte58.js} +1 -2
  28. package/dist/shared/@ai-setting/{roy-agent-core-vneyghpg.js → roy-agent-core-ddq5hcp5.js} +1 -1
  29. package/dist/shared/@ai-setting/{roy-agent-core-qhhxx2x2.js → roy-agent-core-ds5f75pg.js} +2 -1
  30. package/dist/shared/@ai-setting/{roy-agent-core-4cdtdxqx.js → roy-agent-core-ewr1nw7t.js} +1 -1
  31. package/dist/shared/@ai-setting/roy-agent-core-hvdfgvfz.js +114 -0
  32. package/dist/shared/@ai-setting/{roy-agent-core-3arrpf7n.js → roy-agent-core-hxsbegfc.js} +229 -9
  33. package/dist/shared/@ai-setting/{roy-agent-core-9y09xfav.js → roy-agent-core-j0107ww1.js} +6 -418
  34. package/dist/shared/@ai-setting/{roy-agent-core-6mk0m4t3.js → roy-agent-core-m683wd1n.js} +283 -15
  35. package/dist/shared/@ai-setting/{roy-agent-core-bgw4dq11.js → roy-agent-core-mw4ty0ba.js} +44 -5
  36. package/dist/shared/@ai-setting/{roy-agent-core-7z4xtrmw.js → roy-agent-core-nqzt9ne4.js} +53 -0
  37. package/dist/shared/@ai-setting/roy-agent-core-pt7as39r.js +0 -0
  38. package/dist/shared/@ai-setting/{roy-agent-core-6n7xwv4v.js → roy-agent-core-rkz8r2sx.js} +5 -3
  39. package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-txwf64pd.js} +70 -0
  40. package/dist/shared/@ai-setting/{roy-agent-core-7fdzfsm6.js → roy-agent-core-w0kb72ve.js} +42 -213
  41. package/dist/shared/@ai-setting/roy-agent-core-w6bmrgap.js +581 -0
  42. package/dist/shared/@ai-setting/{roy-agent-core-qhjb153z.js → roy-agent-core-xnxyzaw4.js} +27 -4
  43. package/dist/shared/@ai-setting/roy-agent-core-yanpq5gb.js +116 -0
  44. package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-z240ts1r.js} +27 -3
  45. package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-zky9jse4.js} +163 -3
  46. package/package.json +1 -1
  47. package/dist/shared/@ai-setting/roy-agent-core-x3gtyqax.js +0 -378
  48. /package/dist/shared/@ai-setting/{roy-agent-core-4f3976cd.js → roy-agent-core-k5hxvaf0.js} +0 -0
@@ -1,3 +1,7 @@
1
+ import {
2
+ AUTO_TASK_METADATA_BEGIN,
3
+ AUTO_TASK_METADATA_END
4
+ } from "./roy-agent-core-yanpq5gb.js";
1
5
  import {
2
6
  AskUserError,
3
7
  init_workflow_hil
@@ -25,8 +29,6 @@ import {
25
29
  import {
26
30
  __require
27
31
  } from "./roy-agent-core-fs0mn2jk.js";
28
- // src/env/tool/tool-component.ts
29
- import { z } from "zod";
30
32
 
31
33
  // src/env/tool/registry.ts
32
34
  class ToolRegistry {
@@ -144,6 +146,7 @@ class ToolValidator {
144
146
  }
145
147
 
146
148
  // src/env/tool/tool-component.ts
149
+ import { z } from "zod";
147
150
  init_logger();
148
151
  init_global_hook_manager();
149
152
 
@@ -178,7 +181,138 @@ var TOOL_CONFIG_REGISTRATION = {
178
181
  // src/env/tool/tool-component.ts
179
182
  init_workflow_hil();
180
183
  init_env_context();
181
- var logger = createLogger("tool");
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");
182
316
  var configComponentInstance = null;
183
317
  function setToolConfigComponent(component) {
184
318
  configComponentInstance = component;
@@ -199,6 +333,29 @@ function truncateOutput(output, maxSize) {
199
333
  metadata: {}
200
334
  };
201
335
  }
336
+ const beginIdx = output.indexOf(AUTO_TASK_METADATA_BEGIN);
337
+ const endIdx = output.indexOf(AUTO_TASK_METADATA_END, beginIdx >= 0 ? beginIdx + AUTO_TASK_METADATA_BEGIN.length : 0);
338
+ if (beginIdx >= 0 && endIdx > beginIdx) {
339
+ const metaEnd = endIdx + AUTO_TASK_METADATA_END.length;
340
+ const metadataBlock = output.substring(beginIdx, metaEnd);
341
+ const remainder = output.substring(0, beginIdx) + output.substring(metaEnd);
342
+ const budget = Math.max(0, maxSize - metadataBlock.length);
343
+ const truncatedRemainder = remainder.substring(0, budget);
344
+ const isRemainderTruncated = remainder.length > budget;
345
+ const truncationNotice2 = isRemainderTruncated ? `
346
+
347
+ [OUTPUT TRUNCATED: ${remainder.length} → ${budget} characters. Use offset/limit parameters or pipe to file for full content.]` : "";
348
+ return {
349
+ output: metadataBlock + `
350
+
351
+ ` + truncatedRemainder + truncationNotice2,
352
+ metadata: {
353
+ output_truncated: isRemainderTruncated,
354
+ original_output_size: output.length,
355
+ truncated_output_size: maxSize
356
+ }
357
+ };
358
+ }
202
359
  const truncatedOutput = output.substring(0, maxSize);
203
360
  const truncationNotice = `
204
361
 
@@ -212,6 +369,49 @@ function truncateOutput(output, maxSize) {
212
369
  }
213
370
  };
214
371
  }
372
+ var TOOL_MAX_OUTPUT_SIZE_OVERRIDES = {
373
+ grep: 51200,
374
+ read_file: 204800,
375
+ glob: 10240
376
+ };
377
+ function getMaxOutputSizeForTool(toolName, overrideMaxSize) {
378
+ if (typeof overrideMaxSize === "number" && overrideMaxSize >= 0) {
379
+ return overrideMaxSize;
380
+ }
381
+ if (toolName && TOOL_MAX_OUTPUT_SIZE_OVERRIDES[toolName] !== undefined) {
382
+ return TOOL_MAX_OUTPUT_SIZE_OVERRIDES[toolName];
383
+ }
384
+ return getMaxOutputSize();
385
+ }
386
+ function truncateOutputInline(result, maxSize, overrideMaxSize, toolName) {
387
+ const cloned = {
388
+ success: result.success,
389
+ output: result.output,
390
+ error: result.error,
391
+ metadata: result.metadata ? { ...result.metadata } : { execution_time_ms: 0 }
392
+ };
393
+ const effectiveMax = typeof maxSize === "number" ? maxSize : getMaxOutputSizeForTool(toolName, overrideMaxSize);
394
+ if (effectiveMax <= 0) {
395
+ return cloned;
396
+ }
397
+ if (typeof cloned.output === "string") {
398
+ const truncated = truncateOutput(cloned.output, effectiveMax);
399
+ cloned.output = truncated.output;
400
+ cloned.metadata = {
401
+ ...cloned.metadata,
402
+ ...truncated.metadata
403
+ };
404
+ }
405
+ if (typeof cloned.error === "string" && cloned.error.length > effectiveMax) {
406
+ const truncated = truncateOutput(cloned.error, effectiveMax);
407
+ cloned.error = truncated.output;
408
+ cloned.metadata = {
409
+ ...cloned.metadata,
410
+ ...truncated.metadata
411
+ };
412
+ }
413
+ return cloned;
414
+ }
215
415
 
216
416
  class ToolComponent extends BaseComponent {
217
417
  name = "tool";
@@ -238,7 +438,7 @@ class ToolComponent extends BaseComponent {
238
438
  if (this.config?.builtInTools?.enabled !== false) {
239
439
  await this.loadBuiltInTools();
240
440
  }
241
- logger.info(`ToolComponent initialized with ${this.getToolCount()} tools`);
441
+ logger2.info(`ToolComponent initialized with ${this.getToolCount()} tools`);
242
442
  }
243
443
  async registerConfig(options) {
244
444
  const configComponent = options.configComponent;
@@ -336,7 +536,7 @@ class ToolComponent extends BaseComponent {
336
536
  });
337
537
  }
338
538
  onConfigChange(event) {
339
- logger.info(`Tool config changed: ${event.key}`, {
539
+ logger2.info(`Tool config changed: ${event.key}`, {
340
540
  oldValue: event.oldValue,
341
541
  newValue: event.newValue
342
542
  });
@@ -354,7 +554,7 @@ class ToolComponent extends BaseComponent {
354
554
  source,
355
555
  enabled: true
356
556
  });
357
- logger.debug(`Registered tool: ${tool.name}`);
557
+ logger2.debug(`Registered tool: ${tool.name}`);
358
558
  globalHookManager.execute(ToolHookPoints.AFTER_REGISTER, { tool });
359
559
  }
360
560
  registerMany(tools, source = "dynamic") {
@@ -422,13 +622,32 @@ class ToolComponent extends BaseComponent {
422
622
  }
423
623
  if (typeof result.output === "string") {
424
624
  const maxOutputSize = getMaxOutputSize();
625
+ let fullOutput = null;
425
626
  if (maxOutputSize > 0) {
627
+ fullOutput = result.output;
426
628
  const { output: truncatedOutput, metadata: truncationMeta } = truncateOutput(result.output, maxOutputSize);
427
629
  result.output = truncatedOutput;
428
630
  result.metadata = {
429
631
  ...result.metadata,
430
632
  ...truncationMeta
431
633
  };
634
+ if (truncationMeta.output_truncated === true && tool.name !== "read_file" && fullOutput !== null) {
635
+ try {
636
+ const tempFilePath = await TempFileManager.getInstance().writeTempFile(fullOutput, tool.name);
637
+ result.metadata = {
638
+ ...result.metadata,
639
+ truncation_temp_file: tempFilePath
640
+ };
641
+ result.output += `
642
+
643
+ ⚠️ 输出被截断(原 ${truncationMeta.original_output_size} 字符,截断到 ${truncationMeta.truncated_output_size} 字符)
644
+ \uD83D\uDCC1 完整内容保存到: ${tempFilePath}
645
+ \uD83D\uDD0D 使用 read_file 工具按需读取`;
646
+ logger2.debug(`[tool-component] Truncated output saved to temp file: ${tempFilePath} (${truncationMeta.original_output_size} bytes)`);
647
+ } catch (err) {
648
+ logger2.warn(`[tool-component] Failed to write temp file for truncated output: ${err}`);
649
+ }
650
+ }
432
651
  }
433
652
  const currentTaskId = getCurrentTaskId();
434
653
  if (currentTaskId !== undefined) {
@@ -471,9 +690,9 @@ class ToolComponent extends BaseComponent {
471
690
  const { getAllBuiltInTools } = await import("../../env/tool/built-in/index.js");
472
691
  const tools = getAllBuiltInTools();
473
692
  this.registerMany(tools, "built-in");
474
- logger.info(`Loaded ${tools.length} built-in tools`);
693
+ logger2.info(`Loaded ${tools.length} built-in tools`);
475
694
  } catch (err) {
476
- logger.warn(`Failed to load built-in tools: ${err.message}`);
695
+ logger2.warn(`Failed to load built-in tools: ${err.message}`);
477
696
  }
478
697
  }
479
698
  getHookPoints() {
@@ -503,4 +722,5 @@ var ToolComponentConfigSchema = z.object({
503
722
  maxConcurrency: z.number().int().positive().default(4)
504
723
  }).default({})
505
724
  });
506
- export { ToolRegistry, ToolValidator, setToolConfigComponent, getMaxOutputSize, ToolComponent };
725
+
726
+ export { ToolRegistry, ToolValidator, setToolConfigComponent, getMaxOutputSize, truncateOutputInline, ToolComponent };