@tbrandenburg/node-red-agents 0.1.5 → 0.2.0

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.
@@ -475,6 +475,12 @@
475
475
  the id of the execution to kill, as returned by an earlier run in
476
476
  <code>msg.agentExecution.id</code> or an Events message's
477
477
  <code>executionId</code>.</dd>
478
+ <dt class="optional">concurrency <span class="property-type">number</span></dt>
479
+ <dd>Overrides the Concurrency field at runtime, applied before this
480
+ message is submitted -- no redeploy needed. Raising it starts any
481
+ already-queued messages immediately; lowering it only affects
482
+ future scheduling (already-running executions are never
483
+ cancelled). Non-numeric/non-positive values are ignored.</dd>
478
484
  </dl>
479
485
  <h3>Outputs</h3>
480
486
  <ol class="node-ports">
@@ -509,7 +515,9 @@
509
515
  complete in a different order than the messages arrived; ordering is
510
516
  not guaranteed above concurrency 1. On redeploy/removal, queued
511
517
  messages are cancelled (a <code>cancelled</code> event plus a Node-RED
512
- error) and any still-running agent processes are terminated.</p>
518
+ error) and any still-running agent processes are terminated. Send
519
+ <code>msg.concurrency</code> to change the bound at runtime without a
520
+ redeploy -- see Inputs below.</p>
513
521
  <p><b>Terminating a specific execution on demand</b>: send a message with
514
522
  <code>msg.operation = "terminate"</code> and <code>msg.executionId</code>
515
523
  set to the id to kill (from a prior run's <code>msg.agentExecution.id</code>
@@ -342,6 +342,15 @@ module.exports = function (RED) {
342
342
  return;
343
343
  }
344
344
 
345
+ // Optional per-message override of the deploy-time Concurrency
346
+ // field, applied before this message is submitted so a raised
347
+ // bound can immediately start any items already queued from
348
+ // earlier messages. Invalid values (non-numeric/non-positive)
349
+ // are ignored -- see ExecutionScheduler.setConcurrency.
350
+ if (msg.concurrency !== undefined) {
351
+ node.scheduler.setConcurrency(Number(msg.concurrency));
352
+ }
353
+
345
354
  let resolved;
346
355
  try {
347
356
  resolved = {
@@ -27,6 +27,20 @@ class ExecutionScheduler {
27
27
  return this.active.size;
28
28
  }
29
29
 
30
+ // Runtime override of the concurrency bound (e.g. from a per-message
31
+ // msg.concurrency), as opposed to the fixed value passed into the
32
+ // constructor. Invalid input (non-finite/non-positive) is ignored
33
+ // rather than falling back to 1 -- an in-flight bound should never be
34
+ // silently reset by a bad message. Raising the bound immediately
35
+ // drains eligible queued items via _advance(); lowering it only
36
+ // affects future scheduling -- already-active items are never
37
+ // cancelled by this call.
38
+ setConcurrency(concurrency) {
39
+ if (!Number.isFinite(concurrency) || concurrency <= 0) return;
40
+ this.concurrency = Math.floor(concurrency);
41
+ this._advance();
42
+ }
43
+
30
44
  get queuedCount() {
31
45
  return this.queue.length;
32
46
  }
@@ -194,7 +194,7 @@
194
194
  <label for="node-input-maxInstances"><i class="fa fa-tasks"></i> Max instances</label>
195
195
  <input type="text" id="node-input-maxInstances" placeholder="5" style="width:80px">
196
196
  <i class="fa fa-info-circle" style="color:#888; cursor:help; margin-left:4px;"
197
- title="Maximum number of daemons this node may have spawned at once. A new no-session-id trigger errors immediately once reached (no queueing). 0 = unlimited."></i>
197
+ title="Maximum number of daemons this node may have spawned at once. A new no-session-id trigger errors immediately once reached (no queueing). 0 = unlimited. Overridable at runtime via msg.maxInstances."></i>
198
198
  </div>
199
199
  <div class="form-row agent-server-row-spawn">
200
200
  <label for="node-input-startupTimeoutMs"><i class="fa fa-clock-o"></i> Startup timeout</label>
@@ -340,6 +340,12 @@
340
340
  configured Operation for a single trigger -- e.g. to ask a message-sending node
341
341
  instance for its own current status, without needing a second node pointed at
342
342
  nothing.</p>
343
+ <p>Set <code>msg.maxInstances</code> to override the Max instances field at
344
+ runtime, without a redeploy -- 0 keeps meaning "unlimited", and
345
+ negative/non-numeric values are ignored. Lowering it below the current
346
+ number of tracked daemons never kills any of them; it only blocks
347
+ <em>future</em> spawns until the count naturally drops back under the
348
+ new cap.</p>
343
349
  <h3>Outputs</h3>
344
350
  <ol class="node-ports">
345
351
  <li>Result
@@ -464,6 +464,18 @@ module.exports = function (RED) {
464
464
  return;
465
465
  }
466
466
 
467
+ // Optional per-message override of the deploy-time Max instances
468
+ // field, applied before spawnNewInstance()'s guard clause reads it
469
+ // -- no redeploy needed. 0 stays "unlimited" (same as the
470
+ // constructor's semantics above); negative/non-numeric values are
471
+ // ignored. Lowering the limit below the current registry size
472
+ // never evicts already-spawned daemons -- it only blocks *future*
473
+ // spawns until the count naturally drops back under the new cap.
474
+ if (msg.maxInstances !== undefined) {
475
+ const n = Number(msg.maxInstances);
476
+ if (Number.isFinite(n) && n >= 0) node.maxInstances = Math.floor(n);
477
+ }
478
+
467
479
  // msg.operation can override the configured default for this one
468
480
  // trigger. This matters because each node instance's registry is
469
481
  // private (per-node-instance scoping, same as the `agent` node's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbrandenburg/node-red-agents",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Node-RED nodes for running coding agents (opencode, pi) and GitHub CLI operations from flows.",
5
5
  "keywords": [
6
6
  "node-red",