@action-llama/action-llama 0.13.3 → 0.13.5

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 (163) hide show
  1. package/README.md +6 -6
  2. package/agent-docs/AGENTS.md +1478 -339
  3. package/dist/agents/container-entry.d.ts.map +1 -1
  4. package/dist/agents/container-entry.js +3 -1
  5. package/dist/agents/container-entry.js.map +1 -1
  6. package/dist/agents/execution-engine.d.ts.map +1 -1
  7. package/dist/agents/execution-engine.js +3 -1
  8. package/dist/agents/execution-engine.js.map +1 -1
  9. package/dist/agents/runner.d.ts.map +1 -1
  10. package/dist/agents/runner.js +3 -1
  11. package/dist/agents/runner.js.map +1 -1
  12. package/dist/build-info.json +1 -1
  13. package/dist/cli/commands/chat.js +6 -2
  14. package/dist/cli/commands/chat.js.map +1 -1
  15. package/dist/cli/commands/push.d.ts +1 -0
  16. package/dist/cli/commands/push.d.ts.map +1 -1
  17. package/dist/cli/commands/push.js +22 -4
  18. package/dist/cli/commands/push.js.map +1 -1
  19. package/dist/cli/commands/status.d.ts.map +1 -1
  20. package/dist/cli/commands/status.js +10 -5
  21. package/dist/cli/commands/status.js.map +1 -1
  22. package/dist/cli/main.js +3 -2
  23. package/dist/cli/main.js.map +1 -1
  24. package/dist/cloud/{vps/cloudflare-api.d.ts → cloudflare/api.d.ts} +1 -1
  25. package/dist/cloud/cloudflare/api.d.ts.map +1 -0
  26. package/dist/cloud/{vps/cloudflare-api.js → cloudflare/api.js} +1 -1
  27. package/dist/cloud/cloudflare/api.js.map +1 -0
  28. package/dist/cloud/provider.js +2 -2
  29. package/dist/cloud/provider.js.map +1 -1
  30. package/dist/cloud/vps/provider.d.ts +4 -4
  31. package/dist/cloud/vps/provider.d.ts.map +1 -1
  32. package/dist/cloud/vps/provider.js +4 -4
  33. package/dist/cloud/vps/provider.js.map +1 -1
  34. package/dist/cloud/vps/provision.js +4 -4
  35. package/dist/cloud/vps/provision.js.map +1 -1
  36. package/dist/cloud/vps/teardown.d.ts +2 -2
  37. package/dist/cloud/vps/teardown.d.ts.map +1 -1
  38. package/dist/cloud/vps/teardown.js +3 -3
  39. package/dist/cloud/vps/teardown.js.map +1 -1
  40. package/dist/cloud/vps/verify.js +2 -2
  41. package/dist/cloud/vps/verify.js.map +1 -1
  42. package/dist/credentials/builtins/cloudflare-api-token.js +1 -1
  43. package/dist/credentials/builtins/cloudflare-api-token.js.map +1 -1
  44. package/dist/gateway/auth.d.ts +6 -1
  45. package/dist/gateway/auth.d.ts.map +1 -1
  46. package/dist/gateway/auth.js +21 -4
  47. package/dist/gateway/auth.js.map +1 -1
  48. package/dist/gateway/index.d.ts +1 -0
  49. package/dist/gateway/index.d.ts.map +1 -1
  50. package/dist/gateway/index.js +13 -6
  51. package/dist/gateway/index.js.map +1 -1
  52. package/dist/gateway/lock-store.d.ts +17 -0
  53. package/dist/gateway/lock-store.d.ts.map +1 -1
  54. package/dist/gateway/lock-store.js +101 -28
  55. package/dist/gateway/lock-store.js.map +1 -1
  56. package/dist/gateway/routes/control.d.ts +3 -0
  57. package/dist/gateway/routes/control.d.ts.map +1 -1
  58. package/dist/gateway/routes/control.js +7 -0
  59. package/dist/gateway/routes/control.js.map +1 -1
  60. package/dist/gateway/routes/dashboard.d.ts +6 -1
  61. package/dist/gateway/routes/dashboard.d.ts.map +1 -1
  62. package/dist/gateway/routes/dashboard.js +37 -3
  63. package/dist/gateway/routes/dashboard.js.map +1 -1
  64. package/dist/gateway/routes/locks.d.ts.map +1 -1
  65. package/dist/gateway/routes/locks.js +7 -3
  66. package/dist/gateway/routes/locks.js.map +1 -1
  67. package/dist/gateway/routes/webhooks.d.ts.map +1 -1
  68. package/dist/gateway/routes/webhooks.js +0 -3
  69. package/dist/gateway/routes/webhooks.js.map +1 -1
  70. package/dist/gateway/session-store.d.ts +11 -0
  71. package/dist/gateway/session-store.d.ts.map +1 -0
  72. package/dist/gateway/session-store.js +33 -0
  73. package/dist/gateway/session-store.js.map +1 -0
  74. package/dist/gateway/types.d.ts +5 -0
  75. package/dist/gateway/types.d.ts.map +1 -1
  76. package/dist/remote/push.d.ts +15 -1
  77. package/dist/remote/push.d.ts.map +1 -1
  78. package/dist/remote/push.js +54 -3
  79. package/dist/remote/push.js.map +1 -1
  80. package/dist/scheduler/call-dispatcher.d.ts +11 -0
  81. package/dist/scheduler/call-dispatcher.d.ts.map +1 -0
  82. package/dist/scheduler/call-dispatcher.js +65 -0
  83. package/dist/scheduler/call-dispatcher.js.map +1 -0
  84. package/dist/scheduler/cron-setup.d.ts +41 -0
  85. package/dist/scheduler/cron-setup.d.ts.map +1 -0
  86. package/dist/scheduler/cron-setup.js +94 -0
  87. package/dist/scheduler/cron-setup.js.map +1 -0
  88. package/dist/scheduler/event-queue-sqlite.d.ts +27 -0
  89. package/dist/scheduler/event-queue-sqlite.d.ts.map +1 -0
  90. package/dist/scheduler/event-queue-sqlite.js +105 -0
  91. package/dist/scheduler/event-queue-sqlite.js.map +1 -0
  92. package/dist/scheduler/event-queue.d.ts +31 -9
  93. package/dist/scheduler/event-queue.d.ts.map +1 -1
  94. package/dist/scheduler/event-queue.js +21 -32
  95. package/dist/scheduler/event-queue.js.map +1 -1
  96. package/dist/scheduler/execution.d.ts +9 -2
  97. package/dist/scheduler/execution.d.ts.map +1 -1
  98. package/dist/scheduler/execution.js +64 -48
  99. package/dist/scheduler/execution.js.map +1 -1
  100. package/dist/scheduler/gateway-setup.d.ts +40 -0
  101. package/dist/scheduler/gateway-setup.d.ts.map +1 -0
  102. package/dist/scheduler/gateway-setup.js +135 -0
  103. package/dist/scheduler/gateway-setup.js.map +1 -0
  104. package/dist/scheduler/index.d.ts +4 -7
  105. package/dist/scheduler/index.d.ts.map +1 -1
  106. package/dist/scheduler/index.js +81 -437
  107. package/dist/scheduler/index.js.map +1 -1
  108. package/dist/scheduler/runner-setup.d.ts +34 -0
  109. package/dist/scheduler/runner-setup.d.ts.map +1 -0
  110. package/dist/scheduler/runner-setup.js +63 -0
  111. package/dist/scheduler/runner-setup.js.map +1 -0
  112. package/dist/scheduler/shutdown.d.ts +20 -0
  113. package/dist/scheduler/shutdown.d.ts.map +1 -0
  114. package/dist/scheduler/shutdown.js +38 -0
  115. package/dist/scheduler/shutdown.js.map +1 -0
  116. package/dist/scheduler/state.d.ts +17 -0
  117. package/dist/scheduler/state.d.ts.map +1 -0
  118. package/dist/scheduler/state.js +10 -0
  119. package/dist/scheduler/state.js.map +1 -0
  120. package/dist/scheduler/validation.d.ts +18 -0
  121. package/dist/scheduler/validation.d.ts.map +1 -0
  122. package/dist/scheduler/validation.js +59 -0
  123. package/dist/scheduler/validation.js.map +1 -0
  124. package/dist/scheduler/watcher.d.ts.map +1 -1
  125. package/dist/scheduler/watcher.js +31 -48
  126. package/dist/scheduler/watcher.js.map +1 -1
  127. package/dist/scheduler/webhook-setup.d.ts +18 -1
  128. package/dist/scheduler/webhook-setup.d.ts.map +1 -1
  129. package/dist/scheduler/webhook-setup.js +51 -0
  130. package/dist/scheduler/webhook-setup.js.map +1 -1
  131. package/dist/shared/config.d.ts +2 -3
  132. package/dist/shared/config.d.ts.map +1 -1
  133. package/dist/shared/config.js +0 -15
  134. package/dist/shared/config.js.map +1 -1
  135. package/dist/shared/queue-memory.d.ts +16 -0
  136. package/dist/shared/queue-memory.d.ts.map +1 -0
  137. package/dist/shared/queue-memory.js +28 -0
  138. package/dist/shared/queue-memory.js.map +1 -0
  139. package/dist/shared/queue-sqlite.d.ts +28 -0
  140. package/dist/shared/queue-sqlite.d.ts.map +1 -0
  141. package/dist/shared/queue-sqlite.js +86 -0
  142. package/dist/shared/queue-sqlite.js.map +1 -0
  143. package/dist/shared/queue.d.ts +55 -0
  144. package/dist/shared/queue.d.ts.map +1 -0
  145. package/dist/shared/queue.js +22 -0
  146. package/dist/shared/queue.js.map +1 -0
  147. package/dist/shared/server.d.ts +1 -0
  148. package/dist/shared/server.d.ts.map +1 -1
  149. package/dist/shared/server.js +3 -0
  150. package/dist/shared/server.js.map +1 -1
  151. package/package.json +2 -2
  152. package/agent-docs/skills/README.md +0 -15
  153. package/agent-docs/skills/calls.md +0 -82
  154. package/agent-docs/skills/credentials.md +0 -45
  155. package/agent-docs/skills/environment.md +0 -102
  156. package/agent-docs/skills/resource-locks.md +0 -78
  157. package/agent-docs/skills/signals.md +0 -98
  158. package/dist/cloud/vps/cloudflare-api.d.ts.map +0 -1
  159. package/dist/cloud/vps/cloudflare-api.js.map +0 -1
  160. package/dist/gateway/rate-limiter.d.ts +0 -16
  161. package/dist/gateway/rate-limiter.d.ts.map +0 -1
  162. package/dist/gateway/rate-limiter.js +0 -38
  163. package/dist/gateway/rate-limiter.js.map +0 -1
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Cron job creation, enable/disable event handling, and initial run firing.
3
+ */
4
+ import { Cron } from "croner";
5
+ import { runWithReruns } from "./execution.js";
6
+ export function setupCronJobs(opts) {
7
+ const { activeAgentConfigs, runnerPools, schedulerCtx, webhookSources, globalConfig, agentConfigs, gateway, statusTracker, logger, timezone, anyWebhooks, } = opts;
8
+ const cronJobs = [];
9
+ const agentCronJobs = new Map();
10
+ for (const agentConfig of activeAgentConfigs) {
11
+ if (!agentConfig.schedule)
12
+ continue;
13
+ const pool = runnerPools[agentConfig.name];
14
+ const job = new Cron(agentConfig.schedule, { timezone }, async () => {
15
+ // Skip if scheduler is paused
16
+ if (statusTracker?.isPaused()) {
17
+ logger.info({ agent: agentConfig.name }, "scheduler paused, skipping scheduled run");
18
+ return;
19
+ }
20
+ // Skip if agent is disabled
21
+ if (statusTracker && !statusTracker.isAgentEnabled(agentConfig.name)) {
22
+ logger.info({ agent: agentConfig.name }, "agent is disabled, skipping scheduled run");
23
+ return;
24
+ }
25
+ const availableRunner = pool.getAvailableRunner();
26
+ if (!availableRunner) {
27
+ const { dropped } = schedulerCtx.workQueue.enqueue(agentConfig.name, { type: 'schedule' });
28
+ logger.info({ agent: agentConfig.name, running: pool.runningJobCount, scale: pool.size }, "all runners busy, scheduled run queued");
29
+ if (dropped)
30
+ logger.warn({ agent: agentConfig.name }, "queue full, oldest event dropped");
31
+ return;
32
+ }
33
+ logger.info({ agent: agentConfig.name, running: pool.runningJobCount, scale: pool.size }, "triggering scheduled run");
34
+ await runWithReruns(availableRunner, agentConfig, 0, schedulerCtx);
35
+ });
36
+ cronJobs.push(job);
37
+ agentCronJobs.set(agentConfig.name, job);
38
+ const nextRun = job.nextRun();
39
+ if (nextRun) {
40
+ statusTracker?.setNextRunAt(agentConfig.name, nextRun);
41
+ }
42
+ logger.info(`Scheduled ${agentConfig.name}: "${agentConfig.schedule}" (${timezone})`);
43
+ }
44
+ const webhookUrls = [];
45
+ if (anyWebhooks && gateway) {
46
+ const gatewayPort = globalConfig.gateway?.port || 8080;
47
+ const providerTypes = new Set(agentConfigs.flatMap((a) => a.webhooks?.map((t) => webhookSources[t.source]?.type).filter(Boolean) || []));
48
+ for (const pt of providerTypes) {
49
+ webhookUrls.push(`http://localhost:${gatewayPort}/webhooks/${pt}`);
50
+ }
51
+ }
52
+ return { cronJobs, agentCronJobs, webhookUrls };
53
+ }
54
+ export function setupEnableDisableHandlers(opts) {
55
+ const { statusTracker, agentCronJobs, logger } = opts;
56
+ statusTracker.on("agent-enabled", (agentName) => {
57
+ const job = agentCronJobs.get(agentName);
58
+ if (job) {
59
+ job.resume();
60
+ const nextRun = job.nextRun();
61
+ if (nextRun) {
62
+ statusTracker.setNextRunAt(agentName, nextRun);
63
+ }
64
+ logger.info({ agent: agentName }, "agent enabled, cron job resumed");
65
+ }
66
+ });
67
+ statusTracker.on("agent-disabled", (agentName) => {
68
+ const job = agentCronJobs.get(agentName);
69
+ if (job) {
70
+ job.pause();
71
+ statusTracker.setNextRunAt(agentName, null);
72
+ logger.info({ agent: agentName }, "agent disabled, cron job paused");
73
+ }
74
+ });
75
+ }
76
+ export function fireInitialRuns(opts) {
77
+ const { agentConfigs, runnerPools, schedulerCtx, logger } = opts;
78
+ for (const agentConfig of agentConfigs) {
79
+ if (!agentConfig.schedule)
80
+ continue;
81
+ const pool = runnerPools[agentConfig.name];
82
+ const availableRunner = pool.getAvailableRunner();
83
+ if (availableRunner) {
84
+ logger.info(`Initial run for ${agentConfig.name}`);
85
+ runWithReruns(availableRunner, agentConfig, 0, schedulerCtx).catch((err) => {
86
+ logger.error({ err }, `Initial ${agentConfig.name} run failed`);
87
+ });
88
+ }
89
+ else {
90
+ logger.warn(`${agentConfig.name}: all runners busy, skipping initial run`);
91
+ }
92
+ }
93
+ }
94
+ //# sourceMappingURL=cron-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-setup.js","sourceRoot":"","sources":["../../src/scheduler/cron-setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { WorkQueue, QueuedWorkItem, EnqueueResult } from "./event-queue.js";
2
+ /**
3
+ * SQLite-backed WorkQueue — durable per-agent FIFO queue.
4
+ *
5
+ * Items are written to disk immediately on enqueue, so work
6
+ * survives process crashes and restarts without a separate
7
+ * persistence layer.
8
+ *
9
+ * Uses better-sqlite3 for synchronous embedded storage.
10
+ * Dequeue is atomic (transaction: select + delete) to prevent
11
+ * concurrent double-claims.
12
+ */
13
+ export declare class SqliteWorkQueue<T> implements WorkQueue<T> {
14
+ private db;
15
+ private stmts;
16
+ private maxSize;
17
+ private _dequeueTransaction;
18
+ private _enqueueTransaction;
19
+ constructor(maxSize: number, dbPath: string);
20
+ enqueue(agentName: string, context: T, receivedAt?: Date): EnqueueResult<T>;
21
+ dequeue(agentName: string): QueuedWorkItem<T> | undefined;
22
+ size(agentName: string): number;
23
+ clear(agentName: string): void;
24
+ clearAll(): void;
25
+ close(): void;
26
+ }
27
+ //# sourceMappingURL=event-queue-sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-queue-sqlite.d.ts","sourceRoot":"","sources":["../../src/scheduler/event-queue-sqlite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjF;;;;;;;;;;GAUG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,SAAS,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,EAAE,CAAgC;IAC1C,OAAO,CAAC,KAAK,CAQX;IACF,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,mBAAmB,CAIb;IAEd,OAAO,CAAC,mBAAmB,CAKiC;gBAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAwE3C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;IAoB3E,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS;IASzD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAK/B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B,QAAQ,IAAI,IAAI;IAIhB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,105 @@
1
+ import Database from "better-sqlite3";
2
+ import { mkdirSync } from "fs";
3
+ import { dirname } from "path";
4
+ import { randomUUID } from "crypto";
5
+ /**
6
+ * SQLite-backed WorkQueue — durable per-agent FIFO queue.
7
+ *
8
+ * Items are written to disk immediately on enqueue, so work
9
+ * survives process crashes and restarts without a separate
10
+ * persistence layer.
11
+ *
12
+ * Uses better-sqlite3 for synchronous embedded storage.
13
+ * Dequeue is atomic (transaction: select + delete) to prevent
14
+ * concurrent double-claims.
15
+ */
16
+ export class SqliteWorkQueue {
17
+ db;
18
+ stmts;
19
+ maxSize;
20
+ _dequeueTransaction;
21
+ _enqueueTransaction;
22
+ constructor(maxSize, dbPath) {
23
+ this.maxSize = maxSize;
24
+ mkdirSync(dirname(dbPath), { recursive: true });
25
+ this.db = new Database(dbPath);
26
+ this.db.pragma("journal_mode = WAL");
27
+ this.db.exec(`
28
+ CREATE TABLE IF NOT EXISTS work_queue (
29
+ id TEXT NOT NULL,
30
+ agent TEXT NOT NULL,
31
+ payload TEXT NOT NULL,
32
+ received_at INTEGER NOT NULL,
33
+ PRIMARY KEY (agent, id)
34
+ )
35
+ `);
36
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_wq_agent ON work_queue(agent)");
37
+ this.stmts = {
38
+ enqueue: this.db.prepare("INSERT INTO work_queue (id, agent, payload, received_at) VALUES (?, ?, ?, ?)"),
39
+ dequeue_peek: this.db.prepare("SELECT id, payload, received_at FROM work_queue WHERE agent = ? ORDER BY rowid ASC LIMIT 1"),
40
+ delete_by_id: this.db.prepare("DELETE FROM work_queue WHERE agent = ? AND id = ?"),
41
+ size: this.db.prepare("SELECT COUNT(*) AS n FROM work_queue WHERE agent = ?"),
42
+ clear_agent: this.db.prepare("DELETE FROM work_queue WHERE agent = ?"),
43
+ clear_all: this.db.prepare("DELETE FROM work_queue"),
44
+ oldest: this.db.prepare("SELECT id, payload, received_at FROM work_queue WHERE agent = ? ORDER BY rowid ASC LIMIT 1"),
45
+ };
46
+ // Atomic dequeue: peek + delete in one transaction
47
+ this._dequeueTransaction = this.db.transaction((agent) => {
48
+ const row = this.stmts.dequeue_peek.get(agent);
49
+ if (!row)
50
+ return undefined;
51
+ this.stmts.delete_by_id.run(agent, row.id);
52
+ return row;
53
+ });
54
+ // Atomic enqueue with overflow: insert + conditionally drop oldest
55
+ this._enqueueTransaction = this.db.transaction((agent, id, payload, receivedAt) => {
56
+ const { n } = this.stmts.size.get(agent);
57
+ let dropped;
58
+ if (n >= this.maxSize) {
59
+ const oldest = this.stmts.oldest.get(agent);
60
+ if (oldest) {
61
+ this.stmts.delete_by_id.run(agent, oldest.id);
62
+ dropped = { payload: oldest.payload, received_at: oldest.received_at };
63
+ }
64
+ }
65
+ this.stmts.enqueue.run(id, agent, payload, receivedAt);
66
+ return { dropped };
67
+ });
68
+ }
69
+ enqueue(agentName, context, receivedAt) {
70
+ const id = randomUUID();
71
+ const ts = (receivedAt || new Date()).getTime();
72
+ const { dropped: droppedRow } = this._enqueueTransaction(agentName, id, JSON.stringify(context), ts);
73
+ let dropped;
74
+ if (droppedRow) {
75
+ dropped = {
76
+ context: JSON.parse(droppedRow.payload),
77
+ receivedAt: new Date(droppedRow.received_at),
78
+ };
79
+ }
80
+ return { accepted: true, dropped };
81
+ }
82
+ dequeue(agentName) {
83
+ const row = this._dequeueTransaction(agentName);
84
+ if (!row)
85
+ return undefined;
86
+ return {
87
+ context: JSON.parse(row.payload),
88
+ receivedAt: new Date(row.received_at),
89
+ };
90
+ }
91
+ size(agentName) {
92
+ const row = this.stmts.size.get(agentName);
93
+ return row.n;
94
+ }
95
+ clear(agentName) {
96
+ this.stmts.clear_agent.run(agentName);
97
+ }
98
+ clearAll() {
99
+ this.stmts.clear_all.run();
100
+ }
101
+ close() {
102
+ this.db.close();
103
+ }
104
+ }
105
+ //# sourceMappingURL=event-queue-sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-queue-sqlite.js","sourceRoot":"","sources":["../../src/scheduler/event-queue-sqlite.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import type { StateStore } from "../shared/state-store.js";
2
1
  export interface QueuedWorkItem<T> {
3
2
  context: T;
4
3
  receivedAt: Date;
@@ -7,20 +6,43 @@ export interface EnqueueResult<T> {
7
6
  accepted: boolean;
8
7
  dropped?: QueuedWorkItem<T>;
9
8
  }
10
- export declare class WorkQueue<T> {
9
+ export interface WorkQueue<T> {
10
+ enqueue(agentName: string, context: T, receivedAt?: Date): EnqueueResult<T>;
11
+ dequeue(agentName: string): QueuedWorkItem<T> | undefined;
12
+ size(agentName: string): number;
13
+ clear(agentName: string): void;
14
+ clearAll(): void;
15
+ close(): void;
16
+ }
17
+ /**
18
+ * In-memory WorkQueue — suitable for tests and single-process use
19
+ * where durability is not required. State is lost when the process exits.
20
+ */
21
+ export declare class MemoryWorkQueue<T> implements WorkQueue<T> {
11
22
  private queues;
12
23
  private maxSize;
13
- private store?;
14
- constructor(maxSize?: number, store?: StateStore);
15
- /** Hydrate in-memory state from the persistent store. */
16
- init(): Promise<void>;
24
+ constructor(maxSize?: number);
17
25
  enqueue(agentName: string, context: T, receivedAt?: Date): EnqueueResult<T>;
18
26
  dequeue(agentName: string): QueuedWorkItem<T> | undefined;
19
27
  size(agentName: string): number;
20
28
  clear(agentName: string): void;
21
29
  clearAll(): void;
22
- /** Clear in-memory queues only — persistent state survives for the next instance. */
23
- clearInMemory(): void;
24
- private persist;
30
+ close(): void;
31
+ }
32
+ export interface SqliteWorkQueueOpts {
33
+ type: "sqlite";
34
+ /** Path to the .db file (created if missing). */
35
+ path: string;
36
+ }
37
+ export interface MemoryWorkQueueOpts {
38
+ type: "memory";
25
39
  }
40
+ export type WorkQueueOpts = SqliteWorkQueueOpts | MemoryWorkQueueOpts;
41
+ /**
42
+ * Create a WorkQueue from configuration.
43
+ *
44
+ * Uses dynamic imports so native modules (better-sqlite3)
45
+ * are only loaded when actually needed.
46
+ */
47
+ export declare function createWorkQueue<T>(maxSize: number, opts: WorkQueueOpts): Promise<WorkQueue<T>>;
26
48
  //# sourceMappingURL=event-queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;CAC7B;AAID,qBAAa,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAC,CAAa;gBAEf,OAAO,SAAM,EAAE,KAAK,CAAC,EAAE,UAAU;IAK7C,yDAAyD;IACnD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;IAe3E,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS;IAQzD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI/B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK9B,QAAQ,IAAI,IAAI;IAKhB,qFAAqF;IACrF,aAAa,IAAI,IAAI;IAKrB,OAAO,CAAC,OAAO;CAQhB"}
1
+ {"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC1D,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,IAAI,IAAI,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,SAAS,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,SAAM;IAIzB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;IAc3E,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS;IAMzD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI/B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B,QAAQ,IAAI,IAAI;IAIhB,KAAK,IAAI,IAAI;CAGd;AAID,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEtE;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAMvB"}
@@ -1,20 +1,12 @@
1
- const NS = "queues";
2
- export class WorkQueue {
1
+ /**
2
+ * In-memory WorkQueue — suitable for tests and single-process use
3
+ * where durability is not required. State is lost when the process exits.
4
+ */
5
+ export class MemoryWorkQueue {
3
6
  queues = new Map();
4
7
  maxSize;
5
- store;
6
- constructor(maxSize = 100, store) {
8
+ constructor(maxSize = 100) {
7
9
  this.maxSize = maxSize;
8
- this.store = store;
9
- }
10
- /** Hydrate in-memory state from the persistent store. */
11
- async init() {
12
- if (!this.store)
13
- return;
14
- const entries = await this.store.list(NS);
15
- for (const { key, value } of entries) {
16
- this.queues.set(key, value.map((item) => ({ context: item.context, receivedAt: new Date(item.receivedAt) })));
17
- }
18
10
  }
19
11
  enqueue(agentName, context, receivedAt) {
20
12
  let queue = this.queues.get(agentName);
@@ -27,41 +19,38 @@ export class WorkQueue {
27
19
  dropped = queue.shift();
28
20
  }
29
21
  queue.push({ context, receivedAt: receivedAt || new Date() });
30
- this.persist(agentName);
31
22
  return { accepted: true, dropped };
32
23
  }
33
24
  dequeue(agentName) {
34
25
  const queue = this.queues.get(agentName);
35
26
  if (!queue || queue.length === 0)
36
27
  return undefined;
37
- const item = queue.shift();
38
- this.persist(agentName);
39
- return item;
28
+ return queue.shift();
40
29
  }
41
30
  size(agentName) {
42
31
  return this.queues.get(agentName)?.length ?? 0;
43
32
  }
44
33
  clear(agentName) {
45
34
  this.queues.delete(agentName);
46
- this.store?.delete(NS, agentName).catch(() => { });
47
35
  }
48
36
  clearAll() {
49
37
  this.queues.clear();
50
- this.store?.deleteAll(NS).catch(() => { });
51
38
  }
52
- /** Clear in-memory queues only — persistent state survives for the next instance. */
53
- clearInMemory() {
39
+ close() {
54
40
  this.queues.clear();
55
- // Does NOT touch this.store — persistent state survives for the next instance
56
- }
57
- persist(agentName) {
58
- const queue = this.queues.get(agentName);
59
- if (!queue || queue.length === 0) {
60
- this.store?.delete(NS, agentName).catch(() => { });
61
- }
62
- else {
63
- this.store?.set(NS, agentName, queue, { ttl: 86400 }).catch(() => { }); // 24h TTL
64
- }
65
41
  }
66
42
  }
43
+ /**
44
+ * Create a WorkQueue from configuration.
45
+ *
46
+ * Uses dynamic imports so native modules (better-sqlite3)
47
+ * are only loaded when actually needed.
48
+ */
49
+ export async function createWorkQueue(maxSize, opts) {
50
+ if (opts.type === "sqlite") {
51
+ const { SqliteWorkQueue } = await import("./event-queue-sqlite.js");
52
+ return new SqliteWorkQueue(maxSize, opts.path);
53
+ }
54
+ return new MemoryWorkQueue(maxSize);
55
+ }
67
56
  //# sourceMappingURL=event-queue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"AAmBA;;;GAGG;AACH,MAAM,OAAO,eAAe;IAClB,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IAChD,OAAO,CAAS;IAExB,YAAY,OAAO,GAAG,GAAG;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,SAAiB,EAAE,OAAU,EAAE,UAAiB;QACtD,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAsC,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACnD,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,IAAI,CAAC,SAAiB;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,SAAiB;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACF;AAgBD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,IAAmB;IAEnB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACpE,OAAO,IAAI,eAAe,CAAI,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,eAAe,CAAI,OAAO,CAAC,CAAC;AACzC,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import { type PromptSkills } from "../agents/prompt.js";
2
- import { WorkQueue } from "./event-queue.js";
2
+ import type { WorkQueue } from "./event-queue.js";
3
3
  import { RunnerPool, type PoolRunner } from "./runner-pool.js";
4
4
  import type { AgentConfig } from "../shared/config.js";
5
5
  import type { WebhookContext } from "../webhooks/types.js";
6
6
  import type { createLogger } from "../shared/logger.js";
7
7
  import type { SchedulerEventBus } from "./events.js";
8
8
  import type { CallStore } from "../gateway/call-store.js";
9
+ import type { StatusTracker } from "../tui/status-tracker.js";
9
10
  export declare const DEFAULT_MAX_RERUNS = 10;
10
11
  export declare const DEFAULT_MAX_TRIGGER_DEPTH = 3;
11
12
  export type WorkItem = {
@@ -17,6 +18,8 @@ export type WorkItem = {
17
18
  context: string;
18
19
  depth: number;
19
20
  callId?: string;
21
+ } | {
22
+ type: 'schedule';
20
23
  };
21
24
  export interface RunCompleteEvent {
22
25
  agentName: string;
@@ -39,6 +42,10 @@ export interface SchedulerContext {
39
42
  events?: SchedulerEventBus;
40
43
  /** Optional call store for updating al-call lifecycle status. */
41
44
  callStore?: CallStore;
45
+ /** Optional status tracker — used to check global pause state. */
46
+ statusTracker?: StatusTracker;
47
+ /** Returns false if the named agent has been paused/disabled; undefined = treat as enabled. */
48
+ isAgentEnabled?: (name: string) => boolean;
42
49
  }
43
50
  export declare function makeScheduledPrompt(agentConfig: AgentConfig, ctx: SchedulerContext): string;
44
51
  export declare function makeWebhookPrompt(agentConfig: AgentConfig, context: WebhookContext, ctx: SchedulerContext): string;
@@ -59,7 +66,7 @@ export declare function dispatchTriggers(triggers: Array<{
59
66
  agent: string;
60
67
  context: string;
61
68
  }>, sourceAgent: string, depth: number, ctx: SchedulerContext): void;
62
- /** Drain all agents' work queues, processing items in parallel batches. */
69
+ /** Drain all agents' work queues fires runs without blocking. */
63
70
  export declare function drainQueues(ctx: SchedulerContext): Promise<void>;
64
71
  export declare function runWithReruns(runner: PoolRunner, agentConfig: AgentConfig, depth: number, ctx: SchedulerContext): Promise<void>;
65
72
  //# sourceMappingURL=execution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/scheduler/execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/scheduler/execution.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,11 @@ export function dispatchTriggers(triggers, sourceAgent, depth, ctx) {
53
53
  ctx.logger.info({ source: sourceAgent, target: agent }, "target disabled (scale=0), skipping");
54
54
  continue;
55
55
  }
56
+ if (ctx.isAgentEnabled && !ctx.isAgentEnabled(agent)) {
57
+ ctx.workQueue.enqueue(agent, { type: 'agent-trigger', sourceAgent, context, depth });
58
+ ctx.logger.info({ source: sourceAgent, target: agent }, "target agent is paused, trigger queued");
59
+ continue;
60
+ }
56
61
  const runner = pool.getAvailableRunner();
57
62
  if (!runner) {
58
63
  ctx.workQueue.enqueue(agent, { type: 'agent-trigger', sourceAgent, context, depth });
@@ -66,63 +71,74 @@ export function dispatchTriggers(triggers, sourceAgent, depth, ctx) {
66
71
  .catch((err) => ctx.logger.error({ err, target: agent }, "triggered run failed"));
67
72
  }
68
73
  }
69
- /** Drain all agents' work queues, processing items in parallel batches. */
74
+ /** Drain all agents' work queues fires runs without blocking. */
70
75
  export async function drainQueues(ctx) {
71
- while (!ctx.shuttingDown) {
72
- const batch = [];
73
- for (const agentConfig of ctx.agentConfigs) {
74
- const pool = ctx.runnerPools[agentConfig.name];
75
- if (!pool || ctx.workQueue.size(agentConfig.name) === 0)
76
- continue;
77
- for (const runner of pool.getAllAvailableRunners()) {
78
- const item = ctx.workQueue.dequeue(agentConfig.name);
79
- if (!item)
80
- break;
81
- batch.push({ item, runner, agentConfig });
82
- }
76
+ if (ctx.shuttingDown)
77
+ return;
78
+ if (ctx.statusTracker?.isPaused())
79
+ return;
80
+ for (const agentConfig of ctx.agentConfigs) {
81
+ if (ctx.isAgentEnabled && !ctx.isAgentEnabled(agentConfig.name))
82
+ continue;
83
+ const pool = ctx.runnerPools[agentConfig.name];
84
+ if (!pool || ctx.workQueue.size(agentConfig.name) === 0)
85
+ continue;
86
+ for (const runner of pool.getAllAvailableRunners()) {
87
+ const item = ctx.workQueue.dequeue(agentConfig.name);
88
+ if (!item)
89
+ break;
90
+ fireQueuedItem(item, runner, agentConfig, ctx);
83
91
  }
84
- if (batch.length === 0)
85
- break;
86
- await Promise.all(batch.map(({ item, runner, agentConfig }) => {
87
- const work = item.context;
88
- const ageMs = Date.now() - item.receivedAt.getTime();
89
- if (work.type === 'webhook') {
90
- ctx.logger.info({ agent: agentConfig.name, event: work.context.event, ageMs }, "draining queued webhook");
91
- const prompt = makeWebhookPrompt(agentConfig, work.context, ctx);
92
- return executeRun(runner, prompt, { type: 'webhook', source: work.context.event }, agentConfig.name, 0, ctx)
93
- .catch((err) => ctx.logger.error({ err, agent: agentConfig.name }, "queued webhook failed"));
94
- }
95
- else {
96
- if (work.depth >= ctx.maxTriggerDepth)
97
- return Promise.resolve();
98
- ctx.logger.info({ source: work.sourceAgent, target: agentConfig.name, depth: work.depth, ageMs }, "draining queued trigger");
99
- const prompt = makeTriggeredPrompt(agentConfig, work.sourceAgent, work.context, ctx);
100
- if (work.callId)
101
- ctx.callStore?.setRunning(work.callId);
102
- return executeRun(runner, prompt, { type: 'agent', source: work.sourceAgent }, agentConfig.name, work.depth + 1, ctx)
103
- .then(({ result, returnValue }) => {
104
- if (work.callId) {
105
- if (result === "completed" || result === "rerun") {
106
- ctx.callStore?.complete(work.callId, returnValue);
107
- }
108
- else {
109
- ctx.callStore?.fail(work.callId, "agent run failed");
110
- }
111
- }
112
- })
113
- .catch((err) => {
114
- if (work.callId)
115
- ctx.callStore?.fail(work.callId, err?.message || "unknown error");
116
- ctx.logger.error({ err, agent: agentConfig.name }, "queued trigger failed");
117
- });
92
+ }
93
+ }
94
+ function fireQueuedItem(item, runner, agentConfig, ctx) {
95
+ const work = item.context;
96
+ const ageMs = Date.now() - item.receivedAt.getTime();
97
+ if (work.type === 'webhook') {
98
+ ctx.logger.info({ agent: agentConfig.name, event: work.context.event, ageMs }, "draining queued webhook");
99
+ const prompt = makeWebhookPrompt(agentConfig, work.context, ctx);
100
+ executeRun(runner, prompt, { type: 'webhook', source: work.context.event }, agentConfig.name, 0, ctx)
101
+ .then(() => drainQueues(ctx))
102
+ .catch((err) => ctx.logger.error({ err, agent: agentConfig.name }, "queued webhook failed"));
103
+ }
104
+ else if (work.type === 'agent-trigger') {
105
+ if (work.depth >= ctx.maxTriggerDepth)
106
+ return;
107
+ ctx.logger.info({ source: work.sourceAgent, target: agentConfig.name, depth: work.depth, ageMs }, "draining queued trigger");
108
+ const prompt = makeTriggeredPrompt(agentConfig, work.sourceAgent, work.context, ctx);
109
+ if (work.callId)
110
+ ctx.callStore?.setRunning(work.callId);
111
+ executeRun(runner, prompt, { type: 'agent', source: work.sourceAgent }, agentConfig.name, work.depth + 1, ctx)
112
+ .then(({ result, returnValue }) => {
113
+ if (work.callId) {
114
+ if (result === "completed" || result === "rerun")
115
+ ctx.callStore?.complete(work.callId, returnValue);
116
+ else
117
+ ctx.callStore?.fail(work.callId, "agent run failed");
118
118
  }
119
- }));
119
+ return drainQueues(ctx);
120
+ })
121
+ .catch((err) => {
122
+ if (work.callId)
123
+ ctx.callStore?.fail(work.callId, err?.message || "unknown error");
124
+ ctx.logger.error({ err, agent: agentConfig.name }, "queued trigger failed");
125
+ });
126
+ }
127
+ else if (work.type === 'schedule') {
128
+ ctx.logger.info({ agent: agentConfig.name, ageMs }, "draining queued scheduled run");
129
+ // runWithReruns already calls drainQueues on completion
130
+ runWithReruns(runner, agentConfig, 0, ctx)
131
+ .catch((err) => ctx.logger.error({ err, agent: agentConfig.name }, "queued scheduled run failed"));
120
132
  }
121
133
  }
122
134
  export async function runWithReruns(runner, agentConfig, depth, ctx) {
123
135
  let { result } = await executeRun(runner, makeScheduledPrompt(agentConfig, ctx), { type: 'schedule' }, agentConfig.name, depth, ctx);
124
136
  let reruns = 0;
125
137
  while (result === "rerun" && reruns < ctx.maxReruns) {
138
+ if (ctx.isAgentEnabled && !ctx.isAgentEnabled(agentConfig.name)) {
139
+ ctx.logger.info({ agent: agentConfig.name }, "agent paused, stopping reruns");
140
+ break;
141
+ }
126
142
  reruns++;
127
143
  ctx.logger.info({ rerun: reruns, maxReruns: ctx.maxReruns }, `${agentConfig.name} requested rerun`);
128
144
  ({ result } = await executeRun(runner, makeScheduledPrompt(agentConfig, ctx), { type: 'schedule', source: `rerun ${reruns}/${ctx.maxReruns}` }, agentConfig.name, depth, ctx));