@action-llama/action-llama 0.11.0 → 0.11.2

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 (133) hide show
  1. package/README.md +25 -18
  2. package/dist/agents/container-entry.d.ts.map +1 -1
  3. package/dist/agents/container-entry.js +9 -0
  4. package/dist/agents/container-entry.js.map +1 -1
  5. package/dist/agents/container-runner.d.ts +1 -1
  6. package/dist/agents/container-runner.d.ts.map +1 -1
  7. package/dist/agents/container-runner.js +2 -12
  8. package/dist/agents/container-runner.js.map +1 -1
  9. package/dist/agents/runner.d.ts.map +1 -1
  10. package/dist/agents/runner.js +16 -0
  11. package/dist/agents/runner.js.map +1 -1
  12. package/dist/cli/commands/chat.js +1 -1
  13. package/dist/cli/commands/cloud-deploy.js +1 -1
  14. package/dist/cli/commands/doctor.js +2 -2
  15. package/dist/cli/commands/logs.js +1 -1
  16. package/dist/cli/commands/run.d.ts.map +1 -1
  17. package/dist/cli/commands/run.js +9 -5
  18. package/dist/cli/commands/run.js.map +1 -1
  19. package/dist/cli/commands/start.js +3 -3
  20. package/dist/cli/commands/start.js.map +1 -1
  21. package/dist/cli/commands/status.d.ts +1 -0
  22. package/dist/cli/commands/status.d.ts.map +1 -1
  23. package/dist/cli/commands/status.js +167 -56
  24. package/dist/cli/commands/status.js.map +1 -1
  25. package/dist/cli/main.js +24 -16
  26. package/dist/cli/main.js.map +1 -1
  27. package/dist/cloud/aws/constants.d.ts +2 -0
  28. package/dist/cloud/aws/constants.d.ts.map +1 -1
  29. package/dist/cloud/aws/constants.js +2 -0
  30. package/dist/cloud/aws/constants.js.map +1 -1
  31. package/dist/cloud/aws/deploy.d.ts.map +1 -1
  32. package/dist/cloud/aws/deploy.js +68 -2
  33. package/dist/cloud/aws/deploy.js.map +1 -1
  34. package/dist/cloud/aws/iam.js +1 -1
  35. package/dist/cloud/aws/provision.d.ts.map +1 -1
  36. package/dist/cloud/aws/provision.js +52 -1
  37. package/dist/cloud/aws/provision.js.map +1 -1
  38. package/dist/cloud/scheduler-image.js +1 -1
  39. package/dist/cloud/scheduler-image.js.map +1 -1
  40. package/dist/docker/runtime.d.ts +1 -0
  41. package/dist/docker/runtime.d.ts.map +1 -1
  42. package/dist/gateway/call-store.d.ts +6 -1
  43. package/dist/gateway/call-store.d.ts.map +1 -1
  44. package/dist/gateway/call-store.js +25 -1
  45. package/dist/gateway/call-store.js.map +1 -1
  46. package/dist/gateway/container-registry.d.ts +25 -0
  47. package/dist/gateway/container-registry.d.ts.map +1 -0
  48. package/dist/gateway/container-registry.js +43 -0
  49. package/dist/gateway/container-registry.js.map +1 -0
  50. package/dist/gateway/index.d.ts +6 -2
  51. package/dist/gateway/index.d.ts.map +1 -1
  52. package/dist/gateway/index.js +18 -10
  53. package/dist/gateway/index.js.map +1 -1
  54. package/dist/gateway/lock-store.d.ts +7 -1
  55. package/dist/gateway/lock-store.d.ts.map +1 -1
  56. package/dist/gateway/lock-store.js +37 -7
  57. package/dist/gateway/lock-store.js.map +1 -1
  58. package/dist/gateway/routes/calls.d.ts +2 -2
  59. package/dist/gateway/routes/calls.d.ts.map +1 -1
  60. package/dist/gateway/routes/calls.js.map +1 -1
  61. package/dist/gateway/routes/dashboard.d.ts +6 -0
  62. package/dist/gateway/routes/dashboard.d.ts.map +1 -1
  63. package/dist/gateway/routes/dashboard.js +14 -8
  64. package/dist/gateway/routes/dashboard.js.map +1 -1
  65. package/dist/gateway/routes/locks.d.ts +2 -2
  66. package/dist/gateway/routes/locks.d.ts.map +1 -1
  67. package/dist/gateway/routes/locks.js.map +1 -1
  68. package/dist/gateway/routes/shutdown.d.ts +2 -2
  69. package/dist/gateway/routes/shutdown.d.ts.map +1 -1
  70. package/dist/gateway/routes/shutdown.js +1 -1
  71. package/dist/gateway/routes/shutdown.js.map +1 -1
  72. package/dist/gateway/routes/signals.d.ts +2 -2
  73. package/dist/gateway/routes/signals.d.ts.map +1 -1
  74. package/dist/gateway/routes/signals.js.map +1 -1
  75. package/dist/preflight/interpolate.d.ts +10 -0
  76. package/dist/preflight/interpolate.d.ts.map +1 -0
  77. package/dist/preflight/interpolate.js +33 -0
  78. package/dist/preflight/interpolate.js.map +1 -0
  79. package/dist/preflight/providers/git-clone.d.ts +3 -0
  80. package/dist/preflight/providers/git-clone.d.ts.map +1 -0
  81. package/dist/preflight/providers/git-clone.js +36 -0
  82. package/dist/preflight/providers/git-clone.js.map +1 -0
  83. package/dist/preflight/providers/http.d.ts +3 -0
  84. package/dist/preflight/providers/http.d.ts.map +1 -0
  85. package/dist/preflight/providers/http.js +36 -0
  86. package/dist/preflight/providers/http.js.map +1 -0
  87. package/dist/preflight/providers/shell.d.ts +3 -0
  88. package/dist/preflight/providers/shell.d.ts.map +1 -0
  89. package/dist/preflight/providers/shell.js +28 -0
  90. package/dist/preflight/providers/shell.js.map +1 -0
  91. package/dist/preflight/registry.d.ts +4 -0
  92. package/dist/preflight/registry.d.ts.map +1 -0
  93. package/dist/preflight/registry.js +20 -0
  94. package/dist/preflight/registry.js.map +1 -0
  95. package/dist/preflight/runner.d.ts +7 -0
  96. package/dist/preflight/runner.d.ts.map +1 -0
  97. package/dist/preflight/runner.js +28 -0
  98. package/dist/preflight/runner.js.map +1 -0
  99. package/dist/preflight/schema.d.ts +21 -0
  100. package/dist/preflight/schema.d.ts.map +1 -0
  101. package/dist/preflight/schema.js +9 -0
  102. package/dist/preflight/schema.js.map +1 -0
  103. package/dist/scheduler/event-queue.d.ts +6 -1
  104. package/dist/scheduler/event-queue.d.ts.map +1 -1
  105. package/dist/scheduler/event-queue.js +28 -2
  106. package/dist/scheduler/event-queue.js.map +1 -1
  107. package/dist/scheduler/index.d.ts.map +1 -1
  108. package/dist/scheduler/index.js +138 -24
  109. package/dist/scheduler/index.js.map +1 -1
  110. package/dist/scheduler/runner-pool.d.ts +6 -16
  111. package/dist/scheduler/runner-pool.d.ts.map +1 -1
  112. package/dist/scheduler/runner-pool.js +15 -26
  113. package/dist/scheduler/runner-pool.js.map +1 -1
  114. package/dist/shared/config.d.ts +2 -0
  115. package/dist/shared/config.d.ts.map +1 -1
  116. package/dist/shared/config.js +2 -2
  117. package/dist/shared/config.js.map +1 -1
  118. package/dist/shared/state-store-dynamo.d.ts +39 -0
  119. package/dist/shared/state-store-dynamo.d.ts.map +1 -0
  120. package/dist/shared/state-store-dynamo.js +143 -0
  121. package/dist/shared/state-store-dynamo.js.map +1 -0
  122. package/dist/shared/state-store-sqlite.d.ts +28 -0
  123. package/dist/shared/state-store-sqlite.d.ts.map +1 -0
  124. package/dist/shared/state-store-sqlite.js +78 -0
  125. package/dist/shared/state-store-sqlite.js.map +1 -0
  126. package/dist/shared/state-store.d.ts +51 -0
  127. package/dist/shared/state-store.d.ts.map +1 -0
  128. package/dist/shared/state-store.js +31 -0
  129. package/dist/shared/state-store.js.map +1 -0
  130. package/dist/webhooks/providers/github.d.ts.map +1 -1
  131. package/dist/webhooks/providers/github.js +3 -0
  132. package/dist/webhooks/providers/github.js.map +1 -1
  133. package/package.json +6 -2
