llm-relay 0.22.0 → 0.24.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.
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/routes/admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/routes/admin.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -15,23 +15,6 @@ export interface ProxyDeps {
15
15
  controlAuthorization?: ControlAuthorizationPort | null;
16
16
  }
17
17
  export declare function createProxy(cfg: Config, deps?: ProxyDeps): Server<typeof IncomingMessage, typeof ServerResponse>;
18
- /**
19
- * Order candidates worst-last WITHOUT dropping any: live, then credential-faulted, then cooling.
20
- *
21
- * Three states, and the distinction between them is the whole point:
22
- * - live — breaker closed, no standing 401/403. Keeps its fitness order.
23
- * - credential-faulted — answered 401/403 recently. It is not sick, it is unusable, and it
24
- * must not cost a round-trip per request ahead of a working member.
25
- * - cooling — breaker open (rate-limited or repeatedly failing).
26
- *
27
- * Demotion, not filtering. The previous `filter(isHealthy)` with a keep-everything fallback
28
- * removed cooling candidates outright whenever at least one was healthy, so a pool could be
29
- * narrowed to a single member and then have nothing to fall back to when that one failed too.
30
- * Ordering is strictly better: a demoted target is only ever reached after every better one has
31
- * actually failed on this request, and a pool with 14 members always has 14 chances.
32
- *
33
- * Stable within each band, so the already-computed deployment fitness still decides among equals.
34
- */
35
18
  export declare function orderByUsability(targets: ResolvedTarget[], breaker?: CircuitBreaker, now?: number): ResolvedTarget[];
