@ai-setting/roy-agent-core 1.6.1 → 1.6.3

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 (36) hide show
  1. package/dist/env/agent/index.js +3 -3
  2. package/dist/env/event-source/index.js +3 -3
  3. package/dist/env/index.js +15 -14
  4. package/dist/env/llm/index.js +2 -2
  5. package/dist/env/prompt/index.js +2 -2
  6. package/dist/env/task/delegate/index.js +2 -2
  7. package/dist/env/task/index.js +4 -3
  8. package/dist/env/task/plugins/index.js +2 -2
  9. package/dist/env/tool/built-in/index.js +7 -1
  10. package/dist/env/tool/index.js +3 -2
  11. package/dist/env/workflow/engine/index.js +3 -3
  12. package/dist/env/workflow/index.js +5 -5
  13. package/dist/env/workflow/nodes/index.js +1 -1
  14. package/dist/env/workflow/tools/index.js +1 -1
  15. package/dist/index.js +18 -17
  16. package/dist/shared/@ai-setting/{roy-agent-core-fg5eaht3.js → roy-agent-core-155408xq.js} +1 -1
  17. package/dist/shared/@ai-setting/{roy-agent-core-q79q54x2.js → roy-agent-core-45tvcwwz.js} +1 -1
  18. package/dist/shared/@ai-setting/{roy-agent-core-j7jeqxhd.js → roy-agent-core-65qs21kf.js} +3 -3
  19. package/dist/shared/@ai-setting/{roy-agent-core-a8pm6hya.js → roy-agent-core-6kygfd9x.js} +9 -0
  20. package/dist/shared/@ai-setting/{roy-agent-core-8cezq5x9.js → roy-agent-core-6ve6tsm5.js} +1 -1
  21. package/dist/shared/@ai-setting/{roy-agent-core-415rxkzy.js → roy-agent-core-78m47x1d.js} +56 -28
  22. package/dist/shared/@ai-setting/{roy-agent-core-mnc0hy7j.js → roy-agent-core-7afcdb2m.js} +17 -6
  23. package/dist/shared/@ai-setting/{roy-agent-core-84ex7khq.js → roy-agent-core-8mqahsj5.js} +3 -3
  24. package/dist/shared/@ai-setting/roy-agent-core-amkqnyzy.js +145 -0
  25. package/dist/shared/@ai-setting/{roy-agent-core-vrn9qj8y.js → roy-agent-core-anhvbnrc.js} +20 -1
  26. package/dist/shared/@ai-setting/{roy-agent-core-9gde0s9d.js → roy-agent-core-ba6243hr.js} +1 -1
  27. package/dist/shared/@ai-setting/{roy-agent-core-2vhsccvz.js → roy-agent-core-caevk7xd.js} +10 -0
  28. package/dist/shared/@ai-setting/{roy-agent-core-skfr9wjk.js → roy-agent-core-g7hfkszj.js} +1 -1
  29. package/dist/shared/@ai-setting/{roy-agent-core-84aqc5c0.js → roy-agent-core-pr7f94gn.js} +15 -1
  30. package/dist/shared/@ai-setting/{roy-agent-core-npkwftxj.js → roy-agent-core-r3209bcd.js} +5 -1
  31. package/dist/shared/@ai-setting/{roy-agent-core-q8n1s1pb.js → roy-agent-core-vf72n6qn.js} +4 -1
  32. package/dist/shared/@ai-setting/{roy-agent-core-txk4gcwm.js → roy-agent-core-xnga0ksx.js} +9 -4
  33. package/dist/shared/@ai-setting/{roy-agent-core-fzkfkd28.js → roy-agent-core-xxfkvqqh.js} +57 -19
  34. package/dist/shared/@ai-setting/{roy-agent-core-57bmm0a1.js → roy-agent-core-y1m7c2v7.js} +1 -1
  35. package/dist/shared/@ai-setting/{roy-agent-core-8cwb4fmp.js → roy-agent-core-z9m38ytb.js} +178 -26
  36. package/package.json +1 -1
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  AgentComponentAdapter,
9
9
  init_agent_component_adapter
