llmist 10.0.0 → 10.1.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.
- package/dist/index.cjs +99 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +99 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8331,6 +8331,13 @@ var init_stream_processor = __esm({
|
|
|
8331
8331
|
inFlightExecutions = /* @__PURE__ */ new Map();
|
|
8332
8332
|
/** Queue of completed gadget results ready to be yielded (for real-time streaming) */
|
|
8333
8333
|
completedResultsQueue = [];
|
|
8334
|
+
// Concurrency limiting
|
|
8335
|
+
/** Subagent configuration map for checking maxConcurrent limits */
|
|
8336
|
+
subagentConfig;
|
|
8337
|
+
/** Track active execution count per gadget name */
|
|
8338
|
+
activeCountByGadget = /* @__PURE__ */ new Map();
|
|
8339
|
+
/** Queue of gadgets waiting for a concurrency slot (per gadget name) */
|
|
8340
|
+
concurrencyQueue = /* @__PURE__ */ new Map();
|
|
8334
8341
|
// Cross-iteration dependency tracking
|
|
8335
8342
|
/** Invocation IDs completed in previous iterations (read-only reference from Agent) */
|
|
8336
8343
|
priorCompletedInvocations;
|
|
@@ -8346,6 +8353,7 @@ var init_stream_processor = __esm({
|
|
|
8346
8353
|
this.baseDepth = options.baseDepth ?? 0;
|
|
8347
8354
|
this.priorCompletedInvocations = options.priorCompletedInvocations ?? /* @__PURE__ */ new Set();
|
|
8348
8355
|
this.priorFailedInvocations = options.priorFailedInvocations ?? /* @__PURE__ */ new Set();
|
|
8356
|
+
this.subagentConfig = options.subagentConfig;
|
|
8349
8357
|
this.parser = new GadgetCallParser({
|
|
8350
8358
|
startPrefix: options.gadgetStartPrefix,
|
|
8351
8359
|
endPrefix: options.gadgetEndPrefix,
|
|
@@ -8609,9 +8617,63 @@ var init_stream_processor = __esm({
|
|
|
8609
8617
|
}
|
|
8610
8618
|
return;
|
|
8611
8619
|
}
|
|
8612
|
-
const
|
|
8620
|
+
const limit = this.getConcurrencyLimit(call.gadgetName);
|
|
8621
|
+
const activeCount = this.activeCountByGadget.get(call.gadgetName) ?? 0;
|
|
8622
|
+
if (limit > 0 && activeCount >= limit) {
|
|
8623
|
+
this.logger.debug("Gadget queued due to concurrency limit", {
|
|
8624
|
+
gadgetName: call.gadgetName,
|
|
8625
|
+
invocationId: call.invocationId,
|
|
8626
|
+
activeCount,
|
|
8627
|
+
limit
|
|
8628
|
+
});
|
|
8629
|
+
const queue = this.concurrencyQueue.get(call.gadgetName) ?? [];
|
|
8630
|
+
queue.push(call);
|
|
8631
|
+
this.concurrencyQueue.set(call.gadgetName, queue);
|
|
8632
|
+
return;
|
|
8633
|
+
}
|
|
8634
|
+
this.startGadgetWithConcurrencyTracking(call);
|
|
8635
|
+
}
|
|
8636
|
+
/**
|
|
8637
|
+
* Get the concurrency limit for a gadget from subagent config.
|
|
8638
|
+
* Returns 0 if no limit is set (unlimited).
|
|
8639
|
+
*/
|
|
8640
|
+
getConcurrencyLimit(gadgetName) {
|
|
8641
|
+
const config = this.subagentConfig?.[gadgetName];
|
|
8642
|
+
return config?.maxConcurrent ?? 0;
|
|
8643
|
+
}
|
|
8644
|
+
/**
|
|
8645
|
+
* Start a gadget execution with concurrency tracking.
|
|
8646
|
+
* Increments active count, starts execution, and schedules queue processing on completion.
|
|
8647
|
+
*/
|
|
8648
|
+
startGadgetWithConcurrencyTracking(call) {
|
|
8649
|
+
const gadgetName = call.gadgetName;
|
|
8650
|
+
const currentCount = this.activeCountByGadget.get(gadgetName) ?? 0;
|
|
8651
|
+
this.activeCountByGadget.set(gadgetName, currentCount + 1);
|
|
8652
|
+
const executionPromise = this.executeGadgetAndCollect(call).finally(() => {
|
|
8653
|
+
const newCount = (this.activeCountByGadget.get(gadgetName) ?? 1) - 1;
|
|
8654
|
+
this.activeCountByGadget.set(gadgetName, newCount);
|
|
8655
|
+
this.processQueuedGadget(gadgetName);
|
|
8656
|
+
});
|
|
8613
8657
|
this.inFlightExecutions.set(call.invocationId, executionPromise);
|
|
8614
8658
|
}
|
|
8659
|
+
/**
|
|
8660
|
+
* Process the next queued gadget for a given gadget name if a slot is available.
|
|
8661
|
+
*/
|
|
8662
|
+
processQueuedGadget(gadgetName) {
|
|
8663
|
+
const queue = this.concurrencyQueue.get(gadgetName);
|
|
8664
|
+
if (!queue || queue.length === 0) return;
|
|
8665
|
+
const limit = this.getConcurrencyLimit(gadgetName);
|
|
8666
|
+
const activeCount = this.activeCountByGadget.get(gadgetName) ?? 0;
|
|
8667
|
+
if (limit === 0 || activeCount < limit) {
|
|
8668
|
+
const nextCall = queue.shift();
|
|
8669
|
+
this.logger.debug("Processing queued gadget", {
|
|
8670
|
+
gadgetName,
|
|
8671
|
+
invocationId: nextCall.invocationId,
|
|
8672
|
+
remainingInQueue: queue.length
|
|
8673
|
+
});
|
|
8674
|
+
this.startGadgetWithConcurrencyTracking(nextCall);
|
|
8675
|
+
}
|
|
8676
|
+
}
|
|
8615
8677
|
/**
|
|
8616
8678
|
* Execute a gadget through the full hook lifecycle and yield events.
|
|
8617
8679
|
* Handles parameter interception, before/after controllers, observers,
|
|
@@ -8799,27 +8861,58 @@ var init_stream_processor = __esm({
|
|
|
8799
8861
|
* Clears the inFlightExecutions map after all gadgets complete.
|
|
8800
8862
|
*/
|
|
8801
8863
|
async *waitForInFlightExecutions() {
|
|
8802
|
-
if (this.inFlightExecutions.size === 0) {
|
|
8864
|
+
if (this.inFlightExecutions.size === 0 && !this.hasQueuedGadgets()) {
|
|
8803
8865
|
return;
|
|
8804
8866
|
}
|
|
8805
8867
|
this.logger.debug("Waiting for in-flight gadget executions", {
|
|
8806
8868
|
count: this.inFlightExecutions.size,
|
|
8807
|
-
invocationIds: Array.from(this.inFlightExecutions.keys())
|
|
8869
|
+
invocationIds: Array.from(this.inFlightExecutions.keys()),
|
|
8870
|
+
queuedCount: this.getQueuedGadgetCount()
|
|
8808
8871
|
});
|
|
8809
|
-
const allDone = Promise.all(this.inFlightExecutions.values()).then(() => "done");
|
|
8810
8872
|
const POLL_INTERVAL_MS = 100;
|
|
8811
|
-
while (
|
|
8873
|
+
while (this.inFlightExecutions.size > 0 || this.hasQueuedGadgets()) {
|
|
8874
|
+
const allDone = this.inFlightExecutions.size > 0 ? Promise.all(this.inFlightExecutions.values()).then(() => "done") : Promise.resolve("done");
|
|
8812
8875
|
const result = await Promise.race([
|
|
8813
8876
|
allDone,
|
|
8814
8877
|
new Promise((resolve) => setTimeout(() => resolve("poll"), POLL_INTERVAL_MS))
|
|
8815
8878
|
]);
|
|
8816
8879
|
yield* this.drainCompletedResults();
|
|
8817
|
-
if (result === "done") {
|
|
8880
|
+
if (result === "done" && this.getTotalActiveGadgetCount() === 0 && !this.hasQueuedGadgets()) {
|
|
8818
8881
|
break;
|
|
8819
8882
|
}
|
|
8820
8883
|
}
|
|
8821
8884
|
this.inFlightExecutions.clear();
|
|
8822
8885
|
}
|
|
8886
|
+
/**
|
|
8887
|
+
* Check if there are any gadgets waiting in concurrency queues.
|
|
8888
|
+
*/
|
|
8889
|
+
hasQueuedGadgets() {
|
|
8890
|
+
for (const queue of this.concurrencyQueue.values()) {
|
|
8891
|
+
if (queue.length > 0) return true;
|
|
8892
|
+
}
|
|
8893
|
+
return false;
|
|
8894
|
+
}
|
|
8895
|
+
/**
|
|
8896
|
+
* Get total count of queued gadgets across all queues.
|
|
8897
|
+
*/
|
|
8898
|
+
getQueuedGadgetCount() {
|
|
8899
|
+
let count = 0;
|
|
8900
|
+
for (const queue of this.concurrencyQueue.values()) {
|
|
8901
|
+
count += queue.length;
|
|
8902
|
+
}
|
|
8903
|
+
return count;
|
|
8904
|
+
}
|
|
8905
|
+
/**
|
|
8906
|
+
* Get total count of actively executing gadgets across all types.
|
|
8907
|
+
* Used to know when all work is truly complete (not just when allDone resolves).
|
|
8908
|
+
*/
|
|
8909
|
+
getTotalActiveGadgetCount() {
|
|
8910
|
+
let total = 0;
|
|
8911
|
+
for (const count of this.activeCountByGadget.values()) {
|
|
8912
|
+
total += count;
|
|
8913
|
+
}
|
|
8914
|
+
return total;
|
|
8915
|
+
}
|
|
8823
8916
|
/**
|
|
8824
8917
|
* Handle a gadget that cannot execute because a dependency failed.
|
|
8825
8918
|
* Calls the onDependencySkipped controller to allow customization.
|