From e31f5be74af6eb31ad871b22ab09cbace345fdd1 Mon Sep 17 00:00:00 2001 From: Vocllum <149675937+Vocllum@users.noreply.github.com> Date: Tue, 8 Sep 2026 02:03:17 +0800 Subject: [PATCH] fix(providers): raise Nous model discovery response cap --- src/providers/registry.ts | 4 +++- .../provider-model-discovery-contract.test.ts | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/providers/registry.ts b/src/providers/registry.ts index 5e46f27d60..e0aa946ac3 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -1539,8 +1539,10 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ modelDiscovery: { // Resolves against effectiveBaseUrl (registry baseUrl .../v1) to the same // canonical endpoint https://inference-api.nousresearch.com/v1/models. + // Nous returns a mixed paid/free catalog whose JSON can exceed 256 KiB; + // keep the provider-specific limit below the process-wide 4 MiB ceiling. path: "models", - maxResponseBytes: 262_144, + maxResponseBytes: 1_048_576, maxModels: 512, }, note: "Nous Research subscription gateway. OAuth device login with your own Portal account; mixed paid + :free models discovered live (fallback seed 2026-08-10: tencent/hy3:free, poolside/laguna-s-2.1:free, stepfun/step-3.7-flash:free, poolside/laguna-xs-2.1:free).", diff --git a/tests/providers/provider-model-discovery-contract.test.ts b/tests/providers/provider-model-discovery-contract.test.ts index b55cbcd32e..f57b74d505 100644 --- a/tests/providers/provider-model-discovery-contract.test.ts +++ b/tests/providers/provider-model-discovery-contract.test.ts @@ -428,6 +428,27 @@ describe("registry-owned provider model discovery", () => { expect(cancelled).toBe(true); }); + test("accepts the observed Nous mixed catalog within its provider-specific response cap", async () => { + const entry = PROVIDER_REGISTRY.find(row => row.id === "nous"); + if (!entry) throw new Error("missing nous registry entry"); + const discovery = resolveProviderModelDiscovery("nous", { + adapter: entry.adapter, + baseUrl: entry.baseUrl, + authMode: "oauth", + }); + const payload = JSON.stringify({ + data: Array.from({ length: 390 }, (_, index) => ({ + id: index === 0 ? "tencent/hy3:free" : `vendor/model-${index}`, + metadata: { description: "x".repeat(1_400) }, + })), + }); + + expect(new TextEncoder().encode(payload).byteLength).toBeGreaterThan(262_144); + expect(discovery.maxResponseBytes).toBe(1_048_576); + const result = await readBoundedDiscoveryJson(new Response(payload), discovery.maxResponseBytes); + expect(result.ok).toBe(true); + }); + test("rejects invalid UTF-8 before JSON parsing", async () => { const invalidUtf8Json = new Uint8Array([ 0x7b, 0x22, 0x78, 0x22, 0x3a, 0x22, 0xc3, 0x28, 0x22, 0x7d,