llmist 15.18.0 → 15.19.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 CHANGED
@@ -1832,6 +1832,9 @@ function isRetryableError(error) {
1832
1832
  if (message.includes("hf bad request")) {
1833
1833
  return true;
1834
1834
  }
1835
+ if (message.includes("incomplete json segment") || message.includes("exception parsing stream chunk") || message.includes("json error injected into sse stream") || message.includes("sending request") && message.includes("exception") || message.includes("invalid chunk") && message.includes("finish reason") || message.includes("unexpected line format")) {
1836
+ return true;
1837
+ }
1835
1838
  if (message.includes("401") || message.includes("403") || message.includes("400") || message.includes("404") || message.includes("authentication") || message.includes("unauthorized") || message.includes("forbidden") || message.includes("invalid") || message.includes("content policy") || name === "AuthenticationError" || name === "BadRequestError" || name === "NotFoundError" || name === "PermissionDeniedError") {
1836
1839
  return false;
1837
1840
  }
@@ -1937,6 +1940,9 @@ Documentation: ${docsUrl}`;
1937
1940
  if (message.toLowerCase().includes("content policy") || message.toLowerCase().includes("safety")) {
1938
1941
  return "Content policy violation - the request was blocked";
1939
1942
  }
1943
+ if (message.toLowerCase().includes("incomplete json segment") || message.toLowerCase().includes("exception parsing stream chunk") || message.toLowerCase().includes("json error injected into sse stream") || message.toLowerCase().includes("sending request") && message.toLowerCase().includes("exception") || message.toLowerCase().includes("invalid chunk") && message.toLowerCase().includes("finish reason") || message.toLowerCase().includes("unexpected line format")) {
1944
+ return "Stream interrupted - the API returned corrupted or incomplete data";
1945
+ }
1940
1946
  try {
1941
1947
  const parsed = JSON.parse(message);
1942
1948
  const extractedMessage = parsed?.error?.message || parsed?.message;
@@ -2759,6 +2765,17 @@ var init_gadget = __esm({
2759
2765
  * ```
2760
2766
  */
2761
2767
  maxConcurrent;
2768
+ /**
2769
+ * If true, this gadget must execute alone — no other gadgets in the same
2770
+ * LLM response can run in parallel. When an exclusive gadget arrives and
2771
+ * other gadgets are already in-flight, it is deferred until they complete.
2772
+ *
2773
+ * Use for gadgets that terminate the agent loop (e.g., Finish), where
2774
+ * sibling tool results must be visible to the LLM before the loop ends.
2775
+ *
2776
+ * This is a safety floor: external config cannot weaken it.
2777
+ */
2778
+ exclusive;
2762
2779
  /**
2763
2780
  * Throws an AbortException if the execution has been aborted.
2764
2781
  *
@@ -12779,6 +12796,7 @@ function Gadget(config) {
12779
12796
  timeoutMs = config.timeoutMs;
12780
12797
  examples = config.examples;
12781
12798
  maxConcurrent = config.maxConcurrent;
12799
+ exclusive = config.exclusive;
12782
12800
  /**
12783
12801
  * Type helper property for accessing inferred parameter type.
12784
12802
  * This is used in the execute method signature: `execute(params: this['params'])`
@@ -13519,6 +13537,9 @@ var init_stream_processor = __esm({
13519
13537
  activeCountByGadget = /* @__PURE__ */ new Map();
13520
13538
  /** Queue of gadgets waiting for a concurrency slot (per gadget name) */
13521
13539
  concurrencyQueue = /* @__PURE__ */ new Map();
13540
+ // Exclusive gadget support
13541
+ /** Queue of exclusive gadgets deferred until in-flight gadgets complete */
13542
+ exclusiveQueue = [];
13522
13543
  // Cross-iteration dependency tracking
13523
13544
  /** Invocation IDs completed in previous iterations (read-only reference from Agent) */
13524
13545
  priorCompletedInvocations;
@@ -13872,6 +13893,16 @@ var init_stream_processor = __esm({
13872
13893
  if (limitResult.value === true) {
13873
13894
  return;
13874
13895
  }
13896
+ const gadget = this.registry.get(call.gadgetName);
13897
+ if (gadget?.exclusive && this.inFlightExecutions.size > 0) {
13898
+ this.logger.debug("Deferring exclusive gadget until in-flight gadgets complete", {
13899
+ gadgetName: call.gadgetName,
13900
+ invocationId: call.invocationId,
13901
+ inFlightCount: this.inFlightExecutions.size
13902
+ });
13903
+ this.exclusiveQueue.push(call);
13904
+ return;
13905
+ }
13875
13906
  const limit = this.getConcurrencyLimit(call.gadgetName);
13876
13907
  const activeCount = this.activeCountByGadget.get(call.gadgetName) ?? 0;
13877
13908
  if (limit > 0 && activeCount >= limit) {
@@ -14157,7 +14188,7 @@ var init_stream_processor = __esm({
14157
14188
  * Clears the inFlightExecutions map after all gadgets complete.
14158
14189
  */
14159
14190
  async *waitForInFlightExecutions() {
14160
- if (this.inFlightExecutions.size === 0 && !this.hasQueuedGadgets()) {
14191
+ if (this.inFlightExecutions.size === 0 && !this.hasQueuedGadgets() && this.exclusiveQueue.length === 0) {
14161
14192
  return;
14162
14193
  }
14163
14194
  this.logger.debug("Waiting for in-flight gadget executions", {
@@ -14178,6 +14209,18 @@ var init_stream_processor = __esm({
14178
14209
  }
14179
14210
  }
14180
14211
  this.inFlightExecutions.clear();
14212
+ if (this.exclusiveQueue.length > 0) {
14213
+ this.logger.debug("Processing deferred exclusive gadgets", {
14214
+ count: this.exclusiveQueue.length
14215
+ });
14216
+ const queue = this.exclusiveQueue;
14217
+ this.exclusiveQueue = [];
14218
+ for (const call of queue) {
14219
+ for await (const evt of this.executeGadgetGenerator(call)) {
14220
+ yield evt;
14221
+ }
14222
+ }
14223
+ }
14181
14224
  }
14182
14225
  /**
14183
14226
  * Check if there are any gadgets waiting in concurrency queues.