36
19
  /**
37
20
  * What one backend status means for failover and for the breaker. THE single policy — both the
package/dist/server.js CHANGED
@@ -7,7 +7,7 @@ import { reconstructFromSse } from "./sse.js";
7
7
  import { emitSse, emitSseTail, syntheticMessageId } from "./emitSse.js";
8
8
  import { repair, destructiveMatcher } from "./repair.js";
9
9
  import { FailoverReshaper, HttpReshaper } from "./reshaper.js";
10
- import { fetchBackend, fetchOpenAiFront, normalizeOpenAiErrorBody, parseRetryAfterMs, SERVED_BY_HEADER, errorOrigin } from "./backend.js";
10
+ import { fetchBackend, fetchOpenAiFront, normalizeOpenAiErrorBody, parseRetryAfterMs, SERVED_BY_HEADER, POOL_ATTEMPTS_HEADER, errorOrigin } from "./backend.js";
11
11
  import { ModelCatalog } from "./catalog.js";
12
12
  import { handleAdminRoutes } from "./routes/admin.js";
13
13
  import { toolSchemaMap } from "./anthropic.js";
@@ -18,6 +18,9 @@ import { estimateRequestTokens, assessCost } from "./metadata.js";
18
18
  import { specOfTarget } from "./benchmarks.js";
19
19
  import { materializeDynamicPools } from "./dynamic-pools.js";
20
20
  import { baseLog } from "./request-log.js";
21
+ import { looksLikeContextLengthError, parseStatedContextLimit, recordObservedContextLimit } from "./context-limits.js";
22
+ import { clearEligibility, cooldownUntil, isCostBlocked, recordEligibility } from "./deployment-eligibility.js";
23
+ import { interpretRefusal, recordUnknownRefusal } from "./refusal-interpretation.js";
21
24
  import { CONTROL_AUTHORIZATION_HEADER, createControlAuthorization, resolveControlAuthorizationConfigDir, validateControlAuthorization, } from "./control-authorization.js";
22
25
  export { baseLog, logSafePath } from "./request-log.js";
23
26
  const HOP_BY_HOP = new Set([
@@ -329,19 +332,35 @@ async function handle(req, res, cfg, h) {
329
332
  // "the pool is mostly free" is exactly the assumption this exists to not rely on. Refusal is
330
333
  // loud (a clean 503 naming the rule), never a fall-through: falling through to
331
334
  // `routing.default` is the Anthropic passthrough, i.e. the very spend being guarded against.
332
- if (subSpec !== null && offloadRule(cfg, requestClient).freeOnly === true) {
335
+ // ⚠ The guard covers a DIRECTLY ADDRESSED pool too, not only offload-rerouted traffic.
336
+ // Gating it on `subSpec !== null` meant it never ran for the case it most needed to: a
337
+ // dispatch `cliLane` runs `claude -p --model pool/<name>`, whose requests are a MAIN
338
+ // conversation — no subagent marker, no `@relay:` directive — so the free-lane traffic this
339
+ // flag exists to bound walked straight past it. `pool/<name>` is by construction relay-routed
340
+ // free-lane traffic and never the vendor passthrough, and the guard can only ever refuse to
341
+ // spend, so extending it there cannot cost anyone an answer they were entitled to.
342
+ const addressesPool = typeof routedModel === "string" && routedModel.startsWith("pool/");
343
+ if ((subSpec !== null || addressesPool) && offloadRule(cfg, requestClient).freeOnly === true) {
333
344
  const kept = [];
334
345
  let blocked = null;
335
346
  for (const t of targetCandidates) {
336
347
  const assessment = t.kind === "openai" && t.model
337
348
  ? assessCost(t.model, h.catalog.cachedLimits(t.provider, t.model), cfg.providers[t.provider]?.tierType)
338
349
  : null; // anthropic passthrough — primary quota, definitionally not free
339
- if (assessment?.costClass === "free")
350
+ // A deployment that STATED it is not free outranks a price table that says it is. The
351
+ // `provider-tier` basis is an assumption about a roster; a 403 naming a subscription is
352
+ // that deployment correcting us. (`isCostBlocked` excludes `allowance-exhausted` — a
353
+ // spent allowance is not a price, and must not be laundered into one here either.)
354
+ if (assessment?.costClass === "free" && !isCostBlocked(t.provider, t.model))
340
355
  kept.push(t);
341
356
  else if (!blocked) {
342
357
  blocked = {
343
358
  spec: t.model ? `${t.provider}/${t.model}` : t.provider,
344
- why: assessment ? `${assessment.costClass} (${assessment.basis})` : "anthropic passthrough (primary quota)",
359
+ why: !assessment
360
+ ? "anthropic passthrough (primary quota)"
361
+ : assessment.costClass === "free"
362
+ ? "observed not free (the deployment stated it requires a subscription, or is gone)"
363
+ : `${assessment.costClass} (${assessment.basis})`,
345
364
  };
346
365
  }
347
366
  }
@@ -533,12 +552,13 @@ async function handle(req, res, cfg, h) {
533
552
  const cls = classifyStatus(backendRes.status);
534
553
  const retryAfterMs = parseRetryAfterMs(backendRes.headers.get("retry-after"));
535
554
  observeAttemptHeaders(h, attempt, backendRes.status, retryAfterMs);
555
+ observeContextLimit(backendRes, target);
536
556
  const localFailure = errorOrigin(backendRes) === "local";
537
557
  const tryNext = !localFailure && shouldTryNext(cls);
538
558
  if (tryNext && !res.destroyed && i < healthyTargets.length - 1) {
539
559
  clearTimeout(timer);
540
560
  res.off("close", onResClose);
541
- await backendRes.body?.cancel().catch(() => { });
561
+ await discardCandidate(backendRes, target, backendRes.status, retryAfterMs);
542
562
  pool429.recordFailover(backendRes.status, retryAfterMs);
543
563
  completeAttemptFailure(h, attempt, {
544
564
  failure: "http",
@@ -557,7 +577,8 @@ async function handle(req, res, cfg, h) {
557
577
  }
558
578
  else {
559
579
  const poolRetryAfterMs = pool429.overrideMs(backendRes.status, retryAfterMs);
560
- await transparentPath(res, backendRes, timer, { tools, streamed, willValidate, started, path, hadTools, req, target, attempt, signal: controller.signal, retryAfterOverrideMs: poolRetryAfterMs }, h);
580
+ pool429.recordFinal(backendRes.status);
581
+ await transparentPath(res, backendRes, timer, { tools, streamed, willValidate, started, path, hadTools, req, target, attempt, signal: controller.signal, retryAfterOverrideMs: poolRetryAfterMs, poolSummary: pool429.summary() }, h);
561
582
  }
562
583
  return;
563
584
  }
@@ -595,12 +616,32 @@ async function handle(req, res, cfg, h) {
595
616
  *
596
617
  * Stable within each band, so the already-computed deployment fitness still decides among equals.
597
618
  */
