graphai 2.0.17 → 2.0.18

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.
@@ -167,14 +167,15 @@ class TaskManager {
167
167
  }
168
168
  perParent.set(parentGraphId, (perParent.get(parentGraphId) ?? 0) + 1);
169
169
  }
170
- // Both the global slot bump and the optional label bypass can free capacity
171
- // for already-queued tasks; drain the queue while progress is being made.
172
- let progressed = true;
173
- while (progressed) {
174
- const before = this.runningNodes.size;
175
- this.dequeueTaskIfPossible();
176
- progressed = this.runningNodes.size > before;
177
- }
170
+ // IMPORTANT: do NOT drain the queue here. The concurrency++ above reserves a
171
+ // slot so the nested graph's own children have headroom to run (deadlock
172
+ // avoidance, which mapAgent asserts via `concurrency > running`). At this
173
+ // point the nested children are not queued yet -- the nested graph is built
174
+ // and run *after* prepareForNesting returns -- so draining now can only
175
+ // dispatch unrelated already-queued sibling tasks into the reserved slot,
176
+ // immediately consuming the headroom and tripping mapAgent's guard. The
177
+ // nested children, and any newly-eligible queued tasks, are dispatched when
178
+ // they call addTask() or when a slot frees up in onComplete().
178
179
  }
179
180
  restoreAfterNesting(label, parentGraphId) {
180
181
  this.concurrency--;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "2.0.17",
3
+ "version": "2.0.18",
4
4
  "description": "Asynchronous data flow execution engine for agentic AI apps.",
5
5
  "main": "lib/index.js",
6
6
  "files": [