feat: complete TASK-WP3-01 model configuration

This commit is contained in:
suyx
2026-08-03 02:40:48 +08:00
parent 1b0a05bbcf
commit d79ac74fdd
19 changed files with 7018 additions and 3 deletions
@@ -0,0 +1,56 @@
import { describe, expect, it } from "vitest";
import {
ModelConfigurationError,
modelIds,
validateModelConfigurationCandidateSet,
type ModelConfigCandidate,
} from "../../apps/api/src/model-configuration.js";
function candidateSet(): ModelConfigCandidate[] {
return modelIds.map((modelId, index) => ({
model_id: modelId,
display_name: modelId,
enabled: true,
is_default: index === 0,
recommendation_priority: index + 1,
route_profile: { endpoint: "https://mock.invalid/v1/images" },
gateway_account_ref: "mock-gateway",
error_mapping_profile: { timeout: "upstream_timeout" },
credit_cost: 1,
supported_ratios: ["3:4", "1:1", "4:3", "9:16"],
reference_limits: { max_file_bytes: 1_024, max_files: 2, max_total_bytes: 2_048 },
prompt_max_length: 1_000,
safety_source: "provider",
}));
}
describe("TDD-WP3-MDL-002 invalid full configuration sets", () => {
it.each([
["missing", undefined],
["fractional", 1.5],
["zero", 0],
["negative", -1],
])("rejects a %s recommendation priority", (_name, value) => {
const models = candidateSet();
models[1].recommendation_priority = value as number;
expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(
expect.objectContaining({ code: "MODEL_RECOMMENDATION_PRIORITY_INVALID" }),
);
});
it("rejects duplicate priorities", () => {
const models = candidateSet();
models[1].recommendation_priority = models[0].recommendation_priority;
expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(
expect.objectContaining({ code: "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" }),
);
});
it.each(["missing model", "unknown model"])("rejects a candidate with a %s", (scenario) => {
const models = candidateSet();
if (scenario === "missing model") models.pop();
else models[2].model_id = "unknown-model";
expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(ModelConfigurationError);
});
});