| 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; |
| 3 | |
| 4 | import { DEFAULT_ROUTING as POLICY, parseRouting } from "../../runner/src/model-env.ts"; |
| 5 | import { allowedProviders, clampTier, limitsAgree, pinnedModel, replyModel } from "./routing.ts"; |
| 6 | |
| 7 | test("a tier is held between the floor and the ceiling", () => { |
| 8 | assert.equal(clampTier("small", null, null), "small"); |
| 9 | assert.equal(clampTier("small", "large", null), "large", "a reviewer's floor lifts a reply"); |
| 10 | assert.equal(clampTier("frontier", null, "large"), "large", "triage's ceiling caps it"); |
| 11 | assert.equal(clampTier("large", "small", "frontier"), "large"); |
| 12 | assert.equal(clampTier("small", "frontier", "frontier"), "frontier"); |
| 13 | }); |
| 14 | |
| 15 | test("a floor above the ceiling: the ceiling wins, and validation says no", () => { |
| 16 | assert.equal(clampTier("small", "frontier", "large"), "large"); |
| 17 | assert.equal(clampTier("frontier", "frontier", "small"), "small"); |
| 18 | assert.equal(limitsAgree("frontier", "large"), false); |
| 19 | assert.equal(limitsAgree("large", "large"), true); |
| 20 | assert.equal(limitsAgree(null, "small"), true); |
| 21 | }); |
| 22 | |
| 23 | test("providers: empty means whatever the workspace allows; a list narrows it", () => { |
| 24 | assert.deepEqual(allowedProviders({ providers: [] }, null), { hosted: true, own: false }); |
| 25 | assert.deepEqual(allowedProviders({ providers: [] }, "int_1"), { hosted: true, own: true }); |
| 26 | assert.deepEqual(allowedProviders({ providers: ["g1t"] }, "int_1"), { hosted: true, own: false }); |
| 27 | assert.deepEqual(allowedProviders({ providers: ["int_1"] }, "int_1"), { hosted: false, own: true }); |
| 28 | assert.deepEqual(allowedProviders({ providers: ["int_2"] }, "int_1"), { hosted: false, own: false }, "a provider the workspace no longer has"); |
| 29 | // The profile form's choices. |
| 30 | assert.deepEqual(allowedProviders({ providers: ["workspace"] }, "int_1"), { hosted: false, own: true }); |
| 31 | assert.deepEqual(allowedProviders({ providers: ["workspace"] }, null), { hosted: false, own: false }, "own providers only, and it has none"); |
| 32 | assert.deepEqual(allowedProviders({ providers: ["g1t", "workspace"] }, "int_1"), { hosted: true, own: true }); |
| 33 | }); |
| 34 | |
| 35 | test("a reply runs on the small tier's model, moved by the agent's limits", () => { |
| 36 | const limits = { floor: null, ceiling: null, pinned: null }; |
| 37 | assert.equal(replyModel(POLICY, limits).model, POLICY.tiers.small.model); |
| 38 | const reviewer = replyModel(POLICY, { ...limits, floor: "large" }); |
| 39 | assert.equal(reviewer.tier, "large"); |
| 40 | assert.equal(reviewer.model, POLICY.tiers.large.model); |
| 41 | assert.deepEqual(reviewer.price, POLICY.tiers.large.price); |
| 42 | // The workspace chose frontier for replies; a ceiling still holds. |
| 43 | assert.equal(replyModel(POLICY, { ...limits, ceiling: "large" }, { chosen: "frontier" }).tier, "large"); |
| 44 | }); |
| 45 | |
| 46 | test("the tier's model comes from AGENT_ROUTING, never from code", () => { |
| 47 | const policy = parseRouting(JSON.stringify({ tiers: { small: { modelName: "Tiny 1", model: "tiny-1" } } })); |
| 48 | const routed = replyModel(policy, { floor: null, ceiling: null, pinned: null }); |
| 49 | assert.equal(routed.model, "tiny-1"); |
| 50 | assert.equal(routed.modelName, "Tiny 1"); |
| 51 | assert.equal(routed.price, null, "a model named without a price has none"); |
| 52 | }); |
| 53 | |
| 54 | test("a pinned model or a route's own model replaces the tier's", () => { |
| 55 | assert.equal(pinnedModel("openai/gpt-x"), "gpt-x"); |
| 56 | assert.equal(pinnedModel(null), null); |
| 57 | const pinned = replyModel(POLICY, { floor: null, ceiling: null, pinned: "acme/llama-9" }); |
| 58 | assert.equal(pinned.model, "llama-9"); |
| 59 | assert.equal(pinned.price, null); |
| 60 | assert.equal(replyModel(POLICY, { floor: null, ceiling: null, pinned: "acme/llama-9" }, { named: "route-model" }).model, "route-model"); |
| 61 | }); |