feat: add answer extraction replay commands
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import {
|
||||
collectExtractionBusinessIssues,
|
||||
repairExtractionParams,
|
||||
selectExtractionModel,
|
||||
} from "../src/answer-extraction.ts";
|
||||
|
||||
function model(provider: string, id: string) {
|
||||
return { provider, id } as never;
|
||||
}
|
||||
|
||||
test("selectExtractionModel uses first configured model with auth", async () => {
|
||||
const first = model("missing", "a");
|
||||
const second = model("ok", "b");
|
||||
const result = await selectExtractionModel(
|
||||
{
|
||||
model: model("fallback", "c"),
|
||||
modelRegistry: {
|
||||
find(provider: string, _id: string) {
|
||||
if (provider === "missing") {
|
||||
return first;
|
||||
}
|
||||
if (provider === "ok") {
|
||||
return second;
|
||||
}
|
||||
},
|
||||
getApiKeyAndHeaders(candidate: { provider: string }) {
|
||||
if (candidate.provider === "ok") {
|
||||
return Promise.resolve({ ok: true, apiKey: "key" });
|
||||
}
|
||||
return Promise.resolve({ ok: false, error: "no" });
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
[
|
||||
{ provider: "missing", id: "a" },
|
||||
{ provider: "ok", id: "b" },
|
||||
]
|
||||
);
|
||||
|
||||
assert.deepEqual(result, {
|
||||
model: second,
|
||||
auth: { ok: true, apiKey: "key" },
|
||||
usedFallback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("extraction business rules flag option spam", () => {
|
||||
const issues = collectExtractionBusinessIssues({
|
||||
questions: [
|
||||
{
|
||||
id: "q",
|
||||
prompt: "Pick one",
|
||||
options: [
|
||||
{ value: "a", label: "A" },
|
||||
{ value: "b", label: "B" },
|
||||
{ value: "c", label: "C" },
|
||||
{ value: "d", label: "D" },
|
||||
{ value: "e", label: "E" },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(issues, ["questions[0].options has 5 items; max is 4"]);
|
||||
});
|
||||
|
||||
test("repairExtractionParams caps options while preserving other", () => {
|
||||
const repaired = repairExtractionParams({
|
||||
questions: [
|
||||
{
|
||||
id: "q",
|
||||
prompt: "Pick one",
|
||||
options: [
|
||||
{ value: "a", label: "A" },
|
||||
{ value: "b", label: "B" },
|
||||
{ value: "c", label: "C" },
|
||||
{ value: "d", label: "D" },
|
||||
{ value: "other", label: "Other" },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
repaired.questions[0]?.options.map((option) => option.value),
|
||||
["a", "b", "c", "other"]
|
||||
);
|
||||
});
|
||||
|
||||
test("repairExtractionParams drops generic conversational prompts", () => {
|
||||
const repaired = repairExtractionParams({
|
||||
questions: [
|
||||
{
|
||||
id: "generic",
|
||||
prompt: "How can I help you today?",
|
||||
options: [{ value: "help", label: "Help me" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(repaired.questions, []);
|
||||
});
|
||||
|
||||
test("selectExtractionModel validates fallback model auth", async () => {
|
||||
const fallback = model("fallback", "c");
|
||||
const result = await selectExtractionModel(
|
||||
{
|
||||
model: fallback,
|
||||
modelRegistry: {
|
||||
find() {
|
||||
return;
|
||||
},
|
||||
getApiKeyAndHeaders() {
|
||||
return Promise.resolve({ ok: false, error: "no auth" });
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
[]
|
||||
);
|
||||
|
||||
assert.deepEqual(result, {
|
||||
error: "No auth for fallback chat model: fallback/c.",
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user