10
- } from "./roy-agent-core-q8n1s1pb.js";
10
+ } from "./roy-agent-core-vf72n6qn.js";
11
11
  import {
12
12
  TemplateResolver,
13
13
  init_template_resolver
@@ -19,7 +19,7 @@ import {
19
19
  init_skill_node,
20
20
  init_tool_node,
21
21
  init_workflow_node
22
- } from "./roy-agent-core-9gde0s9d.js";
22
+ } from "./roy-agent-core-ba6243hr.js";
23
23
  import {
24
24
  WorkflowError,
25
25
  createWorkflowEvent,
@@ -416,14 +416,17 @@ var init_executor = __esm(() => {
416
416
  await this.writeNodeStart(context.sessionId, nodeId, nodeType, context.input, agentSessionId);
417
417
  const abortController = new AbortController;
418
418
  this.abortControllers.set(nodeId, abortController);
419
- const timeout = definition.timeout ?? this.options.globalTimeout ?? undefined;
419
+ context.abortSignal ??= abortController.signal;
420
+ const ctxCfg = context.config;
421
+ const cfgTimeout = ctxCfg && typeof ctxCfg.timeout === "number" && ctxCfg.timeout > 0 ? ctxCfg.timeout : undefined;
422
+ const timeout = definition.timeout ?? cfgTimeout ?? this.options.globalTimeout ?? undefined;
420
423
  const retryConfig = definition.retry ?? this.options.globalRetry;
421
424
  try {
422
425
  let result;
423
426
  if (retryConfig && retryConfig.max_attempts > 1) {
424
- result = await this.executeWithRetry(definition, context, abortController.signal, timeout);
427
+ result = await this.executeWithRetry(definition, context, abortController, timeout);
425
428
  } else {
426
- result = await this.executeWithTimeout(definition, context, abortController.signal, timeout);
429
+ result = await this.executeWithTimeout(definition, context, abortController, timeout);
427
430
  }
428
431
  if (result.error instanceof AskUserError) {
429
432
  const interruptEvent = createNodeInterruptEvent(context.runId, nodeId, nodeType, result.error.query, result.error.agentSessionId || agentSessionId);
@@ -455,7 +458,7 @@ var init_executor = __esm(() => {
455
458
  this.abortControllers.delete(nodeId);
456
459
  }
457
460
  }
458
- async executeWithTimeout(definition, context, signal, timeout) {
461
+ async executeWithTimeout(definition, context, abortController, timeout) {
459
462
  const startTime = Date.now();
460
463
  const nodeContext = {
461
464
  runId: context.runId,
@@ -464,9 +467,13 @@ var init_executor = __esm(() => {
464
467
  debug: context.debug
465
468
  };
466
469
  const node = this.nodeRegistry.createNode(definition, nodeContext);
470
+ const signal = abortController.signal;
467
471
  if (timeout) {
468
472
  const timeoutPromise = new Promise((_, reject) => {
469
473
  const handle = setTimeout(() => {
474
+ if (!abortController.signal.aborted) {
475
+ abortController.abort(new Error(`Node execution timeout: ${timeout}ms`));
476
+ }
470
477
  reject(new Error(`Node execution timeout: ${timeout}ms`));
471
478
  }, timeout);
472
479
  signal.addEventListener("abort", () => clearTimeout(handle));
@@ -510,10 +517,11 @@ var init_executor = __esm(() => {
510
517
  }
511
518
  }
512
519
  }
513
- async executeWithRetry(definition, context, signal, timeout) {
520
+ async executeWithRetry(definition, context, abortController, timeout) {
514
521
  const retryConfig = definition.retry;
515
522
  let lastError;
516
523
  let delay = retryConfig.initial_delay;
524
+ const signal = abortController.signal;
517
525
  for (let attempt = 1;attempt <= retryConfig.max_attempts; attempt++) {
518
526
  if (signal.aborted) {
519
527
  return {
@@ -524,8 +532,25 @@ var init_executor = __esm(() => {
524
532
  }
525
533
  const attemptAbort = new AbortController;
526
534
  const combinedSignal = this.combineAbortSignals(signal, attemptAbort.signal);
535
+ const combinedController = new AbortController;
536
+ combinedSignal.addEventListener("abort", () => {
537
+ if (!combinedController.signal.aborted) {
538
+ combinedController.abort(combinedSignal.reason);
539
+ }
540
+ });
541
+ const attemptAbortController = {
542
+ get signal() {
543
+ return combinedSignal;
544
+ },
545
+ abort: (reason) => {
546
+ attemptAbort.abort(reason);
547
+ if (!combinedController.signal.aborted) {
548
+ combinedController.abort(reason);
549
+ }
550
+ }
551
+ };
527
552
  try {
528
- const result = await this.executeWithTimeout(definition, context, combinedSignal, timeout);
553
+ const result = await this.executeWithTimeout(definition, context, attemptAbortController, timeout);
529
554
  if (!result.error) {
530
555
  return result;
531
556
  }
@@ -991,6 +1016,8 @@ var init_agent_node = __esm(() => {
991
1016
  const agentName = config.agent_name || undefined;
992
1017
  const options = config.options || {};
993
1018
  const outputConfig = parseAgentOutputConfig(config);
1019
+ const flatTimeout = typeof config.timeout === "number" && config.timeout > 0 ? config.timeout : undefined;
1020
+ const resolvedTimeout = flatTimeout ?? options.timeout;
994
1021
  let resolvedPrompt;
995
1022
  if (context.resolvedConfig && context.templateResolver) {
996
1023
  resolvedPrompt = config.prompt || "";
@@ -1044,7 +1071,7 @@ var init_agent_node = __esm(() => {
1044
1071
  type: resolvedAgentType,
1045
1072
  prompt: resolvedPrompt,
1046
1073
  options: {
1047
- timeout: options.timeout,
1074
+ timeout: resolvedTimeout,
1048
1075
  model: effectiveModel,
1049
1076
  allowedTools: effectiveAllowedTools,
1050
1077
  deniedTools: effectiveDeniedTools,
@@ -1058,7 +1085,12 @@ var init_agent_node = __esm(() => {
1058
1085
  userQuery,
1059
1086
  agentSessionId
1060
1087
  };
1061
- const result = await this.agentRunner.run(agentConfig, resumeOptions);
1088
+ let result;
1089
+ if (context.abortSignal) {
1090
+ result = await this.agentRunner.run(agentConfig, resumeOptions, context.abortSignal);
1091
+ } else {
1092
+ result = await this.agentRunner.run(agentConfig, resumeOptions);
1093
+ }
1062
1094
  const duration = Date.now() - startTime;
1063
1095
  return {
1064
1096
  output: buildAgentNodeOutput(result, outputConfig),
@@ -1433,9 +1465,6 @@ var init_engine = __esm(() => {
1433
1465
  if (metadata.status === "completed") {
1434
1466
  return { runId: this.getRunIdFromSessionId(sessionId), status: "completed" };
1435
1467
  }
1436
- if (metadata.status === "failed") {
1437
- return { runId: this.getRunIdFromSessionId(sessionId), status: "failed" };
1438
- }
1439
1468
  if (options?.input && this.sessionComponent) {
1440
1469
  const hasNewInput = typeof options.input === "string" ? options.input !== undefined && options.input !== "" : Object.keys(options.input).length > 0;
1441
1470
  if (hasNewInput) {
@@ -1457,7 +1486,7 @@ var init_engine = __esm(() => {
1457
1486
  extractResumeInfo,
1458
1487
  enrichResumeInfoWithAgentSessions,
1459
1488
  enrichResumePointWithAgentSessions
1460
- } = await import("./roy-agent-core-2vhsccvz.js");
1489
+ } = await import("./roy-agent-core-caevk7xd.js");
1461
1490
  const entry = workflowDef.entry;
1462
1491
  const entryNode = Array.isArray(entry) ? entry[0] : entry;
1463
1492
  const agentSessions = metadata.agentSessions ?? [];
@@ -1496,7 +1525,7 @@ var init_engine = __esm(() => {
1496
1525
  persistedInput = rest;
1497
1526
  }
1498
1527
  }
1499
- const { stripEphemeralResumeInput } = await import("./roy-agent-core-2vhsccvz.js");
1528
+ const { stripEphemeralResumeInput } = await import("./roy-agent-core-caevk7xd.js");
1500
1529
  const { workflowInput: runtimeInput } = stripEphemeralResumeInput(rawRuntimeInput);
1501
1530
  const defaultsFromSchema = {};
1502
1531
  if (definition.inputs) {
@@ -1515,7 +1544,8 @@ var init_engine = __esm(() => {
1515
1544
  strict: options?.strict ?? definition.config?.strict ?? false,
1516
1545
  maxIterations: options?.maxIterations ?? definition.config?.maxIterations ?? 100,
1517
1546
  loopEnabled,
1518
- workflowInput
1547
+ workflowInput,
1548
+ nodeConfig: options?.nodeConfig ?? {}
1519
1549
  };
1520
1550
  const abortController = new AbortController;
1521
1551
  let resolveCompleted;
@@ -1691,6 +1721,8 @@ var init_engine = __esm(() => {
1691
1721
  status: "paused",
1692
1722
  pendingNodeId: event.node_id,
1693
1723
  pauseReason: "ask_user",
1724
+ pendingAskUserQuery: event.query,
1725
+ pendingAskUserAgentSessionId: event.agent_session_id,
1694
1726
  agentSessions
1695
1727
  }
1696
1728
  });
@@ -1712,7 +1744,7 @@ var init_engine = __esm(() => {
1712
1744
  async scheduleAndExecute(sessionState, options) {
1713
1745
  const { scheduler, executor, eventBus, abortController, nodeOutputs } = sessionState;
1714
1746
  const { input: globalInput, pendingNodeId, agentSessionId, restoredOutputs } = options || {};
1715
- const { stripEphemeralResumeInput } = await import("./roy-agent-core-2vhsccvz.js");
1747
+ const { stripEphemeralResumeInput } = await import("./roy-agent-core-caevk7xd.js");
1716
1748
  const { workflowInput: inputToPersist, userQuery: resumeUserQuery } = stripEphemeralResumeInput(globalInput);
1717
1749
  if (inputToPersist) {
1718
1750
  sessionState.config.workflowInput = {
@@ -1854,7 +1886,7 @@ var init_engine = __esm(() => {
1854
1886
  if (!agentSessionId && this.sessionComponent) {
1855
1887
  const session = await this.sessionComponent.get(sessionId);
1856
1888
  const agentSessions = session?.metadata?.agentSessions;
1857
- const { resolveAgentSessionId } = await import("./roy-agent-core-2vhsccvz.js");
1889
+ const { resolveAgentSessionId } = await import("./roy-agent-core-caevk7xd.js");
1858
1890
  agentSessionId = resolveAgentSessionId(nodeId, undefined, agentSessions);
1859
1891
  }
1860
1892
  await sessionState.executor.writeNodeResume(sessionId, nodeId, nodeDef.type, options?.userQuery ?? "", agentSessionId);
@@ -1996,6 +2028,8 @@ var init_engine = __esm(() => {
1996
2028
  const askUser = (query) => {
1997
2029
  throw new AskUserError(runId, sessionState.sessionId, nodeId, nodeDef.type, query);
1998
2030
  };
2031
+ const nodeConfigOverride = sessionState.config.nodeConfig?.[nodeId];
2032
+ const effectiveConfig = nodeConfigOverride ? { ...nodeDef.config ?? {}, ...nodeConfigOverride } : nodeDef.config ?? {};
1999
2033
  const context = {
2000
2034
  runId,
2001
2035
  sessionId: sessionState.sessionId,
@@ -2003,7 +2037,7 @@ var init_engine = __esm(() => {
2003
2037
  nodeId,
2004
2038
  input,
2005
2039
  previousOutputs: sessionState.nodeOutputs,
2006
- config: nodeDef.config ?? {},
2040
+ config: effectiveConfig,
2007
2041
  debug: sessionState.config.debug,
2008
2042
  eventBus: sessionState.eventBus,
2009
2043
  nodeOutputs: sessionState.nodeOutputs,
@@ -2015,7 +2049,7 @@ var init_engine = __esm(() => {
2015
2049
  },
2016
2050
  workflowInput,
2017
2051
  templateResolver,
2018
- resolvedConfig: templateResolver.resolveValue(nodeDef.config ?? {})
2052
+ resolvedConfig: templateResolver.resolveValue(effectiveConfig)
2019
2053
  };
2020
2054
  return context;
2021
2055
  }
@@ -2037,16 +2071,10 @@ var init_engine = __esm(() => {
2037
2071
  const durationMs = Date.now() - sessionState.startedAt.getTime();
2038
2072
  const sessionId = sessionState.sessionId;
2039
2073
  const runId = this.getRunIdFromSessionId(sessionId);
2040
- const dagAnalysis = sessionState.dagManager.analyze();
2041
- const exitNodes = new Set(dagAnalysis.exitNodes);
2042
- const exitOutput = {};
2074
+ const finalOutput = {};
2043
2075
  for (const [nodeId, nodeOutput] of sessionState.nodeOutputs) {
2044
- if (exitNodes.has(nodeId)) {
2045
- exitOutput[nodeId] = nodeOutput;
2046
- }
2076
+ finalOutput[nodeId] = nodeOutput;
2047
2077
  }
2048
- const singleExit = exitNodes.size === 1 ? Array.from(exitNodes)[0] : undefined;
2049
- const finalOutput = singleExit && exitOutput[singleExit] !== undefined ? exitOutput[singleExit] : exitOutput;
2050
2078
  const allNodeOutputs = {};
2051
2079
  for (const [nodeId, nodeOutput] of sessionState.nodeOutputs) {
2052
2080
  allNodeOutputs[nodeId] = nodeOutput;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./roy-agent-core-pzeexnhf.js";
5
5
  import {
6
6
  builtInPrompts
7
- } from "./roy-agent-core-8cwb4fmp.js";
7
+ } from "./roy-agent-core-z9m38ytb.js";
8
8
  import {
9
9
  DEFAULT_SUBAGENT_PROMPT
10
10
  } from "./roy-agent-core-as3phr7n.js";
@@ -349,6 +349,7 @@ class BackgroundTaskManager {
349
349
  const abortController = new AbortController;
350
350
  const processRegistry = new ProcessRegistry;
351
351
  this.processRegistries.set(taskIdGen, processRegistry);
352
+ const createdAt = Date.now();
352
353
  const task = {
353
354
  id: taskIdGen,
354
355
  subSessionId: subSession.id,
@@ -356,7 +357,8 @@ class BackgroundTaskManager {
356
357
  description,
357
358
  subagentType,
358
359
  status: "pending",
359
- createdAt: Date.now(),
360
+ createdAt,
361
+ lastUpdatedAt: createdAt,
360
362
  abortController,
361
363
  similarTaskIds
362
364
  };
@@ -384,8 +386,10 @@ class BackgroundTaskManager {
384
386
  logger.warn(`[BackgroundTaskManager] executeTask: Task not found`, { taskId });
385
387
  return;
386
388
  }
389
+ const startedAt = Date.now();
387
390
  task.status = "running";
388
- task.startedAt = Date.now();
391
+ task.startedAt = startedAt;
392
+ task.lastUpdatedAt = startedAt;
389
393
  const timeoutMs = timeout || DEFAULT_TIMEOUT;
390
394
  const abortController = this.abortControllers.get(taskId);
391
395
  this.startProgressReporter(taskId, parentSessionId || task.parentSessionId);
@@ -401,8 +405,10 @@ class BackgroundTaskManager {
401
405
  logger.info(`[BackgroundTaskManager] Task was aborted`, { taskId });
402
406
  return;
403
407
  }
408
+ const completedAt = Date.now();
404
409
  task.status = "completed";
405
- task.completedAt = Date.now();
410
+ task.completedAt = completedAt;
411
+ task.lastUpdatedAt = completedAt;
406
412
  task.result = result;
407
413
  const executionTimeMs = task.completedAt - task.startedAt;
408
414
  task.associatedTaskId = getCurrentTaskId();
@@ -431,6 +437,9 @@ class BackgroundTaskManager {
431
437
  const errorMessage = error instanceof Error ? error.message : String(error);
432
438
  const isStoppedError = errorMessage.toLowerCase().includes("stopped") || errorMessage.toLowerCase().includes("aborted");
433
439
  const executionTimeMs = task.startedAt ? Date.now() - task.startedAt : 0;
440
+ const completedAt = Date.now();
441
+ task.completedAt = completedAt;
442
+ task.lastUpdatedAt = completedAt;
434
443
  task.associatedTaskId = getCurrentTaskId();
435
444
  if (isStoppedError) {
436
445
  task.status = "stopped";
@@ -472,7 +481,6 @@ class BackgroundTaskManager {
472
481
  this.publishBackgroundEvent(BackgroundTaskEventTypes.FAILED, failedPayload, parentSessionId || task.parentSessionId);
473
482
  }
474
483
  task.error = errorMessage;
475
- task.completedAt = Date.now();
476
484
  logger.error(`[BackgroundTaskManager] Task execution error`, {
477
485
  taskId,
478
486
  status: task.status,
@@ -493,6 +501,7 @@ class BackgroundTaskManager {
493
501
  if (currentTaskId !== undefined) {
494
502
  task.associatedTaskId = currentTaskId;
495
503
  }
504
+ task.lastUpdatedAt = Date.now();
496
505
  const progressPayload = {
497
506
  backgroundTaskId: taskId,
498
507
  subSessionId: task.subSessionId,
@@ -678,9 +687,11 @@ Use these as guidance to improve task execution efficiency.`;
678
687
  message: `Cannot stop task with status: ${task.status}`
679
688
  };
680
689
  }
690
+ const completedAt = Date.now();
681
691
  task.status = "stopped";
682
692
  task.abortController?.abort();
683
- task.completedAt = Date.now();
693
+ task.completedAt = completedAt;
694
+ task.lastUpdatedAt = completedAt;
684
695
  try {
685
696
  await this.processRegistries.get(taskId)?.killAll();
686
697
  } catch (err) {
@@ -6,7 +6,7 @@ import {
6
6
  WorkflowEngine,
7
7
  exports_engine,
8
8
  init_engine
9
- } from "./roy-agent-core-415rxkzy.js";
9
+ } from "./roy-agent-core-78m47x1d.js";
10
10
  import {
11
11
  askUserTool,
12
12
  createRunWorkflowTool,
@@ -18,7 +18,7 @@ import {
18
18
  createWorkflowSearchTool,
19
19
  createWorkflowTagListTool,
20
20
  createWorkflowValidateTool
21
- } from "./roy-agent-core-txk4gcwm.js";
21
+ } from "./roy-agent-core-xnga0ksx.js";
22
22
  import {
23
23
  WorkflowService
24
24
  } from "./roy-agent-core-b75jtybq.js";
@@ -141,7 +141,7 @@ class WorkflowComponent extends BaseComponent {
141
141
  if (!agentRunner && this._workflowEnv) {
142
142
  const agentComponent = this._workflowEnv.getComponent("agent");
143
143
  if (agentComponent) {
144
- const { AgentComponentAdapter } = await import("./roy-agent-core-57bmm0a1.js");
144
+ const { AgentComponentAdapter } = await import("./roy-agent-core-y1m7c2v7.js");
145
145
  agentRunner = new AgentComponentAdapter(agentComponent, {}, this.sessionComponent);
146
146
  }
147
147
  }
@@ -0,0 +1,145 @@
1
+ // src/env/tool/built-in/query-background-process-tool.ts
2
+ import { z } from "zod";
3
+ var QueryBackgroundProcessParameters = z.object({
4
+ bgProcessId: z.string().min(1, "bgProcessId must not be empty").describe("The background process ID returned by delegate_task " + "(format: process_<timestamp>_<random>).")
5
+ });
6
+ function backgroundTaskToOutput(task) {
7
+ return {
8
+ alive: task.status === "pending" || task.status === "running",
9
+ status: task.status,
10
+ createdAt: task.createdAt,
11
+ lastUpdatedAt: task.lastUpdatedAt ?? task.completedAt ?? task.startedAt ?? task.createdAt,
12
+ description: task.description,
13
+ ...task.result !== undefined ? { result: task.result } : {},
14
+ ...task.error !== undefined ? { error: task.error } : {}
15
+ };
16
+ }
17
+ function notFoundOutput(bgProcessId) {
18
+ const now = Date.now();
19
+ return {
20
+ alive: false,
21
+ status: "not_found",
22
+ createdAt: now,
23
+ lastUpdatedAt: now,
24
+ description: `No background process found with id '${bgProcessId}'.`
25
+ };
26
+ }
27
+ var queryBackgroundProcessTool = {
28
+ name: "query_background_process",
29
+ description: `Query the status of a background process previously launched via delegate_task.
30
+
31
+ ` + `Use this tool when:
32
+ ` + ` - You delegated a long-running task but have NOT received any notification after a reasonable wait (5+ minutes), and want to confirm whether the process is still alive.
33
+ ` + ` - The user asks about the progress of a delegated task and you need a current snapshot.
34
+ ` + ` - You suspect a delegated task got stuck (no progress messages, no completion notification).
35
+
36
+ ` + `DO NOT poll this tool on every turn — it is meant for diagnostic checks at a reasonable cadence (e.g. every few minutes, or when you genuinely suspect the task is stuck).
37
+
38
+ ` + `Returns a JSON object with:
39
+ ` + ` - alive: boolean — true if status is 'pending' or 'running'
40
+ ` + ` - status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout' | 'not_found'
41
+ ` + ` - createdAt, lastUpdatedAt: timestamps (ms)
42
+ ` + ` - description: the task description you passed to delegate_task
43
+ ` + ` - result: present when status is 'completed'
44
+ ` + ` - error: present when status is 'failed'
45
+
46
+ ` + "Only the default receptionist agent has this tool. Sub-agents (roy, strict-task-agent, etc.) cannot see it because they do not need to query background tasks they themselves launched.",
47
+ parameters: QueryBackgroundProcessParameters,
48
+ permission: {
49
+ level: "safe",
50
+ requireConfirmation: false
51
+ },
52
+ metadata: {
53
+ category: "task",
54
+ tags: ["background", "delegate", "query", "status", "diagnostic"],
55
+ version: "1.0.0",
56
+ allowedAgentTypes: ["default"]
57
+ },
58
+ execute: async (args, ctx) => createQueryBackgroundProcessTool(null).execute(args, ctx)
59
+ };
60
+ function createQueryBackgroundProcessTool(manager = null) {
61
+ return {
62
+ name: "query_background_process",
63
+ description: `Query the status of a background process previously launched via delegate_task.
64
+
65
+ ` + `Use this tool when:
66
+ ` + ` - You delegated a long-running task but have NOT received any notification after a reasonable wait (5+ minutes), and want to confirm whether the process is still alive.
67
+ ` + ` - The user asks about the progress of a delegated task and you need a current snapshot.
68
+ ` + ` - You suspect a delegated task got stuck (no progress messages, no completion notification).
69
+
70
+ ` + `DO NOT poll this tool on every turn — it is meant for diagnostic checks at a reasonable cadence (e.g. every few minutes, or when you genuinely suspect the task is stuck).
71
+
72
+ ` + `Returns a JSON object with:
73
+ ` + ` - alive: boolean — true if status is 'pending' or 'running'
74
+ ` + ` - status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout' | 'not_found'
75
+ ` + ` - createdAt, lastUpdatedAt: timestamps (ms)
76
+ ` + ` - description: the task description you passed to delegate_task
77
+ ` + ` - result: present when status is 'completed'
78
+ ` + ` - error: present when status is 'failed'
79
+
80
+ ` + "Only the default receptionist agent has this tool. Sub-agents (roy, strict-task-agent, etc.) cannot see it because they do not need to query background tasks they themselves launched.",
81
+ parameters: QueryBackgroundProcessParameters,
82
+ permission: {
83
+ level: "safe",
84
+ requireConfirmation: false
85
+ },
86
+ metadata: {
87
+ category: "task",
88
+ tags: ["background", "delegate", "query", "status", "diagnostic"],
89
+ version: "1.0.0",
90
+ allowedAgentTypes: ["default"]
91
+ },
92
+ execute: async (args, ctx) => {
93
+ const startTime = Date.now();
94
+ const params = QueryBackgroundProcessParameters.parse(args);
95
+ const { bgProcessId } = params;
96
+ if (!manager) {
97
+ return {
98
+ success: false,
99
+ output: "",
100
+ error: "query_background_process is not initialized: no BackgroundTaskManager " + "has been bound. TaskComponent should call " + "createQueryBackgroundProcessTool(manager) and register the tool " + "during startup.",
101
+ metadata: { execution_time_ms: Date.now() - startTime }
102
+ };
103
+ }
104
+ let task;
105
+ try {
106
+ task = manager.getTask(bgProcessId);
107
+ } catch (err) {
108
+ return {
109
+ success: false,
110
+ output: "",
111
+ error: `failed to query background task: ${err.message}`,
112
+ metadata: { execution_time_ms: Date.now() - startTime }
113
+ };
114
+ }
115
+ if (task) {
116
+ const currentSessionId = ctx.session_id;
117
+ if (!currentSessionId || task.parentSessionId !== currentSessionId) {
118
+ return {
119
+ success: true,
120
+ output: JSON.stringify(notFoundOutput(bgProcessId), null, 2),
121
+ metadata: {
122
+ execution_time_ms: Date.now() - startTime,
123
+ bgProcessId,
124
+ status: "not_found",
125
+ alive: false
126
+ }
127
+ };
128
+ }
129
+ }
130
+ const output = task ? backgroundTaskToOutput(task) : notFoundOutput(bgProcessId);
131
+ return {
132
+ success: true,
133
+ output: JSON.stringify(output, null, 2),
134
+ metadata: {
135
+ execution_time_ms: Date.now() - startTime,
136
+ bgProcessId,
137
+ status: output.status,
138
+ alive: output.alive
139
+ }
140
+ };
141
+ }
142
+ };
143
+ }
144
+
145
+ export { queryBackgroundProcessTool, createQueryBackgroundProcessTool };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAutoTaskPlugin
3
- } from "./roy-agent-core-8cezq5x9.js";
3
+ } from "./roy-agent-core-6ve6tsm5.js";
4
4
  import {
5
5
  ContextError,
6
6
  ErrorCodes
@@ -49,6 +49,15 @@ init_env_context();
49
49
  import * as fsSync from "fs";
50
50
  import * as path from "path";
51
51
  var logger = createLogger("environment");
52
+ var DEFAULT_AGENT_NAME = "Roy";
53
+ function injectAgentNamePlaceholder(prompt, context) {
54
+ if (!prompt.includes("{{agent_name}}")) {
55
+ return prompt;
56
+ }
57
+ const metadata = context?.metadata;
58
+ const defaultAgentName = typeof metadata?.defaultAgentName === "string" && metadata.defaultAgentName.length > 0 ? metadata.defaultAgentName : DEFAULT_AGENT_NAME;
59
+ return prompt.replace(/\{\{agent_name\}\}/g, defaultAgentName);
60
+ }
52
61
 
53
62
  class BaseEnvironment extends BaseComponent {
54
63
  name;
@@ -146,6 +155,15 @@ class BaseEnvironment extends BaseComponent {
146
155
  finalSystemPrompt = finalSystemPrompt.replace("{{workspace_dir}}", workspaceDir);
147
156
  logger.debug(`[handle_query] Injected workspace_dir: ${workspaceDir}`);
148
157
  }
158
+ {
159
+ const prev = finalSystemPrompt;
160
+ finalSystemPrompt = injectAgentNamePlaceholder(finalSystemPrompt, context);
161
+ if (prev !== finalSystemPrompt) {
162
+ const metadata = context?.metadata;
163
+ const injectedName = typeof metadata?.defaultAgentName === "string" && metadata.defaultAgentName.length > 0 ? metadata.defaultAgentName : DEFAULT_AGENT_NAME;
164
+ logger.debug(`[handle_query] Injected agent_name: ${injectedName}`);
165
+ }
166
+ }
149
167
  let agent = agentComponent.getAgent(agentName);
150
168
  if (!agent) {
151
169
  if (agentName !== "default") {
@@ -221,6 +239,7 @@ class BaseEnvironment extends BaseComponent {
221
239
  if (agent.config.systemPrompt.includes("{{workspace_dir}}")) {
222
240
  agent.config.systemPrompt = agent.config.systemPrompt.replace("{{workspace_dir}}", process.cwd());
223
241
  }
242
+ agent.config.systemPrompt = injectAgentNamePlaceholder(agent.config.systemPrompt, context);
224
243
  }
225
244
  logger.debug(`[handle_query] Injected memory/workspace_dir for existing agent: ${agentName}`);
226
245
  }
@@ -103,7 +103,7 @@ var init_tool_node = __esm(() => {
103
103
  nodeId: context.nodeId
104
104
  }
105
105
  };
106
- const toolTimeoutMs = getToolTimeoutMs(input, this.definition.config);
106
+ const toolTimeoutMs = getToolTimeoutMs(input, config);
107
107
  const executePromise = tool.execute(input, toolContext);
108
108
  let timeoutHandle;
109
109
  const timeoutPromise = new Promise((_, reject) => {
@@ -28,6 +28,16 @@ function inferNextNode(messages, definition) {
28
28
  };
29
29
  case "workflow.node.end":
30
30
  case "workflow.node.result":
31
+ if (metadata?.success === false) {
32
+ const failedNodeId = getWorkflowNodeIdFromMetadata(metadata);
33
+ if (failedNodeId) {
34
+ return {
35
+ type: "resume_node",
36
+ nodeId: failedNodeId,
37
+ agentSessionId: metadata.agentSessionId
38
+ };
39
+ }
40
+ }
31
41
  return getNextNodes(getWorkflowNodeIdFromMetadata(metadata), definition);
32
42
  default:
33
43
  const lastStart = findLastStartMessage(messages);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtInPrompts
3
- } from "./roy-agent-core-8cwb4fmp.js";
3
+ } from "./roy-agent-core-z9m38ytb.js";
4
4
  import {
5
5
  getXDGPath
6
6
  } from "./roy-agent-core-qxnbvgwe.js";
@@ -1,3 +1,6 @@
1
+ import {
2
+ createQueryBackgroundProcessTool
3
+ } from "./roy-agent-core-amkqnyzy.js";
1
4
  import {
2
5
  TaskEntityEventTypes
3
6
  } from "./roy-agent-core-8gxth0eh.js";
@@ -5,7 +8,7 @@ import {
5
8
  BackgroundTaskManager,
6
9
  createDelegateTool,
7
10
  createStopTool
8
- } from "./roy-agent-core-mnc0hy7j.js";
11
+ } from "./roy-agent-core-7afcdb2m.js";
9
12
  import {
10
13
  SQLiteTaskStore,
11
14
  getDefaultTaskDbPath
@@ -314,6 +317,8 @@ class TaskComponent extends BaseComponent {
314
317
  this.toolComponent = this.env?.getComponent("tool");
315
318
  if (this.toolComponent) {
316
319
  await this.registerTools();
320
+ this.toolComponent.register(createQueryBackgroundProcessTool(this.backgroundTaskManager), "built-in");
321
+ logger2.debug("[TaskComponent] Injected BackgroundTaskManager into query_background_process tool (factory pattern)");
317
322
  } else {
318
323
  logger2.warn("[TaskComponent] ToolComponent not found, skipping tool registration");
319
324
  }
@@ -323,8 +328,17 @@ class TaskComponent extends BaseComponent {
323
328
  this.configWatcher();
324
329
  this.configWatcher = undefined;
325
330
  }
331
+ if (this.toolComponent) {
332
+ try {
333
+ this.toolComponent.register(createQueryBackgroundProcessTool(null), "built-in");
334
+ logger2.debug("[TaskComponent] Reset query_background_process tool to no-manager default (cleanup)");
335
+ } catch (err) {
336
+ logger2.warn(`[TaskComponent] Failed to reset query_background_process tool: ${err.message}`);
337
+ }
338
+ }
326
339
  if (this.backgroundTaskManager) {
327
340
  this.backgroundTaskManager.dispose();
341
+ this.backgroundTaskManager = undefined;
328
342
  }
329
343
  if (this.store) {
330
344
  await this.store.close();
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  understandImageTool
3
3
  } from "./roy-agent-core-t7rw68q8.js";
4
+ import {
5
+ queryBackgroundProcessTool
6
+ } from "./roy-agent-core-amkqnyzy.js";
4
7
  import {
5
8
  getCurrentProcessRegistry,
6
9
  killProcessTree
@@ -929,7 +932,8 @@ function getAllBuiltInTools() {
929
932
  writeFileTool,
930
933
  editFileTool,
931
934
  grepTool,
932
- understandImageTool
935
+ understandImageTool,
936
+ queryBackgroundProcessTool
933
937
  ];
934
938
  }
935
939
  function getBuiltInTool(name) {
@@ -196,7 +196,7 @@ var init_agent_component_adapter = __esm(() => {
196
196
  this.agentSessionPrefixes.set(name, config.sessionIdPrefix);
197
197
  }
198
198
  }
199
- async run(config, resumeOptions) {
199
+ async run(config, resumeOptions, signal) {
200
200
  const startTime = Date.now();
201
201
  const nodeId = config.nodeId || "unknown";
202
202
  const runId = config.runId || "unknown";
@@ -248,6 +248,9 @@ var init_agent_component_adapter = __esm(() => {
248
248
  if (config.options?.timeout) {
249
249
  context.abort = new AbortController;
250
250
  }
251
+ if (signal) {
252
+ context.abort = signal;
253
+ }
251
254
  context.sessionId = agentSessionId;
252
255
  if (config.options?.allowedTools) {
253
256
  context.allowedTools = config.options.allowedTools;