@ai-setting/roy-agent-core 1.7.76 → 1.7.85

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 (82) hide show
  1. package/dist/config/config-protection.d.ts +89 -0
  2. package/dist/config/index.d.ts +1 -0
  3. package/dist/config/index.js +16 -0
  4. package/dist/env/agent/agent-component.d.ts +42 -21
  5. package/dist/env/agent/agent-component.js +3 -3
  6. package/dist/env/agent/index.js +3 -3
  7. package/dist/env/agent/types.d.ts +32 -12
  8. package/dist/env/error-reply.d.ts +6 -0
  9. package/dist/env/error-reply.js +1 -1
  10. package/dist/env/event-source/bounty-im-handler.d.ts +8 -0
  11. package/dist/env/event-source/es-command.d.ts +39 -0
  12. package/dist/env/event-source/es-plugins.d.ts +68 -0
  13. package/dist/env/event-source/event-source-component.d.ts +15 -0
  14. package/dist/env/event-source/event-source-handlers.d.ts +68 -0
  15. package/dist/env/event-source/event-source-handlers.js +22 -10
  16. package/dist/env/event-source/index.d.ts +5 -1
  17. package/dist/env/event-source/index.js +59 -10
  18. package/dist/env/event-source/types.d.ts +101 -1
  19. package/dist/env/event-source/wecom-card-action-handler.d.ts +141 -0
  20. package/dist/env/event-source/wecom-card-builder.d.ts +220 -0
  21. package/dist/env/event-source/wecom-cli-handler.d.ts +266 -0
  22. package/dist/env/event-source/wecom-cli-sender.d.ts +88 -0
  23. package/dist/env/event-source/wecom-media.d.ts +130 -0
  24. package/dist/env/event-source/wecom-respond-registry.d.ts +151 -0
  25. package/dist/env/event-source/wecom-ws-bridge.d.ts +213 -0
  26. package/dist/env/index.js +19 -17
  27. package/dist/env/task/backend/index.js +37 -1
  28. package/dist/env/task/backend/task-store-backend.d.ts +12 -0
  29. package/dist/env/task/backend/types.d.ts +19 -0
  30. package/dist/env/task/delegate/delegate-tool.d.ts +62 -2
  31. package/dist/env/task/delegate/delegate-tool.js +3 -1
  32. package/dist/env/task/delegate/index.js +1 -1
  33. package/dist/env/task/index.js +4 -4
  34. package/dist/env/task/mcp/index.js +3 -0
  35. package/dist/env/task/mcp/task-mcp-server.d.ts +1 -1
  36. package/dist/env/task/plugins/fake-user-message-helper.d.ts +10 -2
  37. package/dist/env/task/plugins/index.d.ts +3 -0
  38. package/dist/env/task/plugins/index.js +36 -4
  39. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +41 -2
  40. package/dist/env/task/plugins/lark-card-patch-notifier.js +1 -1
  41. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +16 -0
  42. package/dist/env/task/plugins/task-op-watermark-plugin.d.ts +112 -0
  43. package/dist/env/task/plugins/wecom-card-state-store.d.ts +121 -0
  44. package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +224 -0
  45. package/dist/env/task/storage/index.js +2 -2
  46. package/dist/env/task/storage/sqlite-task-store.d.ts +54 -0
  47. package/dist/env/task/task-component.d.ts +16 -0
  48. package/dist/env/task/tools/operation/operation-types.d.ts +13 -13
  49. package/dist/env/tool/built-in/index.d.ts +2 -0
  50. package/dist/env/tool/built-in/index.js +6 -1
  51. package/dist/env/tool/index.js +3 -2
  52. package/dist/env/workflow/index.js +3 -3
  53. package/dist/env/workflow/plugins/index.js +2 -2
  54. package/dist/env/workflow/tools/index.js +2 -2
  55. package/dist/env/workflow/types/event.d.ts +4 -4
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +71 -20
  58. package/dist/shared/@ai-setting/{roy-agent-core-v87njmq7.js → roy-agent-core-0dh8npnz.js} +1 -1
  59. package/dist/shared/@ai-setting/roy-agent-core-2stt4rp5.js +134 -0
  60. package/dist/shared/@ai-setting/{roy-agent-core-mww0mnd9.js → roy-agent-core-7bpj859q.js} +1 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-nmx9934r.js → roy-agent-core-7dd0s3xb.js} +15 -5
  62. package/dist/shared/@ai-setting/{roy-agent-core-ghnagzrh.js → roy-agent-core-b31v3qpv.js} +853 -48
  63. package/dist/shared/@ai-setting/{roy-agent-core-cxy143m4.js → roy-agent-core-begm7ytz.js} +63 -2
  64. package/dist/shared/@ai-setting/{roy-agent-core-aa2j7bk9.js → roy-agent-core-cha0jc7n.js} +40 -26
  65. package/dist/shared/@ai-setting/{roy-agent-core-p3zv1mx5.js → roy-agent-core-d1n4jbza.js} +1 -1
  66. package/dist/shared/@ai-setting/{roy-agent-core-q5r75vev.js → roy-agent-core-dkrvmjsh.js} +17 -75
  67. package/dist/shared/@ai-setting/{roy-agent-core-abqhkbn3.js → roy-agent-core-ezvpreqz.js} +23 -0
  68. package/dist/shared/@ai-setting/{roy-agent-core-99nwgj84.js → roy-agent-core-fzw9xzm1.js} +1 -1
  69. package/dist/shared/@ai-setting/roy-agent-core-h21gngxf.js +247 -0
  70. package/dist/shared/@ai-setting/roy-agent-core-m3vjepzz.js +544 -0
  71. package/dist/shared/@ai-setting/{roy-agent-core-zycadbpx.js → roy-agent-core-p6ks90tb.js} +1 -1
  72. package/dist/shared/@ai-setting/{roy-agent-core-ntq0gz7q.js → roy-agent-core-q813vafd.js} +1 -1
  73. package/dist/shared/@ai-setting/{roy-agent-core-z43aj03k.js → roy-agent-core-qk9hd89p.js} +21 -2
  74. package/dist/shared/@ai-setting/{roy-agent-core-6cy43nss.js → roy-agent-core-rykf7c04.js} +49 -9
  75. package/dist/shared/@ai-setting/{roy-agent-core-8ez6mccb.js → roy-agent-core-tk98f92b.js} +4 -0
  76. package/dist/shared/@ai-setting/{roy-agent-core-bxkjk7zx.js → roy-agent-core-vx8zc847.js} +4 -1
  77. package/dist/shared/@ai-setting/roy-agent-core-vyr6svt6.js +31 -0
  78. package/dist/shared/@ai-setting/{roy-agent-core-t3rrb959.js → roy-agent-core-xf6z96qy.js} +2086 -163
  79. package/package.json +10 -1
  80. package/dist/shared/@ai-setting/roy-agent-core-f77k3gqt.js +0 -71
  81. /package/dist/shared/@ai-setting/{roy-agent-core-b4x6x4k2.js → roy-agent-core-m1fgtnrc.js} +0 -0
  82. /package/dist/shared/@ai-setting/{roy-agent-core-v85n42ve.js → roy-agent-core-ze5cqpf2.js} +0 -0
