feat(models): add model-aware runtime metadata
This commit is contained in:
+121
-2
@@ -7,7 +7,12 @@ import { describe, it } from "node:test"
|
||||
import {
|
||||
commandCodeModelsFromApiResponse,
|
||||
commandCodeModelsFromCache,
|
||||
DEFAULT_MODELS_TIMEOUT_MS,
|
||||
getModelsTimeoutMs,
|
||||
loadCommandCodeModels,
|
||||
MODEL_EFFORTS,
|
||||
thinkingLevelMapForEfforts,
|
||||
thinkingMetadataForModel,
|
||||
type CommandCodeModel,
|
||||
} from "../src/models.ts"
|
||||
|
||||
@@ -29,7 +34,7 @@ const EXPECTED_MODELS: readonly CommandCodeModel[] = [
|
||||
{
|
||||
id: "Qwen/Qwen3.7-Max",
|
||||
name: "Qwen 3.7 Max (CC)",
|
||||
reasoning: true,
|
||||
reasoning: false,
|
||||
contextWindow: 1_000_000,
|
||||
maxTokens: 65_536,
|
||||
},
|
||||
@@ -49,6 +54,17 @@ function failingFetch(message = "offline"): typeof fetch {
|
||||
return () => Promise.reject(new TypeError(message))
|
||||
}
|
||||
|
||||
function hangingFetch(): typeof fetch {
|
||||
return (_input, init) =>
|
||||
new Promise<Response>((_resolve, reject) => {
|
||||
init?.signal?.addEventListener(
|
||||
"abort",
|
||||
() => reject(init.signal?.reason ?? new DOMException("Aborted", "AbortError")),
|
||||
{ once: true },
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function withTemporaryCache(
|
||||
run: (paths: { directory: string; cachePath: string }) => Promise<void>,
|
||||
): Promise<void> {
|
||||
@@ -65,6 +81,44 @@ describe("commandCodeModelsFromApiResponse()", () => {
|
||||
assert.deepEqual(commandCodeModelsFromApiResponse(API_RESPONSE), EXPECTED_MODELS)
|
||||
})
|
||||
|
||||
it("marks only known reasoning models as reasoning-capable", () => {
|
||||
const models = commandCodeModelsFromApiResponse({
|
||||
object: "list",
|
||||
data: [
|
||||
{ ...API_RESPONSE.data[0], id: "deepseek/deepseek-v4-flash" },
|
||||
{ ...API_RESPONSE.data[0], id: "new-model-without-metadata" },
|
||||
],
|
||||
})
|
||||
|
||||
assert.equal(models[0]?.reasoning, true)
|
||||
assert.equal(models[1]?.reasoning, false)
|
||||
})
|
||||
|
||||
it("builds explicit maps for every known effort set", () => {
|
||||
for (const [modelId, efforts] of Object.entries(MODEL_EFFORTS)) {
|
||||
const metadata = thinkingMetadataForModel(modelId)
|
||||
assert.ok(metadata, `${modelId} should have reasoning metadata`)
|
||||
for (const level of ["minimal", "low", "medium", "high", "xhigh", "max"] as const) {
|
||||
const expected = efforts.includes(level)
|
||||
assert.equal(
|
||||
metadata.thinkingLevelMap[level],
|
||||
expected ? level : null,
|
||||
`${modelId} should map ${level} according to its catalog entry`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
assert.deepEqual(thinkingLevelMapForEfforts(MODEL_EFFORTS["deepseek/deepseek-v4-flash"]), {
|
||||
minimal: null,
|
||||
low: null,
|
||||
medium: null,
|
||||
high: "high",
|
||||
xhigh: null,
|
||||
max: "max",
|
||||
})
|
||||
assert.deepEqual(thinkingMetadataForModel("new-model-without-metadata"), undefined)
|
||||
})
|
||||
|
||||
it("rejects unexpected API shapes", () => {
|
||||
assert.throws(() => commandCodeModelsFromApiResponse({ object: "list", data: [{}] }))
|
||||
})
|
||||
@@ -78,6 +132,20 @@ describe("commandCodeModelsFromCache()", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("normalizes cached reasoning metadata from the model id", () => {
|
||||
const cached = commandCodeModelsFromCache({
|
||||
version: 1,
|
||||
models: [
|
||||
{
|
||||
...EXPECTED_MODELS[0],
|
||||
id: "deepseek/deepseek-v4-flash",
|
||||
reasoning: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
assert.equal(cached[0]?.reasoning, true)
|
||||
})
|
||||
|
||||
it("rejects empty, invalid, and unsupported caches", () => {
|
||||
assert.throws(() => commandCodeModelsFromCache({ version: 1, models: [] }))
|
||||
assert.throws(() => commandCodeModelsFromCache({ version: 2, models: EXPECTED_MODELS }))
|
||||
@@ -90,7 +158,58 @@ describe("commandCodeModelsFromCache()", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("model discovery configuration", () => {
|
||||
it("uses a safe default timeout and ignores invalid environment values", () => {
|
||||
assert.equal(getModelsTimeoutMs({}), DEFAULT_MODELS_TIMEOUT_MS)
|
||||
assert.equal(
|
||||
getModelsTimeoutMs({ COMMANDCODE_MODELS_TIMEOUT_MS: "0" }),
|
||||
DEFAULT_MODELS_TIMEOUT_MS,
|
||||
)
|
||||
assert.equal(
|
||||
getModelsTimeoutMs({ COMMANDCODE_MODELS_TIMEOUT_MS: "invalid" }),
|
||||
DEFAULT_MODELS_TIMEOUT_MS,
|
||||
)
|
||||
assert.equal(getModelsTimeoutMs({ COMMANDCODE_MODELS_TIMEOUT_MS: "25" }), 25)
|
||||
})
|
||||
})
|
||||
|
||||
describe("loadCommandCodeModels()", () => {
|
||||
it("falls back to cache when live discovery times out", async () => {
|
||||
await withTemporaryCache(async ({ cachePath }) => {
|
||||
await loadCommandCodeModels({ cachePath, fetchImpl: successfulFetch() })
|
||||
|
||||
const startedAt = Date.now()
|
||||
const result = await loadCommandCodeModels({
|
||||
cachePath,
|
||||
fetchImpl: hangingFetch(),
|
||||
timeoutMs: 25,
|
||||
})
|
||||
|
||||
assert.ok(Date.now() - startedAt < 500)
|
||||
assert.deepEqual(result.models, EXPECTED_MODELS)
|
||||
assert.equal(result.source, "cache")
|
||||
assert.match(result.warning ?? "", /timed out after 25ms/)
|
||||
assert.match(result.warning ?? "", /Using the cached catalog/)
|
||||
})
|
||||
})
|
||||
|
||||
it("preserves an external abort instead of falling back to cache", async () => {
|
||||
await withTemporaryCache(async ({ cachePath }) => {
|
||||
await loadCommandCodeModels({ cachePath, fetchImpl: successfulFetch() })
|
||||
const controller = new AbortController()
|
||||
const promise = loadCommandCodeModels({
|
||||
cachePath,
|
||||
fetchImpl: hangingFetch(),
|
||||
timeoutMs: 1_000,
|
||||
signal: controller.signal,
|
||||
})
|
||||
|
||||
controller.abort(new Error("caller cancelled discovery"))
|
||||
|
||||
await assert.rejects(promise, /caller cancelled discovery/)
|
||||
})
|
||||
})
|
||||
|
||||
it("returns live models and writes a validated cache", async () => {
|
||||
await withTemporaryCache(async ({ cachePath }) => {
|
||||
const result = await loadCommandCodeModels({
|
||||
@@ -132,7 +251,7 @@ describe("loadCommandCodeModels()", () => {
|
||||
assert.deepEqual(result.models, [])
|
||||
assert.equal(result.source, "empty")
|
||||
assert.match(result.warning ?? "", /no valid cached catalog/)
|
||||
assert.match(result.warning ?? "", /until \/reload succeeds/)
|
||||
assert.match(result.warning ?? "", /until \/commandcode-refresh succeeds/)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user