@nemesis-oss/ollama-sdk 1.12.0 → 1.12.1

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.d.cts CHANGED
@@ -390,8 +390,9 @@ declare function withRetry<T>(operation: (attempt: number) => Promise<T>, config
390
390
  * registry's synchronous `candidates()`/`filterWithCapacity()` and the
391
391
  * endpoint's `acquire()` — no `await` in between — so the strategy's
392
392
  * no-two-calls-pick-the-same-idle-endpoint guarantee is untouched. Affinity
393
- * only reorders *within* the runnable set; priority tiers and per-strategy
394
- * ordering stay intact inside the resident/non-resident groups.
393
+ * only reorders *within each priority tier* of the runnable set: a
394
+ * higher-priority endpoint is always tried before a lower-priority one, and
395
+ * per-strategy ordering is kept inside the resident/non-resident groups.
395
396
  * - **Best-effort, never blocking, never failing a request.** A probe failure is
396
397
  * recorded with a short backoff (`failureRetryMs`) and never cached as data;
397
398
  * the affected endpoint is simply treated as unknown until a probe succeeds.
@@ -461,9 +462,10 @@ declare class ModelAffinityRouter {
461
462
  readonly now?: NowFn;
462
463
  });
463
464
  /**
464
- * Synchronously reorders `candidates` so endpoints whose fresh `/api/ps`
465
+ * Synchronously reorders `candidates` so that, within each priority tier
466
+ * (run of consecutive equal `priority`), endpoints whose fresh `/api/ps`
465
467
  * snapshot shows `model` resident come first (relative order preserved within
466
- * each group). Returns the input unchanged — and kicks a background refresh —
468
+ * each group). Never moves an endpoint across tiers. Returns the input unchanged — and kicks a background refresh —
467
469
  * when any candidate's snapshot is missing or stale: a wrong reorder is worse
468
470
  * than no reorder, and the first request after a cache miss simply isn't
469
471
  * reordered. No-op without a `model` or with fewer than two candidates.
package/dist/index.d.ts CHANGED
@@ -390,8 +390,9 @@ declare function withRetry<T>(operation: (attempt: number) => Promise<T>, config
390
390
  * registry's synchronous `candidates()`/`filterWithCapacity()` and the
391
391
  * endpoint's `acquire()` — no `await` in between — so the strategy's
392
392
  * no-two-calls-pick-the-same-idle-endpoint guarantee is untouched. Affinity
393
- * only reorders *within* the runnable set; priority tiers and per-strategy
394
- * ordering stay intact inside the resident/non-resident groups.
393
+ * only reorders *within each priority tier* of the runnable set: a
394
+ * higher-priority endpoint is always tried before a lower-priority one, and
395
+ * per-strategy ordering is kept inside the resident/non-resident groups.
395
396
  * - **Best-effort, never blocking, never failing a request.** A probe failure is
396
397
  * recorded with a short backoff (`failureRetryMs`) and never cached as data;
397
398
  * the affected endpoint is simply treated as unknown until a probe succeeds.
@@ -461,9 +462,10 @@ declare class ModelAffinityRouter {
461
462
  readonly now?: NowFn;
462
463
  });
463
464
  /**
464
- * Synchronously reorders `candidates` so endpoints whose fresh `/api/ps`
465
+ * Synchronously reorders `candidates` so that, within each priority tier
466
+ * (run of consecutive equal `priority`), endpoints whose fresh `/api/ps`
465
467
  * snapshot shows `model` resident come first (relative order preserved within
466
- * each group). Returns the input unchanged — and kicks a background refresh —
468
+ * each group). Never moves an endpoint across tiers. Returns the input unchanged — and kicks a background refresh —
467
469
  * when any candidate's snapshot is missing or stale: a wrong reorder is worse
468
470
  * than no reorder, and the first request after a cache miss simply isn't
469
471
  * reordered. No-op without a `model` or with fewer than two candidates.
package/dist/index.js CHANGED
@@ -1763,9 +1763,10 @@ var ModelAffinityRouter = class {
1763
1763
  this.now = options.now ?? Date.now;
1764
1764
  }
1765
1765
  /**
1766
- * Synchronously reorders `candidates` so endpoints whose fresh `/api/ps`
1766
+ * Synchronously reorders `candidates` so that, within each priority tier
1767
+ * (run of consecutive equal `priority`), endpoints whose fresh `/api/ps`
1767
1768
  * snapshot shows `model` resident come first (relative order preserved within
1768
- * each group). Returns the input unchanged — and kicks a background refresh —
1769
+ * each group). Never moves an endpoint across tiers. Returns the input unchanged — and kicks a background refresh —
1769
1770
  * when any candidate's snapshot is missing or stale: a wrong reorder is worse
1770
1771
  * than no reorder, and the first request after a cache miss simply isn't
1771
1772
  * reordered. No-op without a `model` or with fewer than two candidates.
@@ -1782,13 +1783,28 @@ var ModelAffinityRouter = class {
1782
1783
  }
1783
1784
  }
1784
1785
  if (!allFresh) return candidates;
1785
- const resident = candidates.filter((ep) => {
1786
+ const isResident = (ep) => {
1786
1787
  const entry = this.cache.get(ep.name);
1787
1788
  return entry !== void 0 && isModelResident(entry.models, model);
1788
- });
1789
- if (resident.length === 0 || resident.length === candidates.length) return candidates;
1790
- const residentSet = new Set(resident.map((ep) => ep.name));
1791
- return [...resident, ...candidates.filter((ep) => !residentSet.has(ep.name))];
1789
+ };
1790
+ const reordered = [];
1791
+ let changed = false;
1792
+ for (let start = 0; start < candidates.length; ) {
1793
+ const tierPriority = candidates[start].priority ?? 0;
1794
+ let end = start + 1;
1795
+ while (end < candidates.length && (candidates[end].priority ?? 0) === tierPriority) end++;
1796
+ const tier = candidates.slice(start, end);
1797
+ const resident = tier.filter(isResident);
1798
+ if (resident.length === 0 || resident.length === tier.length) {
1799
+ reordered.push(...tier);
1800
+ } else {
1801
+ const tierOrder = [...resident, ...tier.filter((ep) => !isResident(ep))];
1802
+ changed ||= tierOrder.some((ep, i) => ep !== tier[i]);
1803
+ reordered.push(...tierOrder);
1804
+ }
1805
+ start = end;
1806
+ }
1807
+ return changed ? reordered : candidates;
1792
1808
  }
1793
1809
  /**
1794
1810
  * Forces a refresh of the affinity cache for the given endpoints (deduped with