| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| import test from "node:test";
|
| import assert from "node:assert/strict";
|
| import {
|
| createOmniRouteProviderHook,
|
| defaultOmniRouteCombosFetcher,
|
| mapComboToModelV2,
|
| type OmniRouteCombosFetcher,
|
| type OmniRouteModelsFetcher,
|
| type OmniRouteRawCombo,
|
| type OmniRouteRawModelEntry,
|
| } from "../src/index.js";
|
|
|
|
|
|
|
|
|
|
|
| const MODEL_PRIMARY: OmniRouteRawModelEntry = {
|
| id: "claude-primary",
|
| capabilities: {
|
| tool_calling: true,
|
| reasoning: true,
|
| vision: true,
|
| thinking: true,
|
| temperature: true,
|
| },
|
| context_length: 200_000,
|
| max_output_tokens: 64_000,
|
| max_input_tokens: 180_000,
|
| input_modalities: ["text", "image"],
|
| output_modalities: ["text"],
|
| };
|
|
|
| const MODEL_SECONDARY: OmniRouteRawModelEntry = {
|
| id: "claude-secondary",
|
| capabilities: {
|
| tool_calling: true,
|
| reasoning: false,
|
| vision: true,
|
| thinking: false,
|
| temperature: true,
|
| },
|
| context_length: 100_000,
|
| max_output_tokens: 32_000,
|
| max_input_tokens: 96_000,
|
| input_modalities: ["text", "image"],
|
| output_modalities: ["text"],
|
| };
|
|
|
| const MODEL_NO_TOOLS: OmniRouteRawModelEntry = {
|
| id: "gemini-3-flash",
|
| capabilities: { tool_calling: false, reasoning: false, vision: false, thinking: false },
|
| context_length: 1_000_000,
|
| max_output_tokens: 8_192,
|
| input_modalities: ["text"],
|
| output_modalities: ["text"],
|
| };
|
|
|
| const COMBO_CLAUDE_TIER: OmniRouteRawCombo = {
|
| id: "combo-claude-tier",
|
| name: "Claude Tier",
|
| strategy: "priority",
|
| models: [
|
| { id: "s1", kind: "model", model: "claude-primary", weight: 100 },
|
| { id: "s2", kind: "model", model: "claude-secondary", weight: 80 },
|
| ],
|
| };
|
|
|
|
|
|
|
|
|
|
|
| function stubModelsFetcher(
|
| payload: OmniRouteRawModelEntry[]
|
| ): OmniRouteModelsFetcher & { callCount: () => number } {
|
| let n = 0;
|
| const f: OmniRouteModelsFetcher = async () => {
|
| n++;
|
| return payload;
|
| };
|
| return Object.assign(f, { callCount: () => n });
|
| }
|
|
|
| function stubCombosFetcher(
|
| payload: OmniRouteRawCombo[]
|
| ): OmniRouteCombosFetcher & { callCount: () => number; callsBy: () => Array<[string, string]> } {
|
| let n = 0;
|
| const calls: Array<[string, string]> = [];
|
| const f: OmniRouteCombosFetcher = async (baseURL, apiKey) => {
|
| n++;
|
| calls.push([baseURL, apiKey]);
|
| return payload;
|
| };
|
| return Object.assign(f, {
|
| callCount: () => n,
|
| callsBy: () => calls,
|
| });
|
| }
|
|
|
| function failingCombosFetcher(
|
| err = new Error("boom")
|
| ): OmniRouteCombosFetcher & { callCount: () => number } {
|
| let n = 0;
|
| const f: OmniRouteCombosFetcher = async () => {
|
| n++;
|
| throw err;
|
| };
|
| return Object.assign(f, { callCount: () => n });
|
| }
|
|
|
| const apiAuth = (key: string): unknown => ({ type: "api", key });
|
|
|
|
|
|
|
|
|
| async function withWarnCapture<T>(
|
| fn: (warnings: Array<{ args: unknown[] }>) => Promise<T>
|
| ): Promise<{ result: T; warnings: Array<{ args: unknown[] }> }> {
|
| const original = console.warn;
|
| const warnings: Array<{ args: unknown[] }> = [];
|
| console.warn = (...args: unknown[]) => {
|
| warnings.push({ args });
|
| };
|
| try {
|
| const result = await fn(warnings);
|
| return { result, warnings };
|
| } finally {
|
| console.warn = original;
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
| test("defaultOmniRouteCombosFetcher: parses {combos:[…]} envelope", async () => {
|
| const originalFetch = globalThis.fetch;
|
| globalThis.fetch = (async (input: unknown) => {
|
| const url = typeof input === "string" ? input : (input as { url: string }).url;
|
| assert.equal(url, "https://or.example.com/api/combos");
|
| return new Response(
|
| JSON.stringify({
|
| combos: [
|
| { id: "c1", name: "Combo One", strategy: "priority", models: [] },
|
| { id: "c2", name: "Combo Two", strategy: "weighted", models: [] },
|
| ],
|
| }),
|
| { status: 200, headers: { "Content-Type": "application/json" } }
|
| );
|
| }) as typeof fetch;
|
| try {
|
| const combos = await defaultOmniRouteCombosFetcher("https://or.example.com", "sk-test");
|
| assert.equal(combos.length, 2);
|
| assert.equal(combos[0].id, "c1");
|
| assert.equal(combos[1].id, "c2");
|
| } finally {
|
| globalThis.fetch = originalFetch;
|
| }
|
| });
|
|
|
| test("defaultOmniRouteCombosFetcher: parses bare array envelope", async () => {
|
| const originalFetch = globalThis.fetch;
|
| globalThis.fetch = (async () => {
|
| return new Response(JSON.stringify([{ id: "c1" }, { id: "c2" }, { not_an_id: 42 }]), {
|
| status: 200,
|
| });
|
| }) as typeof fetch;
|
| try {
|
| const combos = await defaultOmniRouteCombosFetcher("https://or.example.com/v1", "sk-test");
|
|
|
| assert.equal(combos.length, 2);
|
| assert.equal(combos[0].id, "c1");
|
| assert.equal(combos[1].id, "c2");
|
| } finally {
|
| globalThis.fetch = originalFetch;
|
| }
|
| });
|
|
|
| test("defaultOmniRouteCombosFetcher: strips trailing /v1 before /api/combos", async () => {
|
| const originalFetch = globalThis.fetch;
|
| let observedUrl = "";
|
| globalThis.fetch = (async (input: unknown) => {
|
| observedUrl = typeof input === "string" ? input : (input as { url: string }).url;
|
| return new Response(JSON.stringify({ combos: [] }), { status: 200 });
|
| }) as typeof fetch;
|
| try {
|
| await defaultOmniRouteCombosFetcher("https://or.example.com/v1/", "sk-test");
|
| assert.equal(observedUrl, "https://or.example.com/api/combos");
|
| } finally {
|
| globalThis.fetch = originalFetch;
|
| }
|
| });
|
|
|
| test("defaultOmniRouteCombosFetcher: throws on non-2xx with status code in message", async () => {
|
| const originalFetch = globalThis.fetch;
|
| globalThis.fetch = (async () => {
|
| return new Response(JSON.stringify({ error: "Invalid token" }), {
|
| status: 403,
|
| statusText: "Forbidden",
|
| });
|
| }) as typeof fetch;
|
| try {
|
| await assert.rejects(
|
| async () => {
|
| await defaultOmniRouteCombosFetcher("https://or.example.com", "sk-bad");
|
| },
|
| (err: unknown) => {
|
| const msg = err instanceof Error ? err.message : String(err);
|
| assert.match(msg, /403/, "status code must appear in message");
|
| assert.match(msg, /\/api\/combos/, "url must appear in message");
|
| return true;
|
| }
|
| );
|
| } finally {
|
| globalThis.fetch = originalFetch;
|
| }
|
| });
|
|
|
| test("defaultOmniRouteCombosFetcher: throws when apiKey missing", async () => {
|
| await assert.rejects(
|
| async () => defaultOmniRouteCombosFetcher("https://or.example.com", ""),
|
| /apiKey required/
|
| );
|
| });
|
|
|
| test("defaultOmniRouteCombosFetcher: throws when baseURL missing", async () => {
|
| await assert.rejects(
|
| async () => defaultOmniRouteCombosFetcher("", "sk-test"),
|
| /baseURL required/
|
| );
|
| });
|
|
|
|
|
|
|
|
|
|
|
| test("mapComboToModelV2: empty members → capabilities all false (defensive)", () => {
|
| const m = mapComboToModelV2(
|
| { id: "combo-empty", name: "Empty Combo" },
|
| [],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m.id, "combo-empty");
|
| assert.equal(m.name, "Empty Combo");
|
| assert.equal(m.capabilities.temperature, false);
|
| assert.equal(m.capabilities.reasoning, false);
|
| assert.equal(m.capabilities.attachment, false);
|
| assert.equal(m.capabilities.toolcall, false);
|
| assert.equal(m.capabilities.input.text, false);
|
| assert.equal(m.capabilities.output.text, false);
|
| assert.equal(m.limit.context, 0);
|
| assert.equal(m.limit.output, 0);
|
| assert.equal(m.limit.input, undefined);
|
| assert.deepEqual(m.cost, { input: 0, output: 0, cache: { read: 0, write: 0 } });
|
| });
|
|
|
| test("mapComboToModelV2: all members reasoning=true → combo reasoning=true", () => {
|
| const m = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [
|
| MODEL_PRIMARY,
|
| {
|
| ...MODEL_PRIMARY,
|
| id: "p2",
|
| capabilities: { ...MODEL_PRIMARY.capabilities, thinking: false, reasoning: true },
|
| },
|
| ],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m.capabilities.reasoning, true);
|
| });
|
|
|
| test("mapComboToModelV2: any member reasoning=false → combo reasoning=false", () => {
|
| const m = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_NO_TOOLS],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m.capabilities.reasoning, false);
|
| });
|
|
|
| test("mapComboToModelV2: limit.context is min of members'", () => {
|
| const m = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_SECONDARY, MODEL_NO_TOOLS],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
|
|
| assert.equal(m.limit.context, 100_000);
|
|
|
| assert.equal(m.limit.output, 8_192);
|
| });
|
|
|
| test("mapComboToModelV2: limit.input only emitted when EVERY member declares one", () => {
|
| const m1 = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_SECONDARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
|
|
| assert.equal(m1.limit.input, 96_000);
|
|
|
| const m2 = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_NO_TOOLS],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m2.limit.input, undefined);
|
| });
|
|
|
| test("mapComboToModelV2: nice name preferred from combo.name", () => {
|
| const m1 = mapComboToModelV2(
|
| { id: "combo-x", name: "Pretty Name" },
|
| [MODEL_PRIMARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m1.name, "Pretty Name");
|
|
|
|
|
| const m2 = mapComboToModelV2(
|
| { id: "combo-y" },
|
| [MODEL_PRIMARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m2.name, "combo-y");
|
|
|
| const m3 = mapComboToModelV2(
|
| { id: "combo-z", name: " " },
|
| [MODEL_PRIMARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m3.name, "combo-z");
|
| });
|
|
|
| test("mapComboToModelV2: attachment AND vision flag both honored across members", () => {
|
|
|
| const yes = mapComboToModelV2(
|
| { id: "c1", models: [] },
|
| [MODEL_PRIMARY, MODEL_SECONDARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(yes.capabilities.attachment, true);
|
|
|
|
|
| const no = mapComboToModelV2(
|
| { id: "c2", models: [] },
|
| [MODEL_PRIMARY, MODEL_NO_TOOLS],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(no.capabilities.attachment, false);
|
| });
|
|
|
| test("mapComboToModelV2: modalities AND'd across members", () => {
|
| const m = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_SECONDARY],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m.capabilities.input.text, true);
|
| assert.equal(m.capabilities.input.image, true);
|
| assert.equal(m.capabilities.input.audio, false);
|
|
|
|
|
| const m2 = mapComboToModelV2(
|
| { id: "c", models: [] },
|
| [MODEL_PRIMARY, MODEL_NO_TOOLS],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m2.capabilities.input.text, true);
|
| assert.equal(m2.capabilities.input.image, false);
|
| });
|
|
|
| test("mapComboToModelV2: api block matches providerId + baseURL", () => {
|
| const m = mapComboToModelV2(
|
| { id: "c" },
|
| [MODEL_PRIMARY],
|
| "omniroute-preprod",
|
| "https://or-preprod.example.com/v1"
|
| );
|
| assert.equal(m.providerID, "omniroute-preprod");
|
| assert.equal(m.api.id, "openai-compatible");
|
| assert.equal(m.api.url, "https://or-preprod.example.com/v1");
|
| assert.equal(m.api.npm, "@ai-sdk/openai-compatible");
|
| assert.equal(m.status, "active");
|
| });
|
|
|
| test("mapComboToModelV2: explicit member temperature=false drops combo temperature=false", () => {
|
| const tempFalse: OmniRouteRawModelEntry = {
|
| id: "no-temp",
|
| capabilities: { tool_calling: true, temperature: false },
|
| context_length: 100_000,
|
| max_output_tokens: 8_000,
|
| input_modalities: ["text"],
|
| output_modalities: ["text"],
|
| };
|
| const m = mapComboToModelV2(
|
| { id: "c" },
|
| [MODEL_PRIMARY, tempFalse],
|
| "omniroute",
|
| "https://or.example.com/v1"
|
| );
|
| assert.equal(m.capabilities.temperature, false);
|
| });
|
|
|
|
|
|
|
|
|
|
|
| test("models() returns combo entries merged into the map", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY, MODEL_SECONDARY, MODEL_NO_TOOLS]);
|
| const combosFetcher = stubCombosFetcher([COMBO_CLAUDE_TIER]);
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
| const out = await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
|
|
|
|
| assert.equal(Object.keys(out).length, 4);
|
| assert.ok(out["claude-primary"]);
|
| assert.ok(out["claude-secondary"]);
|
| assert.ok(out["gemini-3-flash"]);
|
| assert.ok(out["combo/claude-tier"]);
|
|
|
| const combo = out["combo/claude-tier"];
|
| assert.equal(combo.name, "Combo: Claude Tier");
|
| assert.equal(combo.providerID, "omniroute");
|
|
|
| assert.equal(combo.limit.context, 100_000);
|
| assert.equal(combo.capabilities.reasoning, false);
|
| assert.equal(combo.capabilities.toolcall, true);
|
| });
|
|
|
| test("models(): combo with unknown member ids degrades to all-false LCD posture", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY]);
|
| const combosFetcher = stubCombosFetcher([
|
| {
|
| id: "phantom",
|
| name: "Phantom Combo",
|
| models: [
|
| { id: "s1", kind: "model", model: "does-not-exist-1", weight: 50 },
|
| { id: "s2", kind: "model", model: "does-not-exist-2", weight: 50 },
|
| ],
|
| },
|
| ]);
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
| const out = await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| assert.ok(out["combo/phantom-combo"]);
|
|
|
| assert.equal(out["combo/phantom-combo"].capabilities.toolcall, false);
|
| assert.equal(out["combo/phantom-combo"].capabilities.reasoning, false);
|
| assert.equal(out["combo/phantom-combo"].limit.context, 0);
|
| });
|
|
|
| test("models(): hidden combos are excluded from the map", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY]);
|
| const combosFetcher = stubCombosFetcher([
|
| {
|
| id: "visible",
|
| name: "Visible",
|
| models: [{ id: "s1", kind: "model", model: "claude-primary", weight: 100 }],
|
| },
|
| {
|
| id: "hidden",
|
| name: "Hidden",
|
| isHidden: true,
|
| models: [{ id: "s1", kind: "model", model: "claude-primary", weight: 100 }],
|
| },
|
| ]);
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
| const out = await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| assert.ok(out["combo/visible"]);
|
| assert.ok(!out["combo/hidden"], "hidden combo must be omitted");
|
| });
|
|
|
| test("models(): combo name exactly matches raw model id → raw deleted, combo lives at combo/ key, no warn", async () => {
|
|
|
|
|
|
|
| const colliderCombo: OmniRouteRawCombo = {
|
| id: "uuid-collider",
|
| name: "claude-primary",
|
| models: [{ id: "s1", kind: "model", model: "claude-secondary", weight: 100 }],
|
| };
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY, MODEL_SECONDARY]);
|
| const combosFetcher = stubCombosFetcher([colliderCombo]);
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
|
|
| const { result: out, warnings } = await withWarnCapture(async (_w) => {
|
| return hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| });
|
|
|
|
|
| assert.equal(out["claude-primary"], undefined, "raw deleted by combo-name dedup");
|
| assert.ok(out["combo/claude-primary"], "combo surfaces under combo/ namespace");
|
| assert.equal(out["combo/claude-primary"].name, "Combo: claude-primary");
|
|
|
|
|
| const collisionWarns = warnings.filter((w) => {
|
| const msg = w.args[0];
|
| return typeof msg === "string" && msg.includes("collides");
|
| });
|
| assert.equal(collisionWarns.length, 0, "no collision warn after dedup");
|
| });
|
|
|
| test("models(): two combos with same slug → second gets disambiguator suffix", async () => {
|
|
|
| const combos: OmniRouteRawCombo[] = [
|
| {
|
| id: "uuid-a",
|
| name: "Claude",
|
| models: [{ id: "s", kind: "model", model: "claude-primary", weight: 1 }],
|
| },
|
| {
|
| id: "uuid-b",
|
| name: "Claude",
|
| models: [{ id: "s", kind: "model", model: "claude-secondary", weight: 1 }],
|
| },
|
| ];
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| {
|
| fetcher: stubModelsFetcher([MODEL_PRIMARY, MODEL_SECONDARY]),
|
| combosFetcher: stubCombosFetcher(combos),
|
| }
|
| );
|
|
|
| const out = await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
|
|
| assert.ok(out["combo/claude"], "first combo at bare slug");
|
| assert.ok(out["combo/claude-uuid"], "second combo disambiguated by id prefix");
|
| });
|
|
|
| test("models(): combos fetch fails → falls back to models-only, warn emitted, no throw", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY, MODEL_SECONDARY]);
|
| const combosFetcher = failingCombosFetcher(new Error("ECONNRESET"));
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
|
|
| const { result: out, warnings } = await withWarnCapture(async () => {
|
| return hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| });
|
|
|
|
|
| assert.equal(Object.keys(out).length, 2);
|
| assert.ok(out["claude-primary"]);
|
| assert.ok(out["claude-secondary"]);
|
|
|
|
|
| const softFail = warnings.find((w) => {
|
| const msg = w.args[0];
|
| return typeof msg === "string" && msg.includes("combos fetch failed");
|
| });
|
| assert.ok(softFail, "soft-fail warning must be emitted on combos fetch error");
|
| assert.equal(combosFetcher.callCount(), 1);
|
| });
|
|
|
| test("models(): combos cached + reused within TTL (one combo fetch per TTL window)", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY, MODEL_SECONDARY]);
|
| const combosFetcher = stubCombosFetcher([COMBO_CLAUDE_TIER]);
|
| let nowMs = 1_000_000;
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1", modelCacheTtl: 60_000 },
|
| { fetcher: modelsFetcher, combosFetcher, now: () => nowMs }
|
| );
|
|
|
| await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| nowMs += 30_000;
|
| const second = await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| assert.equal(combosFetcher.callCount(), 1, "combos fetched only once within TTL");
|
| assert.equal(modelsFetcher.callCount(), 1, "models fetched only once within TTL");
|
| assert.ok(second["combo/claude-tier"]);
|
| });
|
|
|
| test("models(): combos refetched after TTL expiry (same key as models)", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY]);
|
| const combosFetcher = stubCombosFetcher([COMBO_CLAUDE_TIER]);
|
| let nowMs = 1_000_000;
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1", modelCacheTtl: 60_000 },
|
| { fetcher: modelsFetcher, combosFetcher, now: () => nowMs }
|
| );
|
|
|
| await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| nowMs += 60_001;
|
| await hook.models!({} as never, { auth: apiAuth("sk-z") as never });
|
| assert.equal(combosFetcher.callCount(), 2, "combos must refetch past TTL");
|
| assert.equal(modelsFetcher.callCount(), 2, "models must refetch past TTL");
|
| });
|
|
|
| test("models(): combos fetcher receives the resolved baseURL + apiKey", async () => {
|
| const modelsFetcher = stubModelsFetcher([MODEL_PRIMARY]);
|
| const combosFetcher = stubCombosFetcher([COMBO_CLAUDE_TIER]);
|
| const hook = createOmniRouteProviderHook(
|
| { baseURL: "https://or.example.com/v1" },
|
| { fetcher: modelsFetcher, combosFetcher }
|
| );
|
| await hook.models!({} as never, { auth: apiAuth("sk-spy") as never });
|
| assert.deepEqual(combosFetcher.callsBy()[0], ["https://or.example.com/v1", "sk-spy"]);
|
| });
|
|
|