@@ -0,0 +1,36 @@
1
+ import { writeFileSync, mkdirSync } from "fs";
2
+ import { dirname } from "path";
3
+ import { interpolateParams } from "../interpolate.js";
4
+ export const httpProvider = {
5
+ id: "http",
6
+ async run(params, ctx) {
7
+ const resolved = interpolateParams(params, ctx.env);
8
+ const url = resolved.url;
9
+ if (typeof url !== "string" || !url) {
10
+ throw new Error("http provider requires a 'url' param");
11
+ }
12
+ const output = resolved.output;
13
+ if (typeof output !== "string" || !output) {
14
+ throw new Error("http provider requires an 'output' param");
15
+ }
16
+ const method = (typeof resolved.method === "string" ? resolved.method : "GET").toUpperCase();
17
+ const headers = {};
18
+ if (resolved.headers && typeof resolved.headers === "object" && !Array.isArray(resolved.headers)) {
19
+ for (const [k, v] of Object.entries(resolved.headers)) {
20
+ if (typeof v === "string")
21
+ headers[k] = v;
22
+ }
23
+ }
24
+ const body = typeof resolved.body === "string" ? resolved.body : undefined;
25
+ ctx.logger("info", "preflight http", { method, url: url.slice(0, 200) });
26
+ const response = await fetch(url, { method, headers, body });
27
+ if (!response.ok) {
28
+ throw new Error(`HTTP ${response.status} ${response.statusText} from ${url}`);
29
+ }
30
+ const buffer = Buffer.from(await response.arrayBuffer());
31
+ mkdirSync(dirname(output), { recursive: true });
32
+ writeFileSync(output, buffer);
33
+ ctx.logger("info", "preflight http output written", { path: output, bytes: buffer.length });
34
+ },
35
+ };
36
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/preflight/providers/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAqB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,EAAE,EAAE,MAAM;IAEV,KAAK,CAAC,GAAG,CAAC,MAA+B,EAAE,GAAqB;QAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;QACzB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7F,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,QAAQ,CAAC,OAAO,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjG,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAkC,CAAC,EAAE,CAAC;gBACjF,IAAI,OAAO,CAAC,KAAK,QAAQ;oBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAE3E,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,SAAS,GAAG,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QACzD,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,+BAA+B,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9F,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PreflightProvider } from "../schema.js";
2
+ export declare const shellProvider: PreflightProvider;
3
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/preflight/providers/shell.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,cAAc,CAAC;AAGxE,eAAO,MAAM,aAAa,EAAE,iBA0B3B,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { execSync } from "child_process";
2
+ import { writeFileSync, mkdirSync } from "fs";
3
+ import { dirname } from "path";
4
+ import { interpolateParams } from "../interpolate.js";
5
+ export const shellProvider = {
6
+ id: "shell",
7
+ async run(params, ctx) {
8
+ const resolved = interpolateParams(params, ctx.env);
9
+ const command = resolved.command;
10
+ if (typeof command !== "string" || !command) {
11
+ throw new Error("shell provider requires a 'command' param");
12
+ }
13
+ const output = typeof resolved.output === "string" ? resolved.output : undefined;
14
+ ctx.logger("info", "preflight shell", { command: command.slice(0, 200) });
15
+ const stdout = execSync(command, {
16
+ shell: "/bin/sh",
17
+ env: ctx.env,
18
+ stdio: output ? ["pipe", "pipe", "pipe"] : ["pipe", "inherit", "pipe"],
19
+ maxBuffer: 50 * 1024 * 1024, // 50 MB
20
+ });
21
+ if (output) {
22
+ mkdirSync(dirname(output), { recursive: true });
23
+ writeFileSync(output, stdout);
24
+ ctx.logger("info", "preflight shell output written", { path: output, bytes: stdout.length });
25
+ }
26
+ },
27
+ };
28
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/preflight/providers/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAqB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC9C,EAAE,EAAE,OAAO;IAEX,KAAK,CAAC,GAAG,CAAC,MAA+B,EAAE,GAAqB;QAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAEjF,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAE1E,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC/B,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC;YACtE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,QAAQ;SACtC,CAAC,CAAC;QAEH,IAAI,MAAM,EAAE,CAAC;YACX,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,gCAAgC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PreflightProvider } from "./schema.js";
2
+ export declare function resolvePreflightProvider(id: string): PreflightProvider;
3
+ export declare function listPreflightProviders(): string[];
4
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/preflight/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAWrD,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAOtE;AAED,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD"}
@@ -0,0 +1,20 @@
1
+ import { shellProvider } from "./providers/shell.js";
2
+ import { httpProvider } from "./providers/http.js";
3
+ import { gitCloneProvider } from "./providers/git-clone.js";
4
+ const builtinProviders = {
5
+ [shellProvider.id]: shellProvider,
6
+ [httpProvider.id]: httpProvider,
7
+ [gitCloneProvider.id]: gitCloneProvider,
8
+ };
9
+ export function resolvePreflightProvider(id) {
10
+ const provider = builtinProviders[id];
11
+ if (!provider) {
12
+ const available = Object.keys(builtinProviders).join(", ");
13
+ throw new Error(`Unknown preflight provider "${id}". Available: ${available}`);
14
+ }
15
+ return provider;
16
+ }
17
+ export function listPreflightProviders() {
18
+ return Object.keys(builtinProviders);
19
+ }
20
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/preflight/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,gBAAgB,GAAsC;IAC1D,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,aAAa;IACjC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,YAAY;IAC/B,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,gBAAgB;CACxC,CAAC;AAEF,MAAM,UAAU,wBAAwB,CAAC,EAAU;IACjD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,iBAAiB,SAAS,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { PreflightStep, PreflightContext } from "./schema.js";
2
+ /**
3
+ * Run all preflight steps sequentially. If a required step fails, throws.
4
+ * Optional steps log a warning and continue.
5
+ */
6
+ export declare function runPreflight(steps: PreflightStep[], ctx: PreflightContext): Promise<void>;
7
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/preflight/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGnE;;;GAGG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,aAAa,EAAE,EACtB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -0,0 +1,28 @@
1
+ import { resolvePreflightProvider } from "./registry.js";
2
+ /**
3
+ * Run all preflight steps sequentially. If a required step fails, throws.
4
+ * Optional steps log a warning and continue.
5
+ */
6
+ export async function runPreflight(steps, ctx) {
7
+ ctx.logger("info", "preflight starting", { stepCount: steps.length });
8
+ for (let i = 0; i < steps.length; i++) {
9
+ const step = steps[i];
10
+ const required = step.required !== false; // default true
11
+ const label = `[${i + 1}/${steps.length}] ${step.provider}`;
12
+ try {
13
+ const provider = resolvePreflightProvider(step.provider);
14
+ await provider.run(step.params, ctx);
15
+ ctx.logger("info", `preflight step ${label} done`);
16
+ }
17
+ catch (err) {
18
+ const msg = err?.message || String(err);
19
+ if (required) {
20
+ ctx.logger("error", `preflight step ${label} failed (required)`, { error: msg });
21
+ throw new Error(`Required preflight step "${step.provider}" failed: ${msg}`);
22
+ }
23
+ ctx.logger("warn", `preflight step ${label} failed (optional, continuing)`, { error: msg });
24
+ }
25
+ }
26
+ ctx.logger("info", "preflight complete");
27
+ }
28
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/preflight/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAsB,EACtB,GAAqB;IAErB,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,eAAe;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE5D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACrC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,KAAK,oBAAoB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBACjF,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,QAAQ,aAAa,GAAG,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,KAAK,gCAAgC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Preflight step types and provider interface.
3
+ *
4
+ * Preflight steps run mechanical data-staging tasks (clone repos, fetch URLs,
5
+ * run shell commands) inside the container after credentials are loaded but
6
+ * before the LLM session starts. ACTIONS.md references the staged files.
7
+ */
8
+ export interface PreflightStep {
9
+ provider: string;
10
+ required?: boolean;
11
+ params: Record<string, unknown>;
12
+ }
13
+ export interface PreflightContext {
14
+ env: Record<string, string>;
15
+ logger: (level: string, msg: string, data?: Record<string, any>) => void;
16
+ }
17
+ export interface PreflightProvider {
18
+ id: string;
19
+ run(params: Record<string, unknown>, ctx: PreflightContext): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/preflight/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CAC1E;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Preflight step types and provider interface.
3
+ *
4
+ * Preflight steps run mechanical data-staging tasks (clone repos, fetch URLs,
5
+ * run shell commands) inside the container after credentials are loaded but
6
+ * before the LLM session starts. ACTIONS.md references the staged files.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/preflight/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -1,3 +1,4 @@
1
+ import type { StateStore } from "../shared/state-store.js";
1
2
  export interface QueuedEvent {
2
3
  agentType: string;
3
4
  text: string;
@@ -20,12 +21,16 @@ export interface EnqueueResult<T> {
20
21
  export declare class WorkQueue<T> {
21
22
  private queues;
22
23
  private maxSize;
23
- constructor(maxSize?: number);
24
+ private store?;
25
+ constructor(maxSize?: number, store?: StateStore);
26
+ /** Hydrate in-memory state from the persistent store. */
27
+ init(): Promise<void>;
24
28
  enqueue(agentName: string, context: T, receivedAt?: Date): EnqueueResult<T>;
25
29
  dequeue(agentName: string): QueuedWorkItem<T> | undefined;
26
30
  size(agentName: string): number;
27
31
  clear(agentName: string): void;
28
32
  clearAll(): void;
33
+ private persist;
29
34
  }
30
35
  /** @deprecated Use WorkQueue instead */
31
36
  export declare const WebhookEventQueue: typeof WorkQueue;
@@ -1 +1 @@
1
- {"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAEzD,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAItC,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;CAK/B;AAID,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,qBAAa,SAAS,CAAC,CAAC;IACtB,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;CAGjB;AAED,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,kBAAY,CAAC;AAC3C,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC"}
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,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAEzD,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAItC,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;CAK/B;AAID,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,OAAO,CAAC,OAAO;CAQhB;AAED,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,kBAAY,CAAC;AAC3C,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC"}
@@ -9,11 +9,23 @@ export class EventQueue {
9
9
  }
10
10
  }
11
11
  }
12
+ const NS = "queues";
12
13
  export class WorkQueue {
13
14
  queues = new Map();
14
15
  maxSize;
15
- constructor(maxSize = 100) {
16
+ store;
17
+ constructor(maxSize = 100, store) {
16
18
  this.maxSize = maxSize;
19
+ this.store = store;
20
+ }
21
+ /** Hydrate in-memory state from the persistent store. */
22
+ async init() {
23
+ if (!this.store)
24
+ return;
25
+ const entries = await this.store.list(NS);
26
+ for (const { key, value } of entries) {
27
+ this.queues.set(key, value.map((item) => ({ context: item.context, receivedAt: new Date(item.receivedAt) })));
28
+ }
17
29
  }
18
30
  enqueue(agentName, context, receivedAt) {
19
31
  let queue = this.queues.get(agentName);
@@ -26,22 +38,36 @@ export class WorkQueue {
26
38
  dropped = queue.shift();
27
39
  }
28
40
  queue.push({ context, receivedAt: receivedAt || new Date() });
41
+ this.persist(agentName);
29
42
  return { accepted: true, dropped };
30
43
  }
31
44
  dequeue(agentName) {
32
45
  const queue = this.queues.get(agentName);
33
46
  if (!queue || queue.length === 0)
34
47
  return undefined;
35
- return queue.shift();
48
+ const item = queue.shift();
49
+ this.persist(agentName);
50
+ return item;
36
51
  }
37
52
  size(agentName) {
38
53
  return this.queues.get(agentName)?.length ?? 0;
39
54
  }
40
55
  clear(agentName) {
41
56
  this.queues.delete(agentName);
57
+ this.store?.delete(NS, agentName).catch(() => { });
42
58
  }
43
59
  clearAll() {
44
60
  this.queues.clear();
61
+ this.store?.deleteAll(NS).catch(() => { });
62
+ }
63
+ persist(agentName) {
64
+ const queue = this.queues.get(agentName);
65
+ if (!queue || queue.length === 0) {
66
+ this.store?.delete(NS, agentName).catch(() => { });
67
+ }
68
+ else {
69
+ this.store?.set(NS, agentName, queue, { ttl: 86400 }).catch(() => { }); // 24h TTL
70
+ }
45
71
  }
46
72
  }
47
73
  /** @deprecated Use WorkQueue instead */
@@ -1 +1 @@
1
- {"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,UAAU;IACb,SAAS,GAAoB,EAAE,CAAC;IAExC,OAAO,CAAC,QAAuB;QAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,CAAC,KAAkB;QACrB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;CACF;AAcD,MAAM,OAAO,SAAS;IACZ,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;CACF;AAED,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../src/scheduler/event-queue.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAmM/D,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO;;;;;;;GAke3L"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAgR/D,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO;;;;;;;GAuhB3L"}
@@ -47,7 +47,8 @@ function dispatchTriggers(triggers, sourceAgent, depth, ctx) {
47
47
  }
48
48
  const availableRunner = pool.getAvailableRunner();
49
49
  if (!availableRunner) {
50
- ctx.logger.warn({ source: sourceAgent, target: agent, running: pool.runningJobCount, scale: pool.size }, "all agent runners busy, skipping trigger");
50
+ ctx.agentTriggerQueue.enqueue(agent, { sourceAgent, context, depth });
51
+ ctx.logger.info({ source: sourceAgent, target: agent, running: pool.runningJobCount, scale: pool.size }, "all runners busy, agent trigger queued");
51
52
  continue;
52
53
  }
53
54
  ctx.logger.info({ source: sourceAgent, target: agent, depth, running: pool.runningJobCount, scale: pool.size }, "agent trigger firing");
@@ -79,30 +80,84 @@ async function runTriggered(runner, agentConfig, prompt, sourceAgent, depth, ctx
79
80
  if (result === "completed") {
80
81
  ctx.logger.info(`${agentConfig.name} triggered run completed`);
81
82
  }
83
+ // Drain any queued agent triggers that arrived while this runner was busy
84
+ await drainAgentTriggerQueue(ctx);
82
85
  }, {}, SpanKind.INTERNAL);
83
86
  }
84
87
  async function drainWebhookQueue(agentConfig, ctx) {
85
88
  const pool = ctx.runnerPools[agentConfig.name];
86
- let event;
87
- while (!ctx.shuttingDown && (event = ctx.webhookQueue.dequeue(agentConfig.name)) !== undefined) {
88
- const runner = pool.getAvailableRunner();
89
- if (!runner) {
90
- // Put the event back in the queue if no runners are available
91
- ctx.webhookQueue.enqueue(agentConfig.name, event.context, event.receivedAt);
89
+ while (!ctx.shuttingDown && ctx.webhookQueue.size(agentConfig.name) > 0) {
90
+ // Get all available runners at once
91
+ const availableRunners = pool.getAllAvailableRunners();
92
+ if (availableRunners.length === 0) {
93
+ // No runners available, stop draining
92
94
  break;
93
95
  }
94
- const ageMs = Date.now() - event.receivedAt.getTime();
95
- ctx.logger.info({ agent: agentConfig.name, event: event.context.event, ageMs, remaining: ctx.webhookQueue.size(agentConfig.name), running: pool.runningJobCount, scale: pool.size }, "processing queued webhook event");
96
- try {
97
- const prompt = makeWebhookPrompt(agentConfig, event.context, ctx);
98
- const { triggers } = await runner.run(prompt, { type: 'webhook', source: event.context.event });
99
- if (triggers.length > 0) {
100
- dispatchTriggers(triggers, agentConfig.name, 0, ctx);
101
- }
96
+ // Dequeue events up to the number of available runners
97
+ const eventsToProcess = [];
98
+ for (const runner of availableRunners) {
99
+ const event = ctx.webhookQueue.dequeue(agentConfig.name);
100
+ if (!event)
101
+ break; // No more events in queue
102
+ eventsToProcess.push({ event, runner });
102
103
  }
103
- catch (err) {
104
- ctx.logger.error({ err, agent: agentConfig.name }, "queued webhook run failed");
104
+ if (eventsToProcess.length === 0)
105
+ break; // No events to process
106
+ // Process all events in parallel
107
+ const promises = eventsToProcess.map(({ event, runner }) => {
108
+ const ageMs = Date.now() - event.receivedAt.getTime();
109
+ ctx.logger.info({
110
+ agent: agentConfig.name,
111
+ event: event.context.event,
112
+ ageMs,
113
+ remaining: ctx.webhookQueue.size(agentConfig.name),
114
+ running: pool.runningJobCount + eventsToProcess.length,
115
+ scale: pool.size
116
+ }, "processing queued webhook event");
117
+ return (async () => {
118
+ try {
119
+ const prompt = makeWebhookPrompt(agentConfig, event.context, ctx);
120
+ const { triggers } = await runner.run(prompt, { type: 'webhook', source: event.context.event });
121
+ if (triggers.length > 0) {
122
+ dispatchTriggers(triggers, agentConfig.name, 0, ctx);
123
+ }
124
+ }
125
+ catch (err) {
126
+ ctx.logger.error({ err, agent: agentConfig.name }, "queued webhook run failed");
127
+ }
128
+ })();
129
+ });
130
+ // Wait for all parallel runs to complete before checking for more events
131
+ await Promise.all(promises);
132
+ }
133
+ }
134
+ async function drainAgentTriggerQueue(ctx) {
135
+ while (!ctx.shuttingDown) {
136
+ // Collect one batch: for each agent with queued triggers, pair triggers with available runners
137
+ const batch = [];
138
+ for (const agentConfig of ctx.agentConfigs) {
139
+ const pool = ctx.runnerPools[agentConfig.name];
140
+ if (!pool || ctx.agentTriggerQueue.size(agentConfig.name) === 0)
141
+ continue;
142
+ const availableRunners = pool.getAllAvailableRunners();
143
+ for (const runner of availableRunners) {
144
+ const item = ctx.agentTriggerQueue.dequeue(agentConfig.name);
145
+ if (!item)
146
+ break;
147
+ batch.push({ trigger: item.context, runner, agentConfig });
148
+ }
105
149
  }
150
+ if (batch.length === 0)
151
+ break;
152
+ await Promise.all(batch
153
+ .filter(({ trigger }) => trigger.depth < ctx.maxTriggerDepth)
154
+ .map(({ trigger, runner, agentConfig }) => {
155
+ ctx.logger.info({ source: trigger.sourceAgent, target: agentConfig.name, depth: trigger.depth }, "processing queued agent trigger");
156
+ const prompt = makeTriggeredPrompt(agentConfig, trigger.sourceAgent, trigger.context, ctx);
157
+ return runTriggered(runner, agentConfig, prompt, trigger.sourceAgent, trigger.depth, ctx).catch((err) => {
158
+ ctx.logger.error({ err, target: agentConfig.name }, "queued trigger run failed");
159
+ });
160
+ }));
106
161
  }
107
162
  }
108
163
  async function runWithReruns(runner, agentConfig, depth, ctx) {
@@ -138,6 +193,8 @@ async function runWithReruns(runner, agentConfig, depth, ctx) {
138
193
  }
139
194
  // Drain any webhook events that arrived during the rerun cycle
140
195
  await drainWebhookQueue(agentConfig, ctx);
196
+ // Drain any agent-to-agent triggers that arrived while this runner was busy
197
+ await drainAgentTriggerQueue(ctx);
141
198
  }, {}, SpanKind.INTERNAL);
142
199
  }
143
200
  export async function startScheduler(projectPath, globalConfigOverride, statusTracker, cloudMode, gatewayEnabled, webUI) {
@@ -231,6 +288,28 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
231
288
  // They are populated after image builds complete.
232
289
  const runnerPools = {};
233
290
  let cronJobs = [];
291
+ // Create persistent state store (SQLite locally, DynamoDB in cloud).
292
+ let stateStore;
293
+ if (gatewayEnabled) {
294
+ const { createStateStore } = await import("../shared/state-store.js");
295
+ const useCloudStore = cloudMode && globalConfig.cloud;
296
+ if (useCloudStore && globalConfig.cloud?.provider === "ecs") {
297
+ stateStore = await createStateStore({
298
+ type: "dynamodb",
299
+ region: globalConfig.cloud.awsRegion,
300
+ tableName: "al-state",
301
+ });
302
+ logger.info("State store: DynamoDB (al-state)");
303
+ }
304
+ else {
305
+ const { resolve: resolvePath } = await import("path");
306
+ stateStore = await createStateStore({
307
+ type: "sqlite",
308
+ path: resolvePath(projectPath, ".al", "state.db"),
309
+ });
310
+ logger.info("State store: SQLite (.al/state.db)");
311
+ }
312
+ }
234
313
  // Start gateway early if needed (before Docker builds) so users can see build status
235
314
  let gateway;
236
315
  if (gatewayEnabled) {
@@ -253,6 +332,7 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
253
332
  webUI: cloudMode ? false : webUI,
254
333
  lockTimeout: globalConfig.gateway?.lockTimeout,
255
334
  apiKey: gatewayApiKey,
335
+ stateStore,
256
336
  // Control routes, dashboard, and lock status are local-only.
257
337
  // In cloud mode, use cloud-native tools (console, CLI) for these operations.
258
338
  controlDeps: cloudMode ? undefined : {
@@ -327,6 +407,28 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
327
407
  // 1. Create the container runtime
328
408
  const { runtime, agentRuntimeOverrides, runtimeType } = await createContainerRuntime(globalConfig, activeAgentConfigs, cloudMode, logger);
329
409
  logger.info({ runtime: runtimeType }, "Container mode enabled — initializing infrastructure");
410
+ // Check for orphan containers from a previous scheduler run
411
+ try {
412
+ const orphans = await runtime.listRunningAgents();
413
+ if (orphans.length > 0) {
414
+ for (const orphan of orphans) {
415
+ logger.warn({ agent: orphan.agentName, task: orphan.taskId }, "found orphan container");
416
+ }
417
+ if (runtimeType === "local") {
418
+ for (const orphan of orphans) {
419
+ try {
420
+ await runtime.kill(orphan.taskId);
421
+ await runtime.remove(orphan.taskId);
422
+ }
423
+ catch { }
424
+ }
425
+ logger.info({ count: orphans.length }, "cleaned up local orphan containers");
426
+ }
427
+ }
428
+ }
429
+ catch (err) {
430
+ logger.debug({ err }, "orphan detection skipped (runtime does not support listing)");
431
+ }
330
432
  // 2. Build base + per-agent images via shared image builder
331
433
  const buildSkills = { locking: true };
332
434
  const buildResult = await buildAgentImages({
@@ -347,13 +449,14 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
347
449
  if (gatewayEnabled && useCloudRuntime && !gatewayUrl) {
348
450
  logger.warn("Cloud mode is active but gateway URL is not set (via GATEWAY_URL env or gateway.url config) — resource locking and shutdown will not work for cloud containers");
349
451
  }
350
- // Gateway callbacks — no-ops if gateway isn't running (remote runtimes)
452
+ // Gateway callbacks — no-ops if gateway isn't running (remote runtimes).
453
+ // Both are async (ContainerRegistry persists to StateStore).
351
454
  const registerContainer = gateway
352
455
  ? gateway.registerContainer
353
- : (_secret, _reg) => { };
456
+ : async (_secret, _reg) => { };
354
457
  const unregisterContainer = gateway
355
458
  ? gateway.unregisterContainer
356
- : (_secret) => { };
459
+ : async (_secret) => { };
357
460
  for (const agentConfig of agentConfigs) {
358
461
  const scale = agentConfig.scale ?? 1;
359
462
  const runners = [];
@@ -366,9 +469,11 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
366
469
  logger.info({ agent: agentConfig.name, scale }, "Created runner pool");
367
470
  }
368
471
  const webhookQueueSize = globalConfig.workQueueSize ?? globalConfig.webhookQueueSize ?? 20;
369
- const webhookQueue = new WorkQueue(webhookQueueSize);
472
+ const webhookQueue = new WorkQueue(webhookQueueSize, stateStore);
473
+ await webhookQueue.init();
474
+ const agentTriggerQueue = new WorkQueue(webhookQueueSize);
370
475
  const skills = { locking: true };
371
- const schedulerCtx = { runnerPools, agentConfigs, maxReruns, maxTriggerDepth, logger, webhookQueue, shuttingDown: false, skills, useBakedImages: true };
476
+ const schedulerCtx = { runnerPools, agentConfigs, maxReruns, maxTriggerDepth, logger, webhookQueue, agentTriggerQueue, shuttingDown: false, skills, useBakedImages: true };
372
477
  // Set up webhook bindings (only when gateway is enabled)
373
478
  if (webhookRegistry && gatewayEnabled) {
374
479
  for (const agentConfig of activeAgentConfigs) {
@@ -422,8 +527,13 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
422
527
  if (triggers.length > 0) {
423
528
  dispatchTriggers(triggers, agentConfig.name, 0, schedulerCtx);
424
529
  }
425
- // Drain any events that queued while this webhook run was executing
426
- await drainWebhookQueue(agentConfig, schedulerCtx);
530
+ // If there are queued events and more runners available, start draining immediately
531
+ // without waiting for the first run to complete
532
+ if (webhookQueue.size(agentConfig.name) > 0) {
533
+ drainWebhookQueue(agentConfig, schedulerCtx).catch((err) => {
534
+ logger.error({ err }, `${agentConfig.name} parallel queue drain failed`);
535
+ });
536
+ }
427
537
  }, {}, SpanKind.INTERNAL).catch((err) => {
428
538
  logger.error({ err }, `${agentConfig.name} webhook run failed`);
429
539
  });
@@ -522,6 +632,7 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
522
632
  logger.info("Shutting down scheduler...");
523
633
  schedulerCtx.shuttingDown = true;
524
634
  webhookQueue.clearAll();
635
+ agentTriggerQueue.clearAll();
525
636
  for (const job of cronJobs) {
526
637
  job.stop();
527
638
  }
@@ -529,6 +640,9 @@ export async function startScheduler(projectPath, globalConfigOverride, statusTr
529
640
  await gateway.close();
530
641
  logger.info("Gateway server stopped");
531
642
  }
643
+ if (stateStore) {
644
+ await stateStore.close();
645
+ }
532
646
  // Shutdown telemetry
533
647
  if (telemetry) {
534
648
  try {