Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/providers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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).",
Expand Down
21 changes: 21 additions & 0 deletions tests/providers/provider-model-discovery-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading