castle-web-cli 0.4.56 → 0.4.57

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 (2) hide show
  1. package/dist/agent.js +19 -1
  2. package/package.json +1 -1
package/dist/agent.js CHANGED
@@ -78,6 +78,10 @@ function buildAgentInvocation(backend, role, prompt, claudeModel) {
78
78
  const ROUTER_TIMEOUT_MS = 3 * 60_000;
79
79
  const TASK_TIMEOUT_MS = 30 * 60_000;
80
80
  const MAX_TASK_ATTEMPTS = 3;
81
+ // Cap on task agents running at once -- keeps us under e2b / provider rate
82
+ // limits. Over-cap tasks stay queued ('waiting') and start, earliest-created
83
+ // first, as running ones finish. Conservative default; override via env.
84
+ const MAX_CONCURRENT_TASKS = Number(process.env.CASTLE_MAX_CONCURRENT_TASKS) || 4;
81
85
  const TASK_POLL_MS = 1_000;
82
86
  const FENCE_HOLDBACK = '```castle-';
83
87
  const RESULT_SUMMARY_CHARS = 600;
@@ -497,9 +501,21 @@ function createTaskStore(opts) {
497
501
  return !dep || isTerminal(dep.status);
498
502
  });
499
503
  }
504
+ function runningCount() {
505
+ let n = 0;
506
+ for (const t of tasks.values())
507
+ if (t.status === 'running')
508
+ n++;
509
+ return n;
510
+ }
500
511
  function maybeStart(task) {
501
512
  if (task.status !== 'waiting' || task.acknowledged || !depsAreSettled(task))
502
513
  return;
514
+ // Concurrency cap: at most MAX_CONCURRENT_TASKS agents run at once. Over-cap
515
+ // tasks stay 'waiting' and are restarted -- earliest-created first -- by the
516
+ // onFinished sweep below when a running task frees a slot.
517
+ if (runningCount() >= MAX_CONCURRENT_TASKS)
518
+ return;
503
519
  start(task);
504
520
  }
505
521
  function start(task) {
@@ -540,7 +556,9 @@ function createTaskStore(opts) {
540
556
  : `${result.error ?? 'failed'}\n${result.finalText.slice(-RESULT_SUMMARY_CHARS)}`;
541
557
  touch(task);
542
558
  opts.onFinished(task);
543
- for (const waiting of tasks.values())
559
+ // A slot just freed -- restart eligible waiting tasks, earliest-created
560
+ // first, up to the concurrency cap.
561
+ for (const waiting of sorted())
544
562
  maybeStart(waiting);
545
563
  });
546
564
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-cli",
3
- "version": "0.4.56",
3
+ "version": "0.4.57",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castle-web": "./dist/index.js"