@@ -1,6 +1,12 @@
1
1
  import {
2
2
  builtInHandlers
3
- } from "./roy-agent-core-t3rrb959.js";
3
+ } from "./roy-agent-core-xf6z96qy.js";
4
+ import {
5
+ appendAuditLog,
6
+ checkSourceCountDrop,
7
+ readSourceCountFromDisk,
8
+ snapshotConfigDir
9
+ } from "./roy-agent-core-2stt4rp5.js";
4
10
  import {
5
11
  envKeyToConfigKey
6
12
  } from "./roy-agent-core-7hh0brvs.js";
@@ -57,6 +63,23 @@ class EventSourceComponent extends BaseComponent {
57
63
  buffers = new Map;
58
64
  configPath = "";
59
65
  persistenceEnabled = true;
66
+ constructor() {
67
+ super();
68
+ this.applyTestEnvironmentGuard();
69
+ }
70
+ static isTestEnvironment() {
71
+ return "BUN_TEST_WORKER_ID" in process.env;
72
+ }
73
+ applyTestEnvironmentGuard() {
74
+ if (this.persistenceEnabled && EventSourceComponent.isTestEnvironment()) {
75
+ if (process.env.ROY_AGENT_ES_PERSISTENCE === "1") {
76
+ logger.debug("EventSource persistence opt-out active in test env (ROY_AGENT_ES_PERSISTENCE=1)");
77
+ return;
78
+ }
79
+ this.persistenceEnabled = false;
80
+ logger.debug("EventSource persistence disabled by test-environment guard (Task #5181)");
81
+ }
82
+ }
60
83
  configComponent;
61
84
  configWatcher;
62
85
  async onInit() {
@@ -86,6 +109,7 @@ class EventSourceComponent extends BaseComponent {
86
109
  }
87
110
  await this.onInit();
88
111
  this.setStatus("running");
112
+ this.applyTestEnvironmentGuard();
89
113
  }
90
114
  async onStart() {}
91
115
  async onStop() {
@@ -116,7 +140,7 @@ class EventSourceComponent extends BaseComponent {
116
140
  }
117
141
  }
118
142
  async executeInitHooks() {
119
- const { EventSourceInitHooks } = await import("./roy-agent-core-99nwgj84.js");
143
+ const { EventSourceInitHooks } = await import("./roy-agent-core-fzw9xzm1.js");
120
144
  await EventSourceInitHooks.execute(this);
121
145
  }
122
146
  registerHandler(handler) {
@@ -365,6 +389,17 @@ class EventSourceComponent extends BaseComponent {
365
389
  const eventHandler = this.eventHandlers.get(id) ?? this.createDefaultEventHandler(id, config.type);
366
390
  instance.onEvent(eventHandler);
367
391
  await instance.start();
392
+ const instanceStatus = instance.getStatus();
393
+ if (instanceStatus === "error") {
394
+ this.statuses.set(id, "error");
395
+ const reason = instance.getLastError?.() ?? `event source '${config.type}' failed to start`;
396
+ logger.error(`EventSource degraded to error state: ${id} (${config.type}) — ${reason}`);
397
+ this.getEnv()?.pushEnvEvent({
398
+ type: "event-source.error",
399
+ payload: { sourceId: id, sourceType: config.type, reason }
400
+ });
401
+ throw new Error(reason);
402
+ }
368
403
  this.statuses.set(id, "running");
369
404
  this.getEnv()?.pushEnvEvent({
370
405
  type: "event-source.started",
@@ -420,11 +455,37 @@ class EventSourceComponent extends BaseComponent {
420
455
  return;
421
456
  try {
422
457
  const configPath = this.getConfigFilePath();
458
+ const configDir = join(configPath, "..");
459
+ const diskCount = readSourceCountFromDisk(configPath);
460
+ const newCount = this.sources.size;
461
+ const dropCheck = checkSourceCountDrop(diskCount, newCount);
462
+ if (!dropCheck.allowed && process.env.ROY_AGENT_ES_FORCE_SAVE !== "1") {
463
+ appendAuditLog(configDir, {
464
+ file: "event-sources.json",
465
+ action: "drop-blocked",
466
+ detail: dropCheck.reason
467
+ });
468
+ logger.error(`Refusing to save event sources: ${dropCheck.reason}`);
469
+ throw new Error(`EventSource saveConfig blocked: ${dropCheck.reason}`);
470
+ }
471
+ const snapDir = snapshotConfigDir(configDir);
472
+ if (snapDir) {
473
+ appendAuditLog(configDir, {
474
+ file: "event-sources.json",
475
+ action: "pre-save-snapshot",
476
+ detail: `snapshot=${snapDir}`
477
+ });
478
+ }
423
479
  const config = {
424
480
  version: "1.0.0",
425
481
  sources: Array.from(this.sources.values())
426
482
  };
427
483
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
484
+ appendAuditLog(configDir, {
485
+ file: "event-sources.json",
486
+ action: "save",
487
+ detail: `${newCount} sources (disk had ${diskCount})`
488
+ });
428
489
  logger.debug(`Saved ${this.sources.size} event source configurations`);
429
490
  } catch (error) {
430
491
  logger.error("Failed to save event source configurations:", error);
@@ -1058,7 +1058,7 @@ class BackgroundTaskManager {
1058
1058
  return;
1059
1059
  }
1060
1060
  }
1061
- publishBackgroundEvent(type, payload, parentSessionId, triggerEventId, replyChannel) {
1061
+ publishBackgroundEvent(type, payload, parentSessionId, triggerEventId, replyChannel, pluginEnabledSnapshot) {
1062
1062
  if (this.env?.pushEnvEvent) {
1063
1063
  this.env.pushEnvEvent({
1064
1064
  type,
@@ -1067,7 +1067,8 @@ class BackgroundTaskManager {
1067
1067
  source: "task.background",
1068
1068
  trigger_session_id: parentSessionId,
1069
1069
  ...triggerEventId ? { triggerEventId } : {},
1070
- ...replyChannel ? { replyChannel } : {}
1070
+ ...replyChannel ? { replyChannel } : {},
1071
+ ...pluginEnabledSnapshot ? { pluginEnabled: pluginEnabledSnapshot } : {}
1071
1072
  }
1072
1073
  });
1073
1074
  logger3.info(`[BackgroundTaskManager] Event published: ${type}`, {
@@ -1076,8 +1077,8 @@ class BackgroundTaskManager {
1076
1077
  });
1077
1078
  }
1078
1079
  }
1079
- publishBackgroundEventWithTrigger(type, payload, parentSessionId, triggerEventId, replyChannel) {
1080
- this.publishBackgroundEvent(type, payload, parentSessionId, triggerEventId, replyChannel);
1080
+ publishBackgroundEventWithTrigger(type, payload, parentSessionId, triggerEventId, replyChannel, pluginEnabledSnapshot) {
1081
+ this.publishBackgroundEvent(type, payload, parentSessionId, triggerEventId, replyChannel, pluginEnabledSnapshot);
1081
1082
  }
1082
1083
  static parseAskUserErrorFromMessage(error) {
1083
1084
  const rawErrorMessage = error instanceof Error ? error.message : String(error);
@@ -1115,7 +1116,7 @@ class BackgroundTaskManager {
1115
1116
  return null;
1116
1117
  }
1117
1118
  async createTask(options) {
1118
- const { parentSessionId, description, prompt, subagentType, timeout, similarTaskIds, existingSubSessionId, triggerEventId, model, fallbackModel, fallbackModels } = options;
1119
+ const { parentSessionId, description, prompt, subagentType, timeout, similarTaskIds, existingSubSessionId, triggerEventId, model, fallbackModel, fallbackModels, systemPrompt } = options;
1119
1120
  const taskIdGen = `process_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
1120
1121
  const sessionComponent = this.getSessionComponent();
1121
1122
  if (!sessionComponent) {
@@ -1188,6 +1189,7 @@ class BackgroundTaskManager {
1188
1189
  }
1189
1190
  }
1190
1191
  const replyChannelSnapshot = captureReplyChannelSnapshot();
1192
+ const pluginEnabledSnapshot = capturePluginEnabledSnapshot();
1191
1193
  const abortController = new AbortController;
1192
1194
  if (this.processRegistries.size >= this.maxProcessRegistries) {
1193
1195
  this.cleanupEmptyProcessRegistries();
@@ -1216,7 +1218,9 @@ class BackgroundTaskManager {
1216
1218
  model,
1217
1219
  fallbackModel,
1218
1220
  fallbackModels,
1219
- replyChannel: replyChannelSnapshot
1221
+ systemPrompt,
1222
+ replyChannel: replyChannelSnapshot,
1223
+ pluginEnabledSnapshot
1220
1224
  };
1221
1225
  this.tasks.set(taskIdGen, task);
1222
1226
  this.abortControllers.set(taskIdGen, abortController);
@@ -1229,7 +1233,7 @@ class BackgroundTaskManager {
1229
1233
  startedAt: createdAt,
1230
1234
  timeoutMs: timeout || DEFAULT_TIMEOUT
1231
1235
  };
1232
- this.publishBackgroundEvent(BackgroundTaskEventTypes.STARTED, startedPayload, parentSessionId, triggerEventId, replyChannelSnapshot);
1236
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.STARTED, startedPayload, parentSessionId, triggerEventId, replyChannelSnapshot, task.pluginEnabledSnapshot);
1233
1237
  this.executeTask(taskIdGen, prompt, timeout, parentSessionId).catch((err) => {
1234
1238
  logger3.error(`[BackgroundTaskManager] executeTask unhandled rejection`, {
1235
1239
  taskId: taskIdGen,
@@ -1283,7 +1287,7 @@ class BackgroundTaskManager {
1283
1287
  executionTimeMs,
1284
1288
  associatedTaskId: task.associatedTaskId
1285
1289
  };
1286
- this.publishBackgroundEvent(BackgroundTaskEventTypes.COMPLETED, completedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel);
1290
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.COMPLETED, completedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1287
1291
  logger3.info(`[BackgroundTaskManager] Task completed successfully`, {
1288
1292
  taskId,
1289
1293
  executionTimeMs
@@ -1324,7 +1328,7 @@ class BackgroundTaskManager {
1324
1328
  ],
1325
1329
  associatedTaskId: task.associatedTaskId
1326
1330
  };
1327
- this.publishBackgroundEvent(BackgroundTaskEventTypes.ASK_USER, askUserPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel);
1331
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.ASK_USER, askUserPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1328
1332
  logger3.info(`[BackgroundTaskManager] Task awaiting user input (ask_user cascade)`, {
1329
1333
  taskId,
1330
1334
  subSessionId: task.subSessionId,
@@ -1346,7 +1350,7 @@ class BackgroundTaskManager {
1346
1350
  executionTimeMs,
1347
1351
  associatedTaskId: task.associatedTaskId
1348
1352
  };
1349
- this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel);
1353
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1350
1354
  } else if (errorMessage.startsWith("Task execution timeout after")) {
1351
1355
  task.status = "timeout";
1352
1356
  const timeoutPayload = {
@@ -1359,7 +1363,7 @@ class BackgroundTaskManager {
1359
1363
  executionTimeMs,
1360
1364
  associatedTaskId: task.associatedTaskId
1361
1365
  };
1362
- this.publishBackgroundEvent(BackgroundTaskEventTypes.TIMEOUT, timeoutPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel);
1366
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.TIMEOUT, timeoutPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1363
1367
  } else {
1364
1368
  task.status = "failed";
1365
1369
  const failedPayload = {
@@ -1371,7 +1375,7 @@ class BackgroundTaskManager {
1371
1375
  executionTimeMs,
1372
1376
  associatedTaskId: task.associatedTaskId
1373
1377
  };
1374
- this.publishBackgroundEvent(BackgroundTaskEventTypes.FAILED, failedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel);
1378
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.FAILED, failedPayload, parentSessionId || task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1375
1379
  }
1376
1380
  task.error = errorMessage;
1377
1381
  logger3.error(`[BackgroundTaskManager] Task execution error`, {
@@ -1416,7 +1420,7 @@ class BackgroundTaskManager {
1416
1420
  startedAt: task.createdAt,
1417
1421
  timeoutMs: task.timeoutMs
1418
1422
  };
1419
- this.publishBackgroundEvent(BackgroundTaskEventTypes.PROGRESS, progressPayload, parentSessionId, task.triggerEventId, task.replyChannel);
1423
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.PROGRESS, progressPayload, parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1420
1424
  }, PROGRESS_INTERVAL);
1421
1425
  this.progressTimers.set(taskId, timer);
1422
1426
  }
@@ -1444,14 +1448,10 @@ class BackgroundTaskManager {
1444
1448
  const basePrompt = resolved?.basePrompt || subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
1445
1449
  const deniedTools = resolved?.deniedTools || subAgent?.deniedTools || [];
1446
1450
  const allowedTools = resolved?.allowedTools || subAgent?.allowedTools;
1447
- let fullPrompt = basePrompt.replace(/{task_description}/g, taskDescription || "N/A");
1448
- fullPrompt += `
1449
-
1450
- ---
1451
-
1452
- # Session Info
1451
+ let fullPrompt = `# Session Info
1453
1452
  - task_id: ${taskId || "N/A"}
1454
1453
  - session_id: ${sessionId}
1454
+ - task_description: ${taskDescription || "N/A"}
1455
1455
 
1456
1456
  ---
1457
1457
 
@@ -1640,7 +1640,8 @@ ${reuseSection.markdown}`;
1640
1640
  runId: capturedRunId,
1641
1641
  ...inheritedModel ? { model: inheritedModel } : {},
1642
1642
  ...inheritedFallbackModel ? { fallbackModel: inheritedFallbackModel } : {},
1643
- ...Array.isArray(inheritedFallbackModels) ? { fallbackModels: inheritedFallbackModels } : {}
1643
+ ...Array.isArray(inheritedFallbackModels) ? { fallbackModels: inheritedFallbackModels } : {},
1644
+ ...task?.systemPrompt ? { metadata: { systemPrompt: task.systemPrompt } } : {}
1644
1645
  });
1645
1646
  };
1646
1647
  const wrappedPromise = processRegistry ? runWithProcessRegistryAsync(processRegistry, () => runWithBgTaskIdAsync(bgTaskId, () => invokeHandleQuery())) : runWithBgTaskIdAsync(bgTaskId, () => invokeHandleQuery());
@@ -1718,7 +1719,7 @@ ${reuseSection.markdown}`;
1718
1719
  executionTimeMs: task.startedAt ? task.completedAt - task.startedAt : 0,
1719
1720
  associatedTaskId: task.associatedTaskId
1720
1721
  };
1721
- this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, task.parentSessionId, task.triggerEventId, task.replyChannel);
1722
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, task.parentSessionId, task.triggerEventId, task.replyChannel, task.pluginEnabledSnapshot);
1722
1723
  this.finalizeTask(taskId, "stopped");
1723
1724
  return {
1724
1725
  success: true,
@@ -1828,7 +1829,7 @@ ${reuseSection.markdown}`;
1828
1829
  executionTimeMs: taskSafe.startedAt && taskSafe.completedAt ? taskSafe.completedAt - taskSafe.startedAt : 0,
1829
1830
  associatedTaskId: taskSafe.associatedTaskId
1830
1831
  };
1831
- this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, taskSafe.parentSessionId, taskSafe.triggerEventId, taskSafe.replyChannel);
1832
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, taskSafe.parentSessionId, taskSafe.triggerEventId, taskSafe.replyChannel, taskSafe.pluginEnabledSnapshot);
1832
1833
  }
1833
1834
  }
1834
1835
  }
@@ -2056,7 +2057,7 @@ No need to poll — just wait for the notification and use \`task_get\` with the
2056
2057
  };
2057
2058
  await globalHookManager.execute(TaskHookPoints.DELEGATE_BEFORE, delegateCtx, { sessionId: parentSessionId });
2058
2059
  promptWithTaskInfo = delegateCtx.prompt;
2059
- return await handleBackgroundTask(backgroundTaskManager, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout, similar_task_ids, params.sub_session_id, resolvedTriggerEventId, ctx.model, ctx.fallbackModel, ctx.fallbackModels);
2060
+ return await handleBackgroundTask(backgroundTaskManager, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout, similar_task_ids, params.sub_session_id, resolvedTriggerEventId, ctx.model, ctx.fallbackModel, ctx.fallbackModels, ctx.metadata?.systemPrompt);
2060
2061
  }
2061
2062
  };
2062
2063
  tool.execute = wrapFunction(tool.execute, "delegate.execute", {
@@ -2100,7 +2101,19 @@ function _captureReplyChannelSnapshot() {
2100
2101
  };
2101
2102
  }
2102
2103
  var captureReplyChannelSnapshot = wrapFunction(_captureReplyChannelSnapshot, "delegate.captureReplyChannel", { recordParams: false, recordResult: true, recordError: true });
2103
- async function handleBackgroundTask(backgroundTaskManager, parentSessionId, description, prompt, subagentType, timeout, similarTaskIds, existingSubSessionId, triggerEventId, model, fallbackModel, fallbackModels) {
2104
+ function _capturePluginEnabledSnapshot() {
2105
+ const pluginEnabled = getEnvContext()?.pluginEnabled;
2106
+ if (!pluginEnabled)
2107
+ return;
2108
+ if (typeof pluginEnabled !== "object")
2109
+ return;
2110
+ const keys = Object.keys(pluginEnabled);
2111
+ if (keys.length === 0)
2112
+ return;
2113
+ return { ...pluginEnabled };
2114
+ }
2115
+ var capturePluginEnabledSnapshot = wrapFunction(_capturePluginEnabledSnapshot, "delegate.capturePluginEnabled", { recordParams: false, recordResult: true, recordError: true });
2116
+ async function handleBackgroundTask(backgroundTaskManager, parentSessionId, description, prompt, subagentType, timeout, similarTaskIds, existingSubSessionId, triggerEventId, model, fallbackModel, fallbackModels, systemPrompt) {
2104
2117
  const startTime = Date.now();
2105
2118
  try {
2106
2119
  let actualSubagentType = subagentType;
@@ -2129,7 +2142,8 @@ async function handleBackgroundTask(backgroundTaskManager, parentSessionId, desc
2129
2142
  triggerEventId,
2130
2143
  model,
2131
2144
  fallbackModel,
2132
- fallbackModels
2145
+ fallbackModels,
2146
+ systemPrompt
2133
2147
  });
2134
2148
  const output = [
2135
2149
  `✅ Background task accepted`,
@@ -2162,4 +2176,4 @@ async function handleBackgroundTask(backgroundTaskManager, parentSessionId, desc
2162
2176
  };
2163
2177
  }
2164
2178
  }
2165
- export { BackgroundTaskEventTypes, builtInSubAgents, getSubAgentSpec, DelegateToolParameters, buildEntryAgentPrompt, WORKFLOW_COMPAT_ALIASES, DEFAULT_TIMEOUT, PROGRESS_INTERVAL, BackgroundTaskManager, createDelegateTool, deriveTriggerEventIdFromEnvContext, captureReplyChannelSnapshot, handleBackgroundTask };
2179
+ export { BackgroundTaskEventTypes, builtInSubAgents, getSubAgentSpec, DelegateToolParameters, buildEntryAgentPrompt, WORKFLOW_COMPAT_ALIASES, DEFAULT_TIMEOUT, PROGRESS_INTERVAL, BackgroundTaskManager, createDelegateTool, deriveTriggerEventIdFromEnvContext, captureReplyChannelSnapshot, capturePluginEnabledSnapshot, handleBackgroundTask };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LarkCardPatchNotifier,
3
3
  formatDurationMs
4
- } from "./roy-agent-core-nmx9934r.js";
4
+ } from "./roy-agent-core-7dd0s3xb.js";
5
5
  import {
6
6
  WorkflowHookPoints,
7
7
  init_workflow_hook_points
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  isToolUnavailableError,
3
3
  truncateOutputInline
4
- } from "./roy-agent-core-v85n42ve.js";
4
+ } from "./roy-agent-core-ze5cqpf2.js";
5
5
  import {
6
6
  AgentRegistry
7
7
  } from "./roy-agent-core-ed233k5z.js";
8
8
  import {
9
+ createTaskOpWatermarkPlugin,
9
10
  enqueueToAddFakeUserMessage
10
- } from "./roy-agent-core-f77k3gqt.js";
11
+ } from "./roy-agent-core-h21gngxf.js";
11
12
  import {
12
13
  SessionMessageConverter
13
14
  } from "./roy-agent-core-0snm5hc5.js";
@@ -68,8 +69,6 @@ import {
68
69
 
69
70
  // src/env/agent/agent-component.ts
70
71
  init_logger();
71
- import fs from "fs/promises";
72
- import path from "path";
73
72
  import { z } from "zod";
74
73
 
75
74
  // src/env/task/plugins/max-iteration-reminder-plugin.ts
@@ -600,6 +599,7 @@ class AgentComponent extends BaseComponent {
600
599
  abortControllers = new Map;
601
600
  defaultTools = [];
602
601
  doomLoopCaches = new Map;
602
+ _cacheSnapshots = new Map;
603
603
  fallbackState = new Map;
604
604
  configComponent;
605
605
  skipAbortRunningTasksOnStop = false;
@@ -919,6 +919,9 @@ class AgentComponent extends BaseComponent {
919
919
  };
920
920
  this.agents.set(name, instance);
921
921
  this.registerPlugin(name, createMaxIterationReminderPlugin());
922
+ this.registerPlugin(name, createTaskOpWatermarkPlugin({
923
+ resolveTaskComponent: () => this.env?.getComponent?.("task")
924
+ }));
922
925
  logger2.info(`Agent registered: ${name}`, { type: instance.config.type });
923
926
  return instance;
924
927
  }
@@ -1609,25 +1612,14 @@ class AgentComponent extends BaseComponent {
1609
1612
  return { snapshot: null, systemPromptOverride: undefined };
1610
1613
  }
1611
1614
  try {
1612
- const sessionComponent = this.env?.getComponent?.("session");
1613
- if (!sessionComponent) {
1614
- return { snapshot: null, systemPromptOverride: undefined };
1615
- }
1616
- const session = await sessionComponent.get(sessionId);
1617
- const existingSnapshot = session?.metadata?.cacheSnapshot;
1618
- if (existingSnapshot && typeof existingSnapshot === "object" && existingSnapshot.systemPrompt) {
1619
- const stale = await this._isMemorySnapshotStale(existingSnapshot);
1620
- if (stale) {
1621
- logger2.info(`[AgentComponent._run] cacheSnapshot for session ${sessionId} is stale (${stale}); recreating`);
1622
- } else {
1623
- logger2.debug(`[AgentComponent._run] Reusing cacheSnapshot for session ${sessionId} (snapshotAt=${existingSnapshot.snapshotAt})`);
1624
- return {
1625
- snapshot: existingSnapshot,
1626
- systemPromptOverride: existingSnapshot.systemPrompt
1627
- };
1628
- }
1615
+ const existingSnapshot = this._cacheSnapshots.get(sessionId);
1616
+ if (existingSnapshot) {
1617
+ logger2.debug(`[AgentComponent._run] Reusing cacheSnapshot for session ${sessionId} (snapshotAt=${existingSnapshot.snapshotAt})`);
1618
+ return {
1619
+ snapshot: existingSnapshot,
1620
+ systemPromptOverride: existingSnapshot.systemPrompt
1621
+ };
1629
1622
  }
1630
- const memoryStat = await this._collectMemoryStat();
1631
1623
  let resolvedSystemPrompt = initialSystemPrompt;
1632
1624
  if (resolvedSystemPrompt && resolvedSystemPrompt.includes("{{memory}}")) {
1633
1625
  try {
@@ -1646,66 +1638,16 @@ class AgentComponent extends BaseComponent {
1646
1638
  const snapshot = {
1647
1639
  systemPrompt: resolvedSystemPrompt ?? agentConfigSystemPrompt ?? "",
1648
1640
  additionInfo: effectiveContext.additionInfo || "",
1649
- snapshotAt: Date.now(),
1650
- memoryStat
1641
+ snapshotAt: Date.now()
1651
1642
  };
1652
- try {
1653
- await sessionComponent.update(sessionId, {
1654
- metadata: {
1655
- ...session?.metadata ?? {},
1656
- cacheSnapshot: snapshot
1657
- }
1658
- });
1659
- logger2.debug(`[AgentComponent._run] Created cacheSnapshot for session ${sessionId} (snapshotAt=${snapshot.snapshotAt})`);
1660
- } catch (updateErr) {
1661
- logger2.warn(`[AgentComponent._run] Failed to persist cacheSnapshot for session ${sessionId}: ${updateErr}`);
1662
- }
1643
+ this._cacheSnapshots.set(sessionId, snapshot);
1644
+ logger2.debug(`[AgentComponent._run] Created cacheSnapshot for session ${sessionId} (snapshotAt=${snapshot.snapshotAt})`);
1663
1645
  return { snapshot, systemPromptOverride: resolvedSystemPrompt };
1664
1646
  } catch (err) {
1665
1647
  logger2.warn(`[AgentComponent._run] Failed to load cacheSnapshot: ${err}`);
1666
1648
  return { snapshot: null, systemPromptOverride: undefined };
1667
1649
  }
1668
1650
  }
1669
- async _isMemorySnapshotStale(snapshot) {
1670
- const stat = snapshot.memoryStat;
1671
- if (!stat || typeof stat !== "object") {
1672
- return "no-memoryStat (legacy snapshot)";
1673
- }
1674
- const current = await this._collectMemoryStat();
1675
- if (current.globalMtime !== stat.globalMtime) {
1676
- return `global memory.md mtime changed (${stat.globalMtime} -> ${current.globalMtime})`;
1677
- }
1678
- if (current.projectMtime !== stat.projectMtime) {
1679
- return `project memory.md mtime changed (${stat.projectMtime} -> ${current.projectMtime})`;
1680
- }
1681
- return null;
1682
- }
1683
- async _collectMemoryStat() {
1684
- const empty = { globalMtime: 0, projectMtime: 0 };
1685
- try {
1686
- const memoryComponent = this.env?.getComponent?.("memory");
1687
- if (!memoryComponent?.getMemoryPaths || !memoryComponent.getMemoryFile) {
1688
- return empty;
1689
- }
1690
- const memoryFile = memoryComponent.getMemoryFile();
1691
- const paths = memoryComponent.getMemoryPaths();
1692
- const result = { globalMtime: 0, projectMtime: 0 };
1693
- for (const p of paths) {
1694
- const filePath = path.join(p.path, memoryFile);
1695
- try {
1696
- const st = await fs.stat(filePath);
1697
- if (p.type === "global") {
1698
- result.globalMtime = st.mtimeMs;
1699
- } else if (p.type === "project") {
1700
- result.projectMtime = st.mtimeMs;
1701
- }
1702
- } catch {}
1703
- }
1704
- return result;
1705
- } catch {
1706
- return empty;
1707
- }
1708
- }
1709
1651
  async _fallbackReplaceMemory(systemPrompt) {
1710
1652
  if (!systemPrompt.includes("{{memory}}"))
1711
1653
  return systemPrompt;
@@ -709,6 +709,22 @@ var init_sqlite_task_store = __esm(() => {
709
709
  const limit = options.limit || 20;
710
710
  return ops.slice(offset, offset + limit);
711
711
  }
712
+ async listOperationsFresh(options) {
713
+ await this.initialize();
714
+ const stmt = this.db.prepare("SELECT * FROM task_operation WHERE task_id = ? ORDER BY id DESC");
715
+ const rows = stmt.all(options.taskId);
716
+ let ops = rows.map((row) => this.rowToOperation(row));
717
+ const filterType = options.milestoneType ?? options.actionType;
718
+ if (filterType) {
719
+ ops = ops.filter((op) => op.milestoneType === filterType);
720
+ }
721
+ const offset = options.offset || 0;
722
+ const limit = options.limit || 20;
723
+ return ops.slice(offset, offset + limit);
724
+ }
725
+ invalidateOperationsCache(taskId) {
726
+ this.operationsCache.delete(taskId);
727
+ }
712
728
  async getTaskIdBySessionId(sessionId) {
713
729
  await this.initialize();
714
730
  if (!sessionId)
@@ -716,6 +732,13 @@ var init_sqlite_task_store = __esm(() => {
716
732
  const row = this.db.prepare("SELECT task_id FROM task_operation WHERE session_id = ? AND milestone_type = 'create' ORDER BY timestamp ASC LIMIT 1").get(sessionId);
717
733
  return typeof row?.task_id === "number" ? row.task_id : undefined;
718
734
  }
735
+ async getTaskIdsBySessionId(sessionId) {
736
+ await this.initialize();
737
+ if (!sessionId)
738
+ return [];
739
+ const rows = this.db.prepare("SELECT DISTINCT task_id FROM task_operation WHERE session_id = ? ORDER BY task_id ASC").all(sessionId);
740
+ return rows.map((r) => r.task_id).filter((id) => typeof id === "number");
741
+ }
719
742
  rowToTask(row) {
720
743
  return {
721
744
  id: row.id,
@@ -7,7 +7,7 @@ import {
7
7
  isBuiltInEventSourceType,
8
8
  isValidEventSourceType,
9
9
  validateEventSourceConfig
10
- } from "./roy-agent-core-bxkjk7zx.js";
10
+ } from "./roy-agent-core-vx8zc847.js";
11
11
  import"./roy-agent-core-fs0mn2jk.js";
12
12
  export {
13
13
  validateEventSourceConfig,