619
+ /** Is a learned allowance exhaustion still cooling this target? Never throws — no store, no cooling. */
620
+ function cooledByAllowance(t, now) {
621
+ try {
622
+ const until = cooldownUntil(t.provider, t.model ?? null, { now });
623
+ return until !== null && now < until;
624
+ }
625
+ catch {
626
+ return false;
627
+ }
628
+ }
598
629
  export function orderByUsability(targets, breaker = globalCircuitBreaker, now = Date.now()) {
599
630
  const live = [];
600
631
  const faulted = [];
601
632
  const cooling = [];
602
633
  for (const t of targets) {
603
- if (!breaker.isHealthy(t, now))
634
+ // A learned allowance exhaustion cools a target the breaker may know nothing about. That is
635
+ // the whole point of the ACCOUNT scope: one member's stated "you have depleted your monthly
636
+ // included credits" is a fact about the credential, so its siblings are spent too and should
637
+ // step aside without each first spending a round-trip to be told so individually. Measured
638
+ // here: `pool/xhigh`'s 15 members share only four independent quota domains, so the walk was
639
+ // rediscovering four facts fifteen times.
640
+ //
641
+ // Demotion, never exclusion — same contract as the rest of this function, and doubly so here:
642
+ // an exhausted allowance is a temporary condition on a deployment that is still free, and a
643
+ // pool with nothing else left must still be able to try it.
644
+ if (!breaker.isHealthy(t, now) || cooledByAllowance(t, now))
604
645
  cooling.push(t);
605
646
  else if (breaker.hasCredentialFault(t, now))
606
647
  faulted.push(t);
@@ -633,8 +674,11 @@ function shouldTryNext(cls) {
633
674
  class Pool429Tracker {
634
675
  minRetryAfterMs = null;
635
676
  only429 = true;
677
+ /** status → how many candidates answered it, in first-seen order. */
678
+ counts = new Map();
636
679
  /** Record a response being failed over past. */
637
680
  recordFailover(status, retryAfterMs) {
681
+ this.count(status);
638
682
  if (status === 429) {
639
683
  if (retryAfterMs !== null) {
640
684
  this.minRetryAfterMs = this.minRetryAfterMs === null ? retryAfterMs : Math.min(this.minRetryAfterMs, retryAfterMs);
@@ -644,6 +688,43 @@ class Pool429Tracker {
644
688
  this.only429 = false;
645
689
  }
646
690
  }
691
+ /** Record the response actually served — the walk's last candidate, success or failure. */
692
+ recordFinal(status) {
693
+ this.count(status);
694
+ }
695
+ count(status) {
696
+ this.counts.set(status, (this.counts.get(status) ?? 0) + 1);
697
+ }
698
+ /**
699
+ * The walk, as one line: `"13 tried, 0 served: 4x402, 5x429, 3x403, 1x400"`.
700
+ *
701
+ * ⚠ ASCII only. This is an HTTP header value, and Node latin1-encodes those — a `×` reaches a
702
+ * UTF-8 client as mojibake. Caught on a live pool, where the header read `6�402`.
703
+ *
704
+ * A pool's error is one member's error, and that is genuinely misleading when the other twelve
705
+ * failed for three other reasons: the client is handed HuggingFace's 402 and told to go buy
706
+ * credits, when the correct action is "use another pool". The BODY still carries that member's
707
+ * real upstream error — a true upstream error beats a synthesized one, the same maxim the
708
+ * context guardrail and the all-429 policy follow — so the aggregate rides alongside it in a
709
+ * header and in the log, where it costs the client nothing and answers "what actually happened"
710
+ * without a round of manual probing.
711
+ *
712
+ * Null for a single-candidate walk: there is no aggregate to report, and emitting one would
713
+ * dress up an ordinary passthrough error as a pool exhaustion.
714
+ */
715
+ summary() {
716
+ let tried = 0;
717
+ let served = 0;
718
+ for (const [status, n] of this.counts) {
719
+ tried += n;
720
+ if (status < 400)
721
+ served += n;
722
+ }
723
+ if (tried < 2)
724
+ return null;
725
+ const breakdown = [...this.counts.entries()].map(([status, n]) => `${n}x${status}`).join(", ");
726
+ return `${tried} tried, ${served} served: ${breakdown}`;
727
+ }
647
728
  /** Retry-After (ms) to serve on the FINAL response, or undefined to leave its real header alone. */
648
729
  overrideMs(finalStatus, finalRetryAfterMs) {
649
730
  if (finalStatus !== 429 || !this.only429 || this.minRetryAfterMs === null)
@@ -681,6 +762,106 @@ function beginHealthAttempt(h, target, started) {
681
762
  return null;
682
763
  return { handle: begun.value, identity, target, started, completed: false };
683
764
  }
765
+ /**
766
+ * Learn a deployment's real context ceiling from an error it just returned.
767
+ *
768
+ * ⚠ Called from BOTH request paths, right beside `observeAttemptHeaders`, and for the same reason
769
+ * that helper is shared: this repo has already shipped one defect where the OpenAI front had no
770
+ * copy of a policy the Anthropic path enforced ("two paths, two policies, one of them empty" — see
771
+ * docs/pool-failover.md). A learning loop that only ran on one front would silently know less
772
+ * about half the traffic.
773
+ *
774
+ * Never throws and never blocks the response: it reads a CLONE, so the real body is untouched for
775
+ * streaming or failover, and any failure simply means nothing was learned this time.
776
+ */
777
+ function observeContextLimit(res, target) {
778
+ // Context-length rejections are 400 (OpenAI-compatible) or 413. Anything else is a different
779
+ // fault, and scanning every error body would be work for nothing.
780
+ if (res.status !== 400 && res.status !== 413)
781
+ return;
782
+ if (target.model === undefined)
783
+ return;
784
+ let clone;
785
+ try {
786
+ clone = res.clone();
787
+ }
788
+ catch {
789
+ return; // Body already consumed/locked — nothing safe to read.
790
+ }
791
+ void clone
792
+ .text()
793
+ .then((body) => {
794
+ if (!looksLikeContextLengthError(body))
795
+ return;
796
+ const stated = parseStatedContextLimit(body);
797
+ if (stated === null)
798
+ return;
799
+ recordObservedContextLimit(target.provider, target.model, stated);
800
+ })
801
+ .catch(() => {
802
+ // A body that cannot be read teaches us nothing. That is the whole consequence.
803
+ });
804
+ }
805
+ /**
806
+ * Learn what a refusal proved about a deployment — or, when nothing confirmed covers it, learn
807
+ * NOTHING and queue the message for offline research.
808
+ *
809
+ * ⚠ Called from BOTH request paths beside `observeContextLimit`, for the reason that helper
810
+ * documents: a learning loop running on one front knows nothing about half the traffic, which is
811
+ * the exact shape of the pool-failover incident (docs/pool-failover.md).
812
+ *
813
+ * ⚠ The request path does not INTERPRET anything. `interpretRefusal` is a deterministic lookup
814
+ * against confirmed entries and reviewed seeds; a miss records the signature and stops. Judgement
815
+ * about an unrecognized message happens out of band — see `refusal-interpretation.ts` — because
816
+ * an LLM's opinion must never decide a live routing decision.
817
+ *
818
+ * ⚠ Takes a body STRING, never a `Response`, and is called only where that body was going to be
819
+ * read or discarded anyway. The obvious implementation — `res.clone()`, like `observeContextLimit`
820
+ * does — breaks failover outright: `clone()` TEES the body, and the failover branch immediately
821
+ * cancels the original, so the un-read tee branch strands the walk and the client is served the
822
+ * first candidate's error with the rest of the pool untouched. Caught by
823
+ * `test/pool-failover.test.ts` (three pre-existing 402 tests went red), which is the whole reason
824
+ * those tests insist on ≥2 candidates.
825
+ *
826
+ * Never throws: the worst outcome of a failure here is that nothing is learned this time.
827
+ */
828
+ function observeEligibility(target, status, retryAfterMs, body) {
829
+ if (target.model === undefined)
830
+ return;
831
+ try {
832
+ const verdict = interpretRefusal(target.provider, target.model, status, body);
833
+ if (verdict === null) {
834
+ // The fail-safe: an unrecognized refusal changes nothing about routing. It is held so a
835
+ // researcher can say what it means, and only then will it ever bind.
836
+ recordUnknownRefusal(target.provider, target.model, status, body);
837
+ return;
838
+ }
839
+ recordEligibility(target.provider, target.model, verdict, { retryAfterMs });
840
+ }
841
+ catch {
842
+ /* learning is best-effort and never in the request's way */
843
+ }
844
+ }
845
+ /** Statuses that can carry a durable fact about a deployment. A 429 is the breaker's business. */
846
+ function carriesEligibilityFact(status) {
847
+ return status === 400 || status === 402 || status === 403 || status === 404;
848
+ }
849
+ /**
850
+ * Release a candidate the walk is stepping over — reading its body first when that body might say
851
+ * something durable about the deployment.
852
+ *
853
+ * The read replaces the `cancel()` it used to be, rather than joining it: the body is being thrown
854
+ * away either way, so consuming it costs nothing extra and frees the socket just the same.
855
+ */
856
+ async function discardCandidate(res, target, status, retryAfterMs) {
857
+ if (carriesEligibilityFact(status)) {
858
+ const body = await res.text().catch(() => "");
859
+ if (body)
860
+ observeEligibility(target, status, retryAfterMs, body);
861
+ return;
862
+ }
863
+ await res.body?.cancel().catch(() => { });
864
+ }
684
865
  function observeAttemptHeaders(h, attempt, status, retryAfterMs) {
685
866
  const observedAt = Date.now();
686
867
  const result = h.breaker.observeHeaders(attempt.handle, {
@@ -709,6 +890,17 @@ function completeAttemptSuccess(h, attempt, status) {
709
890
  throw new Error(`attempt completion rejected: ${result.error.kind}`);
710
891
  attempt.completed = true;
711
892
  recordCall(attempt.target, true, attempt.started);
893
+ // A served request is first-party proof that this deployment exists and that the credential has
894
+ // allowance RIGHT NOW — strictly better evidence than any stored refusal, so it clears the
895
+ // record, including the account-scoped one. That is how a topped-up balance or a rolled-over
896
+ // month recovers well before the TTL would have expired, with no restart. Same contract as the
897
+ // breaker clearing a credential fault on success.
898
+ try {
899
+ clearEligibility(attempt.target.provider, attempt.target.model ?? null);
900
+ }
901
+ catch {
902
+ /* best-effort */
903
+ }
712
904
  }
713
905
  function completeAttemptFailure(h, attempt, options) {
714
906
  if (attempt.completed)
@@ -851,12 +1043,15 @@ async function openAiFrontPath(res, candidates, ctx, h) {
851
1043
  const cls = classifyStatus(upstream.status);
852
1044
  const retryAfterMs = parseRetryAfterMs(upstream.headers.get("retry-after"));
853
1045
  observeAttemptHeaders(h, attempt, upstream.status, retryAfterMs);
1046
+ observeContextLimit(upstream, target);
854
1047
  const tryNext = localFailure ? false : shouldTryNext(cls);
855
1048
  if (tryNext && !isLast && !res.writableEnded && !res.destroyed) {
856
1049
  clearTimeout(timer);
857
1050
  res.off("close", onResClose);
858
1051
  // Release the skipped candidate's socket — an un-consumed body holds the connection open.
859
- await upstream.body?.cancel().catch(() => { });
1052
+ // The body is read rather than cancelled when it might state a durable fact about the
1053
+ // deployment; either way the socket is freed and the bytes are discarded.
1054
+ await discardCandidate(upstream, target, upstream.status, retryAfterMs);
860
1055
  pool429.recordFailover(upstream.status, retryAfterMs);
861
1056
  completeAttemptFailure(h, attempt, {
862
1057
  failure: "http",
@@ -876,6 +1071,12 @@ async function openAiFrontPath(res, candidates, ctx, h) {
876
1071
  try {
877
1072
  const servedBy = upstream.status >= 400 ? tried.join(", ") : specOfTarget(target);
878
1073
  const headers = { ...filterResponseHeaders(upstream.headers), [SERVED_BY_HEADER]: servedBy };
1074
+ // Same aggregate as the Anthropic path, from the same tracker — the two fronts having
1075
+ // separate copies of one policy is the defect this file has already shipped once.
1076
+ pool429.recordFinal(upstream.status);
1077
+ const poolAttempts = pool429.summary();
1078
+ if (poolAttempts)
1079
+ headers[POOL_ATTEMPTS_HEADER] = poolAttempts;
879
1080
  const poolRetryAfterMs = pool429.overrideMs(upstream.status, retryAfterMs);
880
1081
  if (poolRetryAfterMs !== undefined) {
881
1082
  headers["retry-after"] = String(Math.max(1, Math.ceil(poolRetryAfterMs / 1000)));
@@ -883,6 +1084,10 @@ async function openAiFrontPath(res, candidates, ctx, h) {
883
1084
  if (upstream.status >= 400) {
884
1085
  // Error bodies are small and are never streamed: buffer, normalize the envelope, send.
885
1086
  const raw = await upstream.text().catch(() => "");
1087
+ // The last candidate teaches us as much as the ones stepped over — and for a
1088
+ // single-member pool it is the ONLY one that can. Free, since the body is already here.
1089
+ if (raw && carriesEligibilityFact(upstream.status))
1090
+ observeEligibility(target, upstream.status, retryAfterMs, raw);
886
1091
  const normalized = normalizeOpenAiErrorBody(raw, upstream.status);
887
1092
  const out = Buffer.from(normalized ?? raw, "utf8");
888
1093
  res.writeHead(upstream.status, { ...headers, "content-type": "application/json" });
@@ -930,6 +1135,8 @@ async function transparentPath(res, backendRes, timer, ctx, h) {
930
1135
  if (ctx.retryAfterOverrideMs !== undefined && Number.isFinite(ctx.retryAfterOverrideMs)) {
931
1136
  responseHeaders["retry-after"] = String(Math.max(1, Math.ceil(ctx.retryAfterOverrideMs / 1000)));
932
1137
  }
1138
+ if (ctx.poolSummary)
1139
+ responseHeaders[POOL_ATTEMPTS_HEADER] = ctx.poolSummary;
933
1140
  res.writeHead(backendRes.status, responseHeaders);
934
1141
  let assistant = null;
935
1142
  try {
@@ -959,6 +1166,12 @@ async function transparentPath(res, backendRes, timer, ctx, h) {
959
1166
  const bytes = Buffer.from(await backendRes.arrayBuffer());
960
1167
  if (!res.writableEnded)
961
1168
  res.end(bytes);
1169
+ // Same as the OpenAI front's terminal branch: the served response is the last candidate's,
1170
+ // and for a single-member pool the only refusal we will ever see. Errors are never streamed,
1171
+ // so this branch is where they land.
1172
+ if (backendRes.status >= 400 && carriesEligibilityFact(backendRes.status)) {
1173
+ observeEligibility(ctx.target, backendRes.status, parseRetryAfterMs(backendRes.headers.get("retry-after")), bytes.toString("utf8"));
1174
+ }
962
1175
  if (ctx.willValidate && bytes.length <= MAX_VALIDATE_BYTES)
963
1176
  assistant = parseAssistant(bytes.toString("utf8"));
964
1177
  }