@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.
- package/dist/env/agent/index.js +8 -8
- package/dist/env/event-source/index.js +12 -4
- package/dist/env/index.js +20 -15
- package/dist/env/llm/index.js +4 -2
- package/dist/env/prompt/index.js +2 -1
- package/dist/env/session/index.js +3 -4
- package/dist/env/session/storage/index.js +2 -2
- package/dist/env/task/delegate/index.js +3 -2
- package/dist/env/task/index.js +4 -3
- package/dist/env/task/plugins/index.js +7 -4
- package/dist/env/tool/built-in/index.js +2 -1
- package/dist/env/tool/index.js +11 -8
- package/dist/env/workflow/engine/index.js +5 -3
- package/dist/env/workflow/index.js +6 -4
- package/dist/env/workflow/nodes/index.js +1 -1
- package/dist/env/workflow/tools/index.js +7 -1
- package/dist/env/workflow/utils/index.js +5 -0
- package/dist/index.js +144 -32
- package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-0r4ndyn9.js} +119 -7
- package/dist/shared/@ai-setting/{roy-agent-core-jymz9fzp.js → roy-agent-core-2c8eraxq.js} +126 -41
- package/dist/shared/@ai-setting/{roy-agent-core-0y64qaac.js → roy-agent-core-32m0nb9j.js} +119 -30
- package/dist/shared/@ai-setting/roy-agent-core-4yq23m5g.js +421 -0
- package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-5ykms33a.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mmkyydw7.js → roy-agent-core-83d035pp.js} +91 -579
- package/dist/shared/@ai-setting/roy-agent-core-8wd3qwx5.js +35 -0
- package/dist/shared/@ai-setting/{roy-agent-core-yx0vw1aw.js → roy-agent-core-8zjntsbb.js} +102 -32
- package/dist/shared/@ai-setting/{roy-agent-core-29fh9mxg.js → roy-agent-core-bwjpte58.js} +1 -2
- package/dist/shared/@ai-setting/{roy-agent-core-vneyghpg.js → roy-agent-core-ddq5hcp5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qhhxx2x2.js → roy-agent-core-ds5f75pg.js} +2 -1
- package/dist/shared/@ai-setting/{roy-agent-core-4cdtdxqx.js → roy-agent-core-ewr1nw7t.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-hvdfgvfz.js +114 -0
- package/dist/shared/@ai-setting/{roy-agent-core-3arrpf7n.js → roy-agent-core-hxsbegfc.js} +229 -9
- package/dist/shared/@ai-setting/{roy-agent-core-9y09xfav.js → roy-agent-core-j0107ww1.js} +6 -418
- package/dist/shared/@ai-setting/{roy-agent-core-6mk0m4t3.js → roy-agent-core-m683wd1n.js} +283 -15
- package/dist/shared/@ai-setting/{roy-agent-core-bgw4dq11.js → roy-agent-core-mw4ty0ba.js} +44 -5
- package/dist/shared/@ai-setting/{roy-agent-core-7z4xtrmw.js → roy-agent-core-nqzt9ne4.js} +53 -0
- package/dist/shared/@ai-setting/roy-agent-core-pt7as39r.js +0 -0
- package/dist/shared/@ai-setting/{roy-agent-core-6n7xwv4v.js → roy-agent-core-rkz8r2sx.js} +5 -3
- package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-txwf64pd.js} +70 -0
- package/dist/shared/@ai-setting/{roy-agent-core-7fdzfsm6.js → roy-agent-core-w0kb72ve.js} +42 -213
- package/dist/shared/@ai-setting/roy-agent-core-w6bmrgap.js +581 -0
- package/dist/shared/@ai-setting/{roy-agent-core-qhjb153z.js → roy-agent-core-xnxyzaw4.js} +27 -4
- package/dist/shared/@ai-setting/roy-agent-core-yanpq5gb.js +116 -0
- package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-z240ts1r.js} +27 -3
- package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-zky9jse4.js} +163 -3
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-x3gtyqax.js +0 -378
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
693
|
+
logger2.info(`Loaded ${tools.length} built-in tools`);
|
|
475
694
|
} catch (err) {
|
|
476
|
-
|
|
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
|
-
|
|
725
|
+
|
|
726
|
+
export { ToolRegistry, ToolValidator, setToolConfigComponent, getMaxOutputSize, truncateOutputInline, ToolComponent };
|