@ai-setting/roy-agent-core 1.5.56 → 1.5.58
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/config/index.js +1 -1
- package/dist/env/agent/index.js +1 -1
- package/dist/env/index.js +3 -3
- package/dist/env/prompt/index.js +1 -1
- package/dist/env/task/delegate/index.js +1 -1
- package/dist/env/task/index.js +2 -2
- package/dist/index.js +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-eraxs53g.js → roy-agent-core-0hhxwz5f.js} +74 -231
- package/dist/shared/@ai-setting/{roy-agent-core-qzhkgbyj.js → roy-agent-core-6ph5va4n.js} +1 -0
- package/dist/shared/@ai-setting/{roy-agent-core-2c9ms8gv.js → roy-agent-core-prdngx28.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-grt8ysq2.js → roy-agent-core-q16bh5e9.js} +9 -7
- package/dist/shared/@ai-setting/{roy-agent-core-2tna3t64.js → roy-agent-core-skaha0yj.js} +1 -1
- package/package.json +1 -1
package/dist/config/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
parseJSONCWithProtocols,
|
|
11
11
|
substituteEnvVars,
|
|
12
12
|
substituteProtocolRefs
|
|
13
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
13
|
+
} from "../shared/@ai-setting/roy-agent-core-prdngx28.js";
|
|
14
14
|
import"../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
15
15
|
import"../shared/@ai-setting/roy-agent-core-qxhq8ven.js";
|
|
16
16
|
import"../shared/@ai-setting/roy-agent-core-rgckng3p.js";
|
package/dist/env/agent/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentComponent,
|
|
3
3
|
AgentComponentConfigSchema
|
|
4
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
4
|
+
} from "../../shared/@ai-setting/roy-agent-core-6ph5va4n.js";
|
|
5
5
|
import"../../shared/@ai-setting/roy-agent-core-65yjzwv5.js";
|
|
6
6
|
import"../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
7
7
|
import"../../shared/@ai-setting/roy-agent-core-nx3c3ce2.js";
|
package/dist/env/index.js
CHANGED
|
@@ -38,14 +38,14 @@ import"../shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
|
|
|
38
38
|
import {
|
|
39
39
|
AgentComponent,
|
|
40
40
|
AgentComponentConfigSchema
|
|
41
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
41
|
+
} from "../shared/@ai-setting/roy-agent-core-6ph5va4n.js";
|
|
42
42
|
import"../shared/@ai-setting/roy-agent-core-65yjzwv5.js";
|
|
43
43
|
import"../shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
44
44
|
import {
|
|
45
45
|
TaskComponent
|
|
46
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
46
|
+
} from "../shared/@ai-setting/roy-agent-core-skaha0yj.js";
|
|
47
47
|
import"../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
48
|
-
import"../shared/@ai-setting/roy-agent-core-
|
|
48
|
+
import"../shared/@ai-setting/roy-agent-core-0hhxwz5f.js";
|
|
49
49
|
import"../shared/@ai-setting/roy-agent-core-w4f871e2.js";
|
|
50
50
|
import"../shared/@ai-setting/roy-agent-core-nx3c3ce2.js";
|
|
51
51
|
import {
|
package/dist/env/prompt/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
PromptConfigSchema,
|
|
4
4
|
PromptPathSchema,
|
|
5
5
|
PromptRenderer
|
|
6
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../../shared/@ai-setting/roy-agent-core-q16bh5e9.js";
|
|
7
7
|
import"../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
8
8
|
import"../../shared/@ai-setting/roy-agent-core-qxhq8ven.js";
|
|
9
9
|
import"../../shared/@ai-setting/roy-agent-core-rgckng3p.js";
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
BackgroundTaskManager,
|
|
4
4
|
createDelegateTool,
|
|
5
5
|
createStopTool
|
|
6
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../../../shared/@ai-setting/roy-agent-core-0hhxwz5f.js";
|
|
7
7
|
import"../../../shared/@ai-setting/roy-agent-core-nx3c3ce2.js";
|
|
8
8
|
import"../../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
|
|
9
9
|
import"../../../shared/@ai-setting/roy-agent-core-92z6t4he.js";
|
package/dist/env/task/index.js
CHANGED
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
TaskPriorityEnum,
|
|
6
6
|
TaskStatusEnum,
|
|
7
7
|
TaskTypeEnum
|
|
8
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
8
|
+
} from "../../shared/@ai-setting/roy-agent-core-skaha0yj.js";
|
|
9
9
|
import {
|
|
10
10
|
TaskEntityEventTypes
|
|
11
11
|
} from "../../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
12
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
12
|
+
import"../../shared/@ai-setting/roy-agent-core-0hhxwz5f.js";
|
|
13
13
|
import {
|
|
14
14
|
SQLiteTaskStore,
|
|
15
15
|
getDefaultTaskDbPath
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
PromptStore,
|
|
4
4
|
getBuiltInPrompt,
|
|
5
5
|
getBuiltInPromptNames
|
|
6
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "./shared/@ai-setting/roy-agent-core-q16bh5e9.js";
|
|
7
7
|
import {
|
|
8
8
|
LLMComponent,
|
|
9
9
|
LLMConfigSchema,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "./shared/@ai-setting/roy-agent-core-sfqx98j6.js";
|
|
15
15
|
import {
|
|
16
16
|
ConfigComponent
|
|
17
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
17
|
+
} from "./shared/@ai-setting/roy-agent-core-prdngx28.js";
|
|
18
18
|
import {
|
|
19
19
|
CommandsComponent
|
|
20
20
|
} from "./shared/@ai-setting/roy-agent-core-7wdjpbcr.js";
|
|
@@ -114,7 +114,7 @@ import"./shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
|
|
|
114
114
|
import {
|
|
115
115
|
AgentComponent,
|
|
116
116
|
AgentComponentConfigSchema
|
|
117
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
117
|
+
} from "./shared/@ai-setting/roy-agent-core-6ph5va4n.js";
|
|
118
118
|
import {
|
|
119
119
|
createInvokeConfig,
|
|
120
120
|
invoke,
|
|
@@ -127,9 +127,9 @@ import {
|
|
|
127
127
|
} from "./shared/@ai-setting/roy-agent-core-e25xkv53.js";
|
|
128
128
|
import {
|
|
129
129
|
TaskComponent
|
|
130
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
130
|
+
} from "./shared/@ai-setting/roy-agent-core-skaha0yj.js";
|
|
131
131
|
import"./shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
132
|
-
import"./shared/@ai-setting/roy-agent-core-
|
|
132
|
+
import"./shared/@ai-setting/roy-agent-core-0hhxwz5f.js";
|
|
133
133
|
import {
|
|
134
134
|
SQLiteTaskStore,
|
|
135
135
|
getDefaultTaskDbPath
|
|
@@ -9,8 +9,10 @@ import {
|
|
|
9
9
|
init_global_hook_manager
|
|
10
10
|
} from "./roy-agent-core-7tp56w6n.js";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
init_context
|
|
13
|
+
} from "./roy-agent-core-qg4rma4c.js";
|
|
14
|
+
import {
|
|
15
|
+
getCurrentTaskId
|
|
14
16
|
} from "./roy-agent-core-y5d04fm3.js";
|
|
15
17
|
import {
|
|
16
18
|
TracedAs,
|
|
@@ -26,8 +28,8 @@ import {
|
|
|
26
28
|
|
|
27
29
|
// src/env/task/delegate/delegate-tool.ts
|
|
28
30
|
init_logger();
|
|
29
|
-
init_env_context();
|
|
30
31
|
init_decorator();
|
|
32
|
+
init_context();
|
|
31
33
|
import { z } from "zod";
|
|
32
34
|
|
|
33
35
|
// src/env/task/delegate/subagent-resolver.ts
|
|
@@ -205,10 +207,7 @@ var DelegateToolParameters = z.object({
|
|
|
205
207
|
description: z.string().describe("A short (3-5 words) description of the task"),
|
|
206
208
|
prompt: z.string().describe("The task for the agent to perform"),
|
|
207
209
|
subagent_type: z.string().describe("The type of specialized agent to use for this task").default("general"),
|
|
208
|
-
background: z.boolean().describe("Whether to run the task in background. If true, returns immediately and notifies when complete (default: false)").default(false),
|
|
209
210
|
timeout: z.number().describe("Task timeout in milliseconds. Default: 1800000 (30 minutes). If set, task will be terminated after timeout.").optional(),
|
|
210
|
-
cleanup: z.enum(["delete", "keep"]).describe("Whether to delete sub session after completion. 'delete' removes the session, 'keep' retains it (default: keep)").default("keep").optional(),
|
|
211
|
-
task_id: z.number().describe("Optional task ID to associate with this delegate task, for tracking in operation records").optional(),
|
|
212
211
|
reason: z.string().describe("Brief reason for calling this tool (max 30 chars, e.g., 'Delegate refactor task')").optional()
|
|
213
212
|
});
|
|
214
213
|
var DEFAULT_TIMEOUT = 1800000;
|
|
@@ -239,8 +238,8 @@ class BackgroundTaskManager {
|
|
|
239
238
|
}
|
|
240
239
|
}
|
|
241
240
|
async createTask(options) {
|
|
242
|
-
const { parentSessionId, description, prompt, subagentType, timeout
|
|
243
|
-
const taskIdGen = `
|
|
241
|
+
const { parentSessionId, description, prompt, subagentType, timeout } = options;
|
|
242
|
+
const taskIdGen = `process_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
244
243
|
const sessionComponent = this.getSessionComponent();
|
|
245
244
|
if (!sessionComponent) {
|
|
246
245
|
throw new Error("SessionComponent not found");
|
|
@@ -254,9 +253,6 @@ class BackgroundTaskManager {
|
|
|
254
253
|
created_by: "subagent",
|
|
255
254
|
task_description: description
|
|
256
255
|
};
|
|
257
|
-
if (taskId) {
|
|
258
|
-
metadata.task_id = taskId;
|
|
259
|
-
}
|
|
260
256
|
const subSession = await sessionComponent.create({
|
|
261
257
|
title: `${description} (@${subagentType} subagent)`,
|
|
262
258
|
metadata
|
|
@@ -273,8 +269,7 @@ class BackgroundTaskManager {
|
|
|
273
269
|
subagentType,
|
|
274
270
|
status: "pending",
|
|
275
271
|
createdAt: Date.now(),
|
|
276
|
-
abortController
|
|
277
|
-
taskId
|
|
272
|
+
abortController
|
|
278
273
|
};
|
|
279
274
|
this.tasks.set(taskIdGen, task);
|
|
280
275
|
this.abortControllers.set(taskIdGen, abortController);
|
|
@@ -283,11 +278,10 @@ class BackgroundTaskManager {
|
|
|
283
278
|
subSessionId: subSession.id,
|
|
284
279
|
parentSessionId,
|
|
285
280
|
description,
|
|
286
|
-
subagentType
|
|
287
|
-
associatedTaskId: taskId
|
|
281
|
+
subagentType
|
|
288
282
|
};
|
|
289
283
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.STARTED, startedPayload, parentSessionId);
|
|
290
|
-
this.executeTask(taskIdGen, prompt, timeout,
|
|
284
|
+
this.executeTask(taskIdGen, prompt, timeout, parentSessionId).catch((err) => {
|
|
291
285
|
logger.error(`[BackgroundTaskManager] executeTask unhandled rejection`, {
|
|
292
286
|
taskId: taskIdGen,
|
|
293
287
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -295,7 +289,7 @@ class BackgroundTaskManager {
|
|
|
295
289
|
});
|
|
296
290
|
return { taskId: taskIdGen, subSessionId: subSession.id };
|
|
297
291
|
}
|
|
298
|
-
async executeTask(taskId, prompt, timeout,
|
|
292
|
+
async executeTask(taskId, prompt, timeout, parentSessionId) {
|
|
299
293
|
const task = this.tasks.get(taskId);
|
|
300
294
|
if (!task) {
|
|
301
295
|
logger.warn(`[BackgroundTaskManager] executeTask: Task not found`, { taskId });
|
|
@@ -321,6 +315,13 @@ class BackgroundTaskManager {
|
|
|
321
315
|
task.completedAt = Date.now();
|
|
322
316
|
task.result = result;
|
|
323
317
|
const executionTimeMs = task.completedAt - task.startedAt;
|
|
318
|
+
task.associatedTaskId = getCurrentTaskId();
|
|
319
|
+
if (task.associatedTaskId === undefined && result) {
|
|
320
|
+
const match = result.match(/Task\s+#?(\d+)/i);
|
|
321
|
+
if (match) {
|
|
322
|
+
task.associatedTaskId = parseInt(match[1], 10);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
324
325
|
const completedPayload = {
|
|
325
326
|
backgroundTaskId: task.id,
|
|
326
327
|
subSessionId: task.subSessionId,
|
|
@@ -329,7 +330,7 @@ class BackgroundTaskManager {
|
|
|
329
330
|
result: task.result,
|
|
330
331
|
description: task.description,
|
|
331
332
|
executionTimeMs,
|
|
332
|
-
associatedTaskId: task.
|
|
333
|
+
associatedTaskId: task.associatedTaskId
|
|
333
334
|
};
|
|
334
335
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.COMPLETED, completedPayload, parentSessionId || task.parentSessionId);
|
|
335
336
|
logger.info(`[BackgroundTaskManager] Task completed successfully`, {
|
|
@@ -340,6 +341,7 @@ class BackgroundTaskManager {
|
|
|
340
341
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
341
342
|
const isStoppedError = errorMessage.toLowerCase().includes("stopped") || errorMessage.toLowerCase().includes("aborted");
|
|
342
343
|
const executionTimeMs = task.startedAt ? Date.now() - task.startedAt : 0;
|
|
344
|
+
task.associatedTaskId = getCurrentTaskId();
|
|
343
345
|
if (isStoppedError) {
|
|
344
346
|
task.status = "stopped";
|
|
345
347
|
const stoppedPayload = {
|
|
@@ -350,10 +352,10 @@ class BackgroundTaskManager {
|
|
|
350
352
|
description: task.description,
|
|
351
353
|
error: errorMessage,
|
|
352
354
|
executionTimeMs,
|
|
353
|
-
associatedTaskId: task.
|
|
355
|
+
associatedTaskId: task.associatedTaskId
|
|
354
356
|
};
|
|
355
357
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, parentSessionId || task.parentSessionId);
|
|
356
|
-
} else if (errorMessage.
|
|
358
|
+
} else if (errorMessage.startsWith("Task execution timeout after")) {
|
|
357
359
|
task.status = "timeout";
|
|
358
360
|
const timeoutPayload = {
|
|
359
361
|
backgroundTaskId: task.id,
|
|
@@ -363,7 +365,7 @@ class BackgroundTaskManager {
|
|
|
363
365
|
description: task.description,
|
|
364
366
|
error: errorMessage,
|
|
365
367
|
executionTimeMs,
|
|
366
|
-
associatedTaskId: task.
|
|
368
|
+
associatedTaskId: task.associatedTaskId
|
|
367
369
|
};
|
|
368
370
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.TIMEOUT, timeoutPayload, parentSessionId || task.parentSessionId);
|
|
369
371
|
} else {
|
|
@@ -373,10 +375,9 @@ class BackgroundTaskManager {
|
|
|
373
375
|
subSessionId: task.subSessionId,
|
|
374
376
|
parentSessionId: parentSessionId || task.parentSessionId,
|
|
375
377
|
status: "failed",
|
|
376
|
-
description: task.description,
|
|
377
378
|
error: errorMessage,
|
|
378
379
|
executionTimeMs,
|
|
379
|
-
associatedTaskId: task.
|
|
380
|
+
associatedTaskId: task.associatedTaskId
|
|
380
381
|
};
|
|
381
382
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.FAILED, failedPayload, parentSessionId || task.parentSessionId);
|
|
382
383
|
}
|
|
@@ -402,13 +403,18 @@ class BackgroundTaskManager {
|
|
|
402
403
|
const elapsedMs = Date.now() - task.startedAt;
|
|
403
404
|
task.progress = Math.min(95, Math.floor(elapsedMs / PROGRESS_INTERVAL * 100));
|
|
404
405
|
}
|
|
406
|
+
const currentTaskId = getCurrentTaskId();
|
|
407
|
+
if (currentTaskId !== undefined) {
|
|
408
|
+
task.associatedTaskId = currentTaskId;
|
|
409
|
+
}
|
|
405
410
|
const progressPayload = {
|
|
406
411
|
backgroundTaskId: taskId,
|
|
407
412
|
subSessionId: task.subSessionId,
|
|
408
413
|
parentSessionId,
|
|
409
414
|
description: task.description,
|
|
410
415
|
status: task.status,
|
|
411
|
-
progress: task.progress
|
|
416
|
+
progress: task.progress,
|
|
417
|
+
associatedTaskId: task.associatedTaskId
|
|
412
418
|
};
|
|
413
419
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.PROGRESS, progressPayload, parentSessionId);
|
|
414
420
|
}, PROGRESS_INTERVAL);
|
|
@@ -453,7 +459,8 @@ ${prompt}
|
|
|
453
459
|
## 执行规范
|
|
454
460
|
- 使用可用工具完成任务
|
|
455
461
|
- 返回清晰的任务执行结果摘要
|
|
456
|
-
- 适时调用 task_operation_create
|
|
462
|
+
- 适时调用 task_operation_create 记录进展
|
|
463
|
+
- 如果你通过 task_create 创建了任务,请在最终响应中明确报告 task_id(例如:Task #627)`;
|
|
457
464
|
if (!agentComponent) {
|
|
458
465
|
throw new Error("AgentComponent not found");
|
|
459
466
|
}
|
|
@@ -471,15 +478,26 @@ ${prompt}
|
|
|
471
478
|
return new Promise((resolve, reject) => {
|
|
472
479
|
const timer = setTimeout(() => {
|
|
473
480
|
reject(new Error(`Task execution timeout after ${timeoutMs}ms`));
|
|
481
|
+
try {
|
|
482
|
+
agentComponent?.abort?.(subagentType);
|
|
483
|
+
} catch {}
|
|
474
484
|
}, timeoutMs);
|
|
475
485
|
signal?.addEventListener("abort", () => {
|
|
476
486
|
clearTimeout(timer);
|
|
487
|
+
try {
|
|
488
|
+
const env = this.env;
|
|
489
|
+
const agentComp = env?.getComponent?.("agent");
|
|
490
|
+
if (agentComp?.abort) {
|
|
491
|
+
agentComp.abort(subagentType);
|
|
492
|
+
}
|
|
493
|
+
} catch {}
|
|
477
494
|
reject(new Error("Task execution stopped"));
|
|
478
495
|
});
|
|
479
496
|
this.env.handle_query?.(delegateQuery, {
|
|
480
497
|
sessionId,
|
|
481
498
|
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
482
|
-
agentType: subagentType
|
|
499
|
+
agentType: subagentType,
|
|
500
|
+
abort: signal
|
|
483
501
|
})?.then((result) => {
|
|
484
502
|
clearTimeout(timer);
|
|
485
503
|
resolve(result);
|
|
@@ -512,7 +530,7 @@ ${prompt}
|
|
|
512
530
|
description: task.description,
|
|
513
531
|
error: "Task stopped by user",
|
|
514
532
|
executionTimeMs: task.startedAt ? task.completedAt - task.startedAt : 0,
|
|
515
|
-
associatedTaskId: task.
|
|
533
|
+
associatedTaskId: task.associatedTaskId
|
|
516
534
|
};
|
|
517
535
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, task.parentSessionId);
|
|
518
536
|
return { success: true, task, message: "Task has been stopped" };
|
|
@@ -554,7 +572,8 @@ function getAgentRegistry(taskComponent) {
|
|
|
554
572
|
}
|
|
555
573
|
function createDelegateTool(taskComponent) {
|
|
556
574
|
const env = taskComponent.env;
|
|
557
|
-
const
|
|
575
|
+
const existingManager = taskComponent.backgroundTaskManager;
|
|
576
|
+
const backgroundTaskManager = existingManager ?? new BackgroundTaskManager(env);
|
|
558
577
|
const registry = getAgentRegistry(taskComponent);
|
|
559
578
|
taskComponent._backgroundTaskManager = backgroundTaskManager;
|
|
560
579
|
const tool = {
|
|
@@ -569,26 +588,35 @@ When using the delegate_task tool, you must specify a subagent_type parameter to
|
|
|
569
588
|
## When to use delegate_task:
|
|
570
589
|
- When you need to perform complex, multi-step tasks that require independent execution
|
|
571
590
|
- When you need to explore a codebase thoroughly (use "explore" subagent)
|
|
572
|
-
- When you need to run long-running tasks without blocking the main agent
|
|
591
|
+
- When you need to run long-running tasks without blocking the main agent
|
|
592
|
+
|
|
593
|
+
## How it works:
|
|
594
|
+
This tool **always runs in background mode**. It returns immediately with:
|
|
595
|
+
- **bgProcessId**: Internal background process ID (use with \`stop_task\` to cancel, different from Task #)
|
|
596
|
+
- **subSessionId**: Sub-agent session ID (use with \`session_get\` to see full execution log, always retained)
|
|
597
|
+
|
|
598
|
+
**After delegating, just WAIT for the notification.** The background process will automatically notify you when:
|
|
599
|
+
- ✅ **completed** — with \`bgprocess:\` + \`Task #\` (if it created a task) + result summary
|
|
600
|
+
- ⏱️ **timeout** — with \`bgprocess:\` + \`Task #\` (if available)
|
|
601
|
+
- ❌ **failed** — with \`bgprocess:\` + \`Task #\` + error details
|
|
602
|
+
- \uD83D\uDED1 **stopped** — with \`bgprocess:\` + \`Task #\`
|
|
603
|
+
|
|
604
|
+
The sub-agent runs independently and creates its own tasks via \`task_create\`.
|
|
605
|
+
No need to poll — just wait for the notification and use \`task_get\` with the Task # reported in it.
|
|
573
606
|
|
|
574
607
|
## Parameters:
|
|
575
608
|
- **description**: A short (3-5 words) description of the task
|
|
576
609
|
- **prompt**: The task for the agent to perform
|
|
577
610
|
- **subagent_type**: The type of specialized agent to use (e.g., "general", "explore")
|
|
578
|
-
- **
|
|
579
|
-
- **
|
|
580
|
-
- **task_id**: Optional task ID to associate with this delegate task
|
|
581
|
-
|
|
582
|
-
## Synchronous vs Background mode:
|
|
583
|
-
**Synchronous mode (default)**: Waits for subagent to complete and returns result directly
|
|
584
|
-
**Background mode (background=true)**: Returns immediately with "accepted" status, runs independently`,
|
|
611
|
+
- **timeout**: Task timeout in milliseconds (optional, default 30 minutes)
|
|
612
|
+
- **reason**: Brief reason for calling this tool (optional)`,
|
|
585
613
|
parameters: DelegateToolParameters,
|
|
586
614
|
execute: async (args, ctx) => {
|
|
587
615
|
const startTime = Date.now();
|
|
588
616
|
const params = DelegateToolParameters.parse(args);
|
|
589
|
-
const { description, prompt, subagent_type = "general",
|
|
617
|
+
const { description, prompt, subagent_type = "general", timeout, reason } = params;
|
|
590
618
|
const parentSessionId = ctx.session_id || "default";
|
|
591
|
-
logger.info(`[delegate_task] Called: description=${description}, subagent_type=${subagent_type}
|
|
619
|
+
logger.info(`[delegate_task] Called: description=${description}, subagent_type=${subagent_type}`);
|
|
592
620
|
const registry2 = getAgentRegistry(taskComponent);
|
|
593
621
|
if (!isKnownSubagentType(subagent_type, registry2)) {
|
|
594
622
|
return {
|
|
@@ -601,12 +629,9 @@ When using the delegate_task tool, you must specify a subagent_type parameter to
|
|
|
601
629
|
const tagService = taskComponent.getTagService();
|
|
602
630
|
let promptWithTaskInfo = prompt;
|
|
603
631
|
const delegateCtx = {
|
|
604
|
-
taskId: task_id,
|
|
605
632
|
prompt: promptWithTaskInfo,
|
|
606
633
|
subagentType: subagent_type,
|
|
607
|
-
background,
|
|
608
634
|
timeout,
|
|
609
|
-
cleanup,
|
|
610
635
|
reason,
|
|
611
636
|
tagService
|
|
612
637
|
};
|
|
@@ -619,212 +644,31 @@ When using the delegate_task tool, you must specify a subagent_type parameter to
|
|
|
619
644
|
};
|
|
620
645
|
await globalHookManager.execute(TaskHookPoints.DELEGATE_BEFORE, hookCtx, { sessionId: parentSessionId });
|
|
621
646
|
promptWithTaskInfo = delegateCtx.prompt;
|
|
622
|
-
|
|
623
|
-
return await handleBackgroundTask(taskComponent, backgroundTaskManager, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout, delegateCtx.cleanup, delegateCtx.taskId);
|
|
624
|
-
} else {
|
|
625
|
-
return await handleSyncTask(taskComponent, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout, delegateCtx.taskId);
|
|
626
|
-
}
|
|
647
|
+
return await handleBackgroundTask(backgroundTaskManager, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout);
|
|
627
648
|
}
|
|
628
649
|
};
|
|
629
650
|
return tool;
|
|
630
651
|
}
|
|
631
|
-
async function
|
|
632
|
-
const startTime = Date.now();
|
|
633
|
-
try {
|
|
634
|
-
const sessionComponent = taskComponent.env?.getComponent?.("session");
|
|
635
|
-
if (!sessionComponent) {
|
|
636
|
-
return {
|
|
637
|
-
success: false,
|
|
638
|
-
output: "",
|
|
639
|
-
error: "SessionComponent not found",
|
|
640
|
-
metadata: { execution_time_ms: Date.now() - startTime }
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
const parentSession = await sessionComponent.get(parentSessionId);
|
|
644
|
-
if (!parentSession) {
|
|
645
|
-
return {
|
|
646
|
-
success: false,
|
|
647
|
-
output: "",
|
|
648
|
-
error: `Parent session not found: ${parentSessionId}`,
|
|
649
|
-
metadata: { execution_time_ms: Date.now() - startTime }
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
const metadata = {
|
|
653
|
-
subagent_type: subagentType,
|
|
654
|
-
created_by: "subagent",
|
|
655
|
-
task_description: description
|
|
656
|
-
};
|
|
657
|
-
if (taskId) {
|
|
658
|
-
metadata.task_id = taskId;
|
|
659
|
-
}
|
|
660
|
-
const subSession = await sessionComponent.create({
|
|
661
|
-
parentID: parentSessionId,
|
|
662
|
-
title: `${description} (@${subagentType} subagent)`,
|
|
663
|
-
metadata
|
|
664
|
-
});
|
|
665
|
-
if (!subSession) {
|
|
666
|
-
return {
|
|
667
|
-
success: false,
|
|
668
|
-
output: "",
|
|
669
|
-
error: "Failed to create sub-session",
|
|
670
|
-
metadata: { execution_time_ms: Date.now() - startTime }
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
const agentComponent = taskComponent.env?.getComponent?.("agent");
|
|
674
|
-
const registry = getAgentRegistry(taskComponent);
|
|
675
|
-
const resolved = await resolveSubAgentConfig(subagentType, { registry });
|
|
676
|
-
const subAgent = getSubAgentSpec(subagentType);
|
|
677
|
-
let basePrompt = resolved?.basePrompt || subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
678
|
-
const deniedTools = resolved?.deniedTools || subAgent?.deniedTools || [];
|
|
679
|
-
const allowedTools = resolved?.allowedTools || subAgent?.allowedTools;
|
|
680
|
-
let fullPrompt = basePrompt.replace(/{task_description}/g, description || "N/A");
|
|
681
|
-
fullPrompt += `
|
|
682
|
-
|
|
683
|
-
---
|
|
684
|
-
|
|
685
|
-
# Session Info
|
|
686
|
-
- task_id: ${taskId || "N/A"}
|
|
687
|
-
- session_id: ${subSession.id}
|
|
688
|
-
|
|
689
|
-
---
|
|
690
|
-
|
|
691
|
-
## 用户指令
|
|
692
|
-
${prompt}
|
|
693
|
-
|
|
694
|
-
---
|
|
695
|
-
|
|
696
|
-
## 执行规范
|
|
697
|
-
- 使用可用工具完成任务
|
|
698
|
-
- 返回清晰的任务执行结果摘要
|
|
699
|
-
- 适时调用 task_operation_create 记录进展`;
|
|
700
|
-
if (!agentComponent) {
|
|
701
|
-
return {
|
|
702
|
-
success: false,
|
|
703
|
-
output: "",
|
|
704
|
-
error: "AgentComponent not found",
|
|
705
|
-
metadata: { execution_time_ms: Date.now() - startTime }
|
|
706
|
-
};
|
|
707
|
-
}
|
|
708
|
-
const subAgentForRegister = subAgent ? { ...subAgent, allowedTools } : allowedTools ? {
|
|
709
|
-
id: subagentType,
|
|
710
|
-
name: subagentType,
|
|
711
|
-
mode: "subagent",
|
|
712
|
-
description: resolved?.description || "Custom agent",
|
|
713
|
-
allowedTools,
|
|
714
|
-
deniedTools
|
|
715
|
-
} : undefined;
|
|
716
|
-
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgentForRegister, deniedTools);
|
|
717
|
-
const isWorkflowAgent = registry?.get(subagentType)?.type === "workflow";
|
|
718
|
-
const delegateQuery = isWorkflowAgent ? prompt : fullPrompt;
|
|
719
|
-
const timeoutMs = timeout || DEFAULT_TIMEOUT;
|
|
720
|
-
let result;
|
|
721
|
-
try {
|
|
722
|
-
result = await Promise.race([
|
|
723
|
-
taskComponent.env?.handle_query?.(delegateQuery, {
|
|
724
|
-
sessionId: subSession.id,
|
|
725
|
-
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
726
|
-
agentType: subagentType
|
|
727
|
-
}),
|
|
728
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error(`Task execution timeout after ${timeoutMs}ms`)), timeoutMs))
|
|
729
|
-
]);
|
|
730
|
-
} catch (error) {
|
|
731
|
-
result = error instanceof Error ? error.message : String(error);
|
|
732
|
-
}
|
|
733
|
-
await sessionComponent.addMessage(subSession.id, {
|
|
734
|
-
role: "assistant",
|
|
735
|
-
content: result
|
|
736
|
-
});
|
|
737
|
-
let taskNotification = "";
|
|
738
|
-
if (taskId) {
|
|
739
|
-
taskNotification = `
|
|
740
|
-
|
|
741
|
-
---
|
|
742
|
-
\uD83D\uDCCB [委托任务完成] 已委托子智能体完成 Task #${taskId} 的处理工作,请知悉。可通过 task_get #${taskId} 查看最新状态。`;
|
|
743
|
-
}
|
|
744
|
-
setCurrentTaskId(undefined);
|
|
745
|
-
logger.info(`[delegate_task.sync] Task completed, currentTaskId cleared from EnvContext${taskId ? ` (was: #${taskId})` : ""}`);
|
|
746
|
-
return {
|
|
747
|
-
success: true,
|
|
748
|
-
output: result + taskNotification + `
|
|
749
|
-
|
|
750
|
-
` + [
|
|
751
|
-
"<task_metadata>",
|
|
752
|
-
`session_id: ${subSession.id}`,
|
|
753
|
-
`subagent_type: ${subagentType}`,
|
|
754
|
-
"</task_metadata>"
|
|
755
|
-
].join(`
|
|
756
|
-
`),
|
|
757
|
-
metadata: {
|
|
758
|
-
execution_time_ms: Date.now() - startTime,
|
|
759
|
-
sessionId: subSession.id
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
} catch (error) {
|
|
763
|
-
setCurrentTaskId(undefined);
|
|
764
|
-
logger.info(`[delegate_task.sync] Error occurred, currentTaskId cleared from EnvContext${taskId ? ` (was: #${taskId})` : ""}`);
|
|
765
|
-
return {
|
|
766
|
-
success: false,
|
|
767
|
-
output: "",
|
|
768
|
-
error: error instanceof Error ? error.message : String(error),
|
|
769
|
-
metadata: { execution_time_ms: Date.now() - startTime }
|
|
770
|
-
};
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
async function handleBackgroundTask(taskComponent, backgroundTaskManager, parentSessionId, description, prompt, subagentType, timeout, cleanup, taskId) {
|
|
652
|
+
async function handleBackgroundTask(backgroundTaskManager, parentSessionId, description, prompt, subagentType, timeout) {
|
|
774
653
|
const startTime = Date.now();
|
|
775
654
|
try {
|
|
776
|
-
|
|
777
|
-
if (!associatedTaskId) {
|
|
778
|
-
const newTask = await taskComponent.createTask({
|
|
779
|
-
title: description,
|
|
780
|
-
description: `Background task delegated to ${subagentType} subagent`,
|
|
781
|
-
priority: "medium",
|
|
782
|
-
goals_and_expected_deliverables: prompt,
|
|
783
|
-
sessionId: parentSessionId,
|
|
784
|
-
project_path: "unknown",
|
|
785
|
-
context: "unknown"
|
|
786
|
-
});
|
|
787
|
-
associatedTaskId = newTask.id;
|
|
788
|
-
await taskComponent.createOperation({
|
|
789
|
-
taskId: associatedTaskId,
|
|
790
|
-
sessionId: parentSessionId,
|
|
791
|
-
actionType: "create",
|
|
792
|
-
actionTitle: `Delegated to ${subagentType} subagent`,
|
|
793
|
-
actionDescription: `Background task started: ${description}`
|
|
794
|
-
});
|
|
795
|
-
} else {
|
|
796
|
-
await taskComponent.updateTask(associatedTaskId, {
|
|
797
|
-
status: "active",
|
|
798
|
-
current_status: `Running ${subagentType} subagent`
|
|
799
|
-
});
|
|
800
|
-
await taskComponent.createOperation({
|
|
801
|
-
taskId: associatedTaskId,
|
|
802
|
-
sessionId: parentSessionId,
|
|
803
|
-
actionType: "progress",
|
|
804
|
-
actionTitle: `Started ${subagentType} subagent`,
|
|
805
|
-
actionDescription: `Background task: ${description}`
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
const { taskId: bgTaskId, subSessionId } = await backgroundTaskManager.createTask({
|
|
655
|
+
const { taskId: bgProcessId, subSessionId } = await backgroundTaskManager.createTask({
|
|
809
656
|
parentSessionId,
|
|
810
657
|
description,
|
|
811
658
|
prompt,
|
|
812
659
|
subagentType,
|
|
813
|
-
timeout
|
|
814
|
-
cleanup,
|
|
815
|
-
taskId: associatedTaskId
|
|
660
|
+
timeout
|
|
816
661
|
});
|
|
817
662
|
const output = [
|
|
818
663
|
`✅ Background task accepted`,
|
|
819
664
|
"",
|
|
820
|
-
`\uD83D\uDCCB
|
|
665
|
+
`\uD83D\uDCCB Process ID: ${bgProcessId}`,
|
|
821
666
|
`\uD83D\uDCDD Description: ${description}`,
|
|
822
667
|
`\uD83E\uDD16 Sub-agent: ${subagentType}`,
|
|
823
|
-
associatedTaskId ? `\uD83D\uDCCC Associated Task: #${associatedTaskId}` : "",
|
|
824
668
|
`⏱️ Timeout: ${(timeout || DEFAULT_TIMEOUT) / 1000}s`,
|
|
825
669
|
"",
|
|
826
|
-
`Use stop_task with task_id="${
|
|
827
|
-
].
|
|
670
|
+
`Use stop_task with task_id="${bgProcessId}" to cancel this task.`
|
|
671
|
+
].join(`
|
|
828
672
|
`);
|
|
829
673
|
return {
|
|
830
674
|
success: true,
|
|
@@ -834,8 +678,7 @@ async function handleBackgroundTask(taskComponent, backgroundTaskManager, parent
|
|
|
834
678
|
sessionId: subSessionId,
|
|
835
679
|
background: true,
|
|
836
680
|
status: "accepted",
|
|
837
|
-
|
|
838
|
-
bgTaskId
|
|
681
|
+
bgProcessId
|
|
839
682
|
}
|
|
840
683
|
};
|
|
841
684
|
} catch (error) {
|
|
@@ -572,6 +572,7 @@ class AgentComponent extends BaseComponent {
|
|
|
572
572
|
const parentEnvContext = getEnvContext();
|
|
573
573
|
const envContext = {
|
|
574
574
|
...parentEnvContext,
|
|
575
|
+
agentContext: parentEnvContext?.agentContext ?? {},
|
|
575
576
|
traceId: effectiveContext.metadata?.traceId,
|
|
576
577
|
sessionId: effectiveContext.sessionId,
|
|
577
578
|
userId: effectiveContext.metadata?.userId ?? "",
|
|
@@ -339,7 +339,7 @@ class FileSource {
|
|
|
339
339
|
}
|
|
340
340
|
try {
|
|
341
341
|
this.watcherHandle = fsSync.watch(this.filePath, async (eventType) => {
|
|
342
|
-
if (eventType === "change") {
|
|
342
|
+
if (eventType === "change" || eventType === "rename") {
|
|
343
343
|
await new Promise((r) => setTimeout(r, 50));
|
|
344
344
|
await this.reloadFromFile();
|
|
345
345
|
}
|
|
@@ -163,18 +163,21 @@ var builtInPrompts = {
|
|
|
163
163
|
|
|
164
164
|
**roy** 的提示词中内置了任务生命周期——它知道如何使用 \`task_create\`、\`task_update\`、\`task_operation_create\` 和 \`task_complete\` 来跟踪每项工作。
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
推荐使用:
|
|
167
167
|
\`\`\`
|
|
168
168
|
delegate_task(
|
|
169
169
|
description="简要 3-5 字摘要",
|
|
170
170
|
prompt="详细说明。
|
|
171
171
|
|
|
172
172
|
重要:遵循任务作为一等公民原则 — 使用 \`task_create\` 创建任务,使用 \`task_update\` 跟踪进度,使用 \`task_operation_create\` 记录里程碑,并使用 \`task_complete\` 完成任务。",
|
|
173
|
-
subagent_type="roy"
|
|
174
|
-
background=true
|
|
173
|
+
subagent_type="roy"
|
|
175
174
|
)
|
|
176
175
|
\`\`\`
|
|
177
176
|
|
|
177
|
+
> **提示**:\`delegate_task\` 现在**总是后台模式**,立即返回。父 agent 通过返回的 \`task_id\` 用 \`task_get\` 查询进度。
|
|
178
|
+
> - delegate_task 内部自动创建关联 Task,调用方无需传入 \`task_id\`
|
|
179
|
+
> - sub-session 始终保留(不会自动删除),可通过 \`session_get\` 查看完整执行日志
|
|
180
|
+
|
|
178
181
|
### \uD83E\uDD48 次选:\`strict-task-agent\`(需要严格验证时使用)
|
|
179
182
|
结构化 Plan → Execute → Verify 工作流智能体,内置自动重试(最多 8 次)。在以下情况使用:
|
|
180
183
|
- **复杂功能开发** — 需要严格的 Plan→Execute→Verify 纪律
|
|
@@ -468,7 +471,7 @@ roy-agent <command> <subcmd> --help
|
|
|
468
471
|
| \`task_list\` | List tasks with optional filters for status/priority |
|
|
469
472
|
| \`task_complete\` | Mark a task as completed (progress=100, status=completed). Creates an operation record. |
|
|
470
473
|
| \`task_delete\` | Delete a task and all its operation records |
|
|
471
|
-
| \`delegate_task\` | Delegate complex tasks to a sub-agent (
|
|
474
|
+
| \`delegate_task\` | Delegate complex tasks to a sub-agent (always background mode) |
|
|
472
475
|
| \`stop_task\` | Stop a running background task |
|
|
473
476
|
| \`task_operation_create\` | Create operation records to track progress/milestones |
|
|
474
477
|
| \`task_operation_list\` | List operation records for a task |
|
|
@@ -510,9 +513,8 @@ Follow this lifecycle for every task:
|
|
|
510
513
|
↓
|
|
511
514
|
┌─────────────────────────────────────────────────────────────────┐
|
|
512
515
|
│ 3. EXECUTE (delegate_task) │
|
|
513
|
-
│ -
|
|
514
|
-
│ -
|
|
515
|
-
│ tasks to avoid blocking │
|
|
516
|
+
│ - delegate_task 总是后台执行,立即返回 │
|
|
517
|
+
│ - 通过返回的 task_id 主动用 task_get 查询进度 │
|
|
516
518
|
│ │
|
|
517
519
|
│ Background mode is recommended when: │
|
|
518
520
|
│ - Task duration > 5 minutes │
|