ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг - Этап 4: обновлён формат ответов и добавлено правило о русском названии коммита
This commit is contained in:
parent
8167bd228d
commit
5a8edfb4f3
|
|
@ -1,6 +1,9 @@
|
||||||
## encoding_rule
|
## encoding_rule
|
||||||
- All source/code/config/docs files must be saved and edited in UTF-8 without BOM; never write mojibake placeholders or replacement characters.
|
- All source/code/config/docs files must be saved and edited in UTF-8 without BOM; never write mojibake placeholders or replacement characters.
|
||||||
|
|
||||||
|
## commit_message_rule
|
||||||
|
- After applying fixes, always provide the user with a ready commit title in Russian.
|
||||||
|
|
||||||
## graphify
|
## graphify
|
||||||
|
|
||||||
This project has a graphify knowledge graph at graphify-out/.
|
This project has a graphify knowledge graph at graphify-out/.
|
||||||
|
|
|
||||||
|
|
@ -2629,7 +2629,29 @@ Stage 4 kickoff preconditions:
|
||||||
2. No route/MCP interface changes are required to start Stage 4.
|
2. No route/MCP interface changes are required to start Stage 4.
|
||||||
3. Remaining acknowledged risk: domain coverage is still limited and will be expanded iteratively.
|
3. Remaining acknowledged risk: domain coverage is still limited and will be expanded iteratively.
|
||||||
|
|
||||||
Status: Ready to start (kickoff approved on 2026-04-11)
|
Implemented in current pass (Stage 4.1 answer-layer contract rollout, 2026-04-12):
|
||||||
|
1. Reworked Stage 1.1 policy renderer to Stage 4 human-centric 5-block response contract:
|
||||||
|
- `Коротко`
|
||||||
|
- `Что именно проверено`
|
||||||
|
- `Что найдено`
|
||||||
|
- `Что пока не доказано`
|
||||||
|
- `Что проверить первым`
|
||||||
|
2. Reworked weak-envelope soft policy renderer to the same contract shape with strict uncertainty and actionable next-step blocks.
|
||||||
|
3. Preserved route/runtime behavior:
|
||||||
|
- no MCP route changes;
|
||||||
|
- no transport/schema refactor;
|
||||||
|
- claim/evidence contract (`answer_structure_v11`) remains source of truth.
|
||||||
|
4. Updated regression expectations to Stage 4 response shape:
|
||||||
|
- `assistantSoftPolicyReply`
|
||||||
|
- `assistantWave6ProblemFirstAnswerContract`
|
||||||
|
- `assistantWave10SettlementCorrectiveRegression`
|
||||||
|
- `assistantWave12VatMonthCloseConsistencyRegression`
|
||||||
|
- `assistantAnswerPolicyV11`
|
||||||
|
5. Validation snapshot:
|
||||||
|
- focused Stage 4 answer pack: `5 files / 30 tests passed`;
|
||||||
|
- `npm --prefix llm_normalizer/backend run build` passed.
|
||||||
|
|
||||||
|
Status: In progress (Stage 4.1 completed; continue with quality loop on real runs/manual comments)
|
||||||
|
|
||||||
## Stage 5 (P3): Quality Loop Driven By GUI Markup
|
## Stage 5 (P3): Quality Loop Driven By GUI Markup
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3649,13 +3649,22 @@ function renderPolicyReply(structure, context) {
|
||||||
limitationLines
|
limitationLines
|
||||||
};
|
};
|
||||||
const enriched = enforceDomainWordingIsolation(enrichedBase, structure, context);
|
const enriched = enforceDomainWordingIsolation(enrichedBase, structure, context);
|
||||||
|
const checkedLines = dedupeNarrativeLines(enriched.evidenceLines, 6);
|
||||||
|
const foundLines = dedupeNarrativeLines([...enriched.brokenLines, ...enriched.whyLines], 6);
|
||||||
|
const unresolvedLines = dedupeNarrativeLines(enriched.limitationLines, 6);
|
||||||
|
const nextStepLines = dedupeNarrativeLines(enriched.checkLines, 5);
|
||||||
return sanitizeUserFacingReply([
|
return sanitizeUserFacingReply([
|
||||||
`Коротко: ${enriched.shortLine}`,
|
`Коротко: ${enriched.shortLine}`,
|
||||||
`Что сломано:\n${formatList(enriched.brokenLines)}`,
|
`Что именно проверено:\n${formatList(checkedLines.length > 0
|
||||||
`Почему это похоже на проблему:\n${formatList(enriched.whyLines)}`,
|
? checkedLines
|
||||||
`На чем это основано:\n${formatList(enriched.evidenceLines)}`,
|
: ["Подтвержденная опора собрана частично; для полного вывода нужен дополнительный проход."])}`,
|
||||||
`Что проверить первым:\n${formatList(enriched.checkLines)}`,
|
`Что найдено:\n${formatList(foundLines.length > 0 ? foundLines : ["Явные отклонения по текущей опоре не подтверждены."])}`,
|
||||||
`Ограничения:\n${formatList(enriched.limitationLines)}`
|
`Что пока не доказано:\n${formatList(unresolvedLines.length > 0
|
||||||
|
? unresolvedLines
|
||||||
|
: ["Существенных ограничений в текущем срезе не выявлено."])}`,
|
||||||
|
`Что проверить первым:\n${formatList(nextStepLines.length > 0
|
||||||
|
? nextStepLines
|
||||||
|
: ["Уточните период, объект или контрагента, чтобы продолжить проверку по 1С."])}`
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n\n"));
|
.join("\n\n"));
|
||||||
|
|
@ -3687,6 +3696,7 @@ function shouldUseSoftPolicyReply(input) {
|
||||||
function renderSoftPolicyReply(input) {
|
function renderSoftPolicyReply(input) {
|
||||||
const questionType = input.context?.questionType ?? "unknown";
|
const questionType = input.context?.questionType ?? "unknown";
|
||||||
const shortLine = ensureSentence(buildShortSectionLine(input.structure));
|
const shortLine = ensureSentence(buildShortSectionLine(input.structure));
|
||||||
|
const foundLines = dedupeNarrativeLines([...buildBrokenSectionLines(input.structure), ...buildWhySectionLines(input.structure, input.context)], 3);
|
||||||
const evidenceLines = dedupeNarrativeLines(buildEvidenceSectionLines(input.structure, questionType, input.context), 3);
|
const evidenceLines = dedupeNarrativeLines(buildEvidenceSectionLines(input.structure, questionType, input.context), 3);
|
||||||
const limitationLines = dedupeNarrativeLines(buildLimitationsSectionLines(input.structure), 3);
|
const limitationLines = dedupeNarrativeLines(buildLimitationsSectionLines(input.structure), 3);
|
||||||
const checkLines = dedupeNarrativeLines(buildChecksSectionLines(input.structure, input.context), 3);
|
const checkLines = dedupeNarrativeLines(buildChecksSectionLines(input.structure, input.context), 3);
|
||||||
|
|
@ -3700,9 +3710,16 @@ function renderSoftPolicyReply(input) {
|
||||||
return sanitizeUserFacingReply([
|
return sanitizeUserFacingReply([
|
||||||
`Коротко: ${shortLine}`,
|
`Коротко: ${shortLine}`,
|
||||||
modeLine,
|
modeLine,
|
||||||
evidenceLines.length > 0 ? `Что уже проверено: ${evidenceLines.join("; ")}` : "",
|
`Что именно проверено:\n${formatList(evidenceLines.length > 0
|
||||||
limitationLines.length > 0 ? `Что пока не доказано: ${limitationLines.join("; ")}` : "",
|
? evidenceLines
|
||||||
actionLines.length > 0 ? `Что могу сделать сейчас: ${actionLines.join("; ")}` : ""
|
: ["Подтвержденная опора собрана частично; для полного вывода нужна дополнительная проверка."])}`,
|
||||||
|
`Что найдено:\n${formatList(foundLines.length > 0 ? foundLines : ["Пока подтверждена только часть сигнала, без финальной фиксации причины."])}`,
|
||||||
|
`Что пока не доказано:\n${formatList(limitationLines.length > 0
|
||||||
|
? limitationLines
|
||||||
|
: ["Для полного вывода не хватает деталей по части требований."])}`,
|
||||||
|
`Что могу сделать сейчас:\n${formatList(actionLines.length > 0
|
||||||
|
? actionLines
|
||||||
|
: ["Уточните период, объект или контрагента, чтобы завершить проверку в следующем ходе."])}`
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n\n"));
|
.join("\n\n"));
|
||||||
|
|
|
||||||
|
|
@ -4338,15 +4338,32 @@ function renderPolicyReply(structure: AnswerStructureV11, context?: AnswerRender
|
||||||
limitationLines
|
limitationLines
|
||||||
};
|
};
|
||||||
const enriched = enforceDomainWordingIsolation(enrichedBase, structure, context);
|
const enriched = enforceDomainWordingIsolation(enrichedBase, structure, context);
|
||||||
|
const checkedLines = dedupeNarrativeLines(enriched.evidenceLines, 6);
|
||||||
|
const foundLines = dedupeNarrativeLines([...enriched.brokenLines, ...enriched.whyLines], 6);
|
||||||
|
const unresolvedLines = dedupeNarrativeLines(enriched.limitationLines, 6);
|
||||||
|
const nextStepLines = dedupeNarrativeLines(enriched.checkLines, 5);
|
||||||
|
|
||||||
return sanitizeUserFacingReply(
|
return sanitizeUserFacingReply(
|
||||||
[
|
[
|
||||||
`Коротко: ${enriched.shortLine}`,
|
`Коротко: ${enriched.shortLine}`,
|
||||||
`Что сломано:\n${formatList(enriched.brokenLines)}`,
|
`Что именно проверено:\n${formatList(
|
||||||
`Почему это похоже на проблему:\n${formatList(enriched.whyLines)}`,
|
checkedLines.length > 0
|
||||||
`На чем это основано:\n${formatList(enriched.evidenceLines)}`,
|
? checkedLines
|
||||||
`Что проверить первым:\n${formatList(enriched.checkLines)}`,
|
: ["Подтвержденная опора собрана частично; для полного вывода нужен дополнительный проход."]
|
||||||
`Ограничения:\n${formatList(enriched.limitationLines)}`
|
)}`,
|
||||||
|
`Что найдено:\n${formatList(
|
||||||
|
foundLines.length > 0 ? foundLines : ["Явные отклонения по текущей опоре не подтверждены."]
|
||||||
|
)}`,
|
||||||
|
`Что пока не доказано:\n${formatList(
|
||||||
|
unresolvedLines.length > 0
|
||||||
|
? unresolvedLines
|
||||||
|
: ["Существенных ограничений в текущем срезе не выявлено."]
|
||||||
|
)}`,
|
||||||
|
`Что проверить первым:\n${formatList(
|
||||||
|
nextStepLines.length > 0
|
||||||
|
? nextStepLines
|
||||||
|
: ["Уточните период, объект или контрагента, чтобы продолжить проверку по 1С."]
|
||||||
|
)}`
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n\n")
|
.join("\n\n")
|
||||||
|
|
@ -4394,6 +4411,10 @@ function renderSoftPolicyReply(input: {
|
||||||
}): string {
|
}): string {
|
||||||
const questionType = input.context?.questionType ?? "unknown";
|
const questionType = input.context?.questionType ?? "unknown";
|
||||||
const shortLine = ensureSentence(buildShortSectionLine(input.structure));
|
const shortLine = ensureSentence(buildShortSectionLine(input.structure));
|
||||||
|
const foundLines = dedupeNarrativeLines(
|
||||||
|
[...buildBrokenSectionLines(input.structure), ...buildWhySectionLines(input.structure, input.context)],
|
||||||
|
3
|
||||||
|
);
|
||||||
const evidenceLines = dedupeNarrativeLines(buildEvidenceSectionLines(input.structure, questionType, input.context), 3);
|
const evidenceLines = dedupeNarrativeLines(buildEvidenceSectionLines(input.structure, questionType, input.context), 3);
|
||||||
const limitationLines = dedupeNarrativeLines(buildLimitationsSectionLines(input.structure), 3);
|
const limitationLines = dedupeNarrativeLines(buildLimitationsSectionLines(input.structure), 3);
|
||||||
const checkLines = dedupeNarrativeLines(buildChecksSectionLines(input.structure, input.context), 3);
|
const checkLines = dedupeNarrativeLines(buildChecksSectionLines(input.structure, input.context), 3);
|
||||||
|
|
@ -4412,9 +4433,24 @@ function renderSoftPolicyReply(input: {
|
||||||
[
|
[
|
||||||
`Коротко: ${shortLine}`,
|
`Коротко: ${shortLine}`,
|
||||||
modeLine,
|
modeLine,
|
||||||
evidenceLines.length > 0 ? `Что уже проверено: ${evidenceLines.join("; ")}` : "",
|
`Что именно проверено:\n${formatList(
|
||||||
limitationLines.length > 0 ? `Что пока не доказано: ${limitationLines.join("; ")}` : "",
|
evidenceLines.length > 0
|
||||||
actionLines.length > 0 ? `Что могу сделать сейчас: ${actionLines.join("; ")}` : ""
|
? evidenceLines
|
||||||
|
: ["Подтвержденная опора собрана частично; для полного вывода нужна дополнительная проверка."]
|
||||||
|
)}`,
|
||||||
|
`Что найдено:\n${formatList(
|
||||||
|
foundLines.length > 0 ? foundLines : ["Пока подтверждена только часть сигнала, без финальной фиксации причины."]
|
||||||
|
)}`,
|
||||||
|
`Что пока не доказано:\n${formatList(
|
||||||
|
limitationLines.length > 0
|
||||||
|
? limitationLines
|
||||||
|
: ["Для полного вывода не хватает деталей по части требований."]
|
||||||
|
)}`,
|
||||||
|
`Что могу сделать сейчас:\n${formatList(
|
||||||
|
actionLines.length > 0
|
||||||
|
? actionLines
|
||||||
|
: ["Уточните период, объект или контрагента, чтобы завершить проверку в следующем ходе."]
|
||||||
|
)}`
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n\n")
|
.join("\n\n")
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ describe.sequential("assistant answer policy v1.1", () => {
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
expect(["partial_coverage", "factual_with_explanation", "factual"]).toContain(response.body.reply_type);
|
expect(["partial_coverage", "factual_with_explanation", "factual"]).toContain(response.body.reply_type);
|
||||||
expect(String(response.body.assistant_reply)).toMatch(/не хватает|уточните|опорного ориентира|Ограничения:/i);
|
expect(String(response.body.assistant_reply)).toMatch(/не хватает|уточните|опорного ориентира|Что пока не доказано:/i);
|
||||||
expect(String(response.body.assistant_reply)).toMatch(/Что проверить первым:|Что могу сделать сейчас:/i);
|
expect(String(response.body.assistant_reply)).toMatch(/Что проверить первым:|Что могу сделать сейчас:/i);
|
||||||
|
|
||||||
const structure = response.body.debug?.answer_structure_v11;
|
const structure = response.body.debug?.answer_structure_v11;
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ describe("assistant soft policy reply", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(output.reply_type).toBe("factual_with_explanation");
|
expect(output.reply_type).toBe("factual_with_explanation");
|
||||||
expect(output.assistant_reply).toContain("Что сломано:");
|
expect(output.assistant_reply).toContain("Что найдено:");
|
||||||
expect(output.assistant_reply).toContain("Ограничения:");
|
expect(output.assistant_reply).toContain("Что пока не доказано:");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -461,7 +461,7 @@ describe("wave10 settlement corrective regression", () => {
|
||||||
buildRetrieval({ requirementId: "R2", status: "empty" })
|
buildRetrieval({ requirementId: "R2", status: "empty" })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const checksSectionMatch = output.assistant_reply.match(/Что проверить первым:\s*([\s\S]*?)\s*Ограничения:/i);
|
const checksSectionMatch = output.assistant_reply.match(/Что проверить первым:\s*([\s\S]*)$/i);
|
||||||
const checksSection = checksSectionMatch?.[1] ?? "";
|
const checksSection = checksSectionMatch?.[1] ?? "";
|
||||||
expect(checksSection).toMatch(/договор|регистр|зачет|зачёт|60\/62/i);
|
expect(checksSection).toMatch(/договор|регистр|зачет|зачёт|60\/62/i);
|
||||||
const firstLine = checksSection
|
const firstLine = checksSection
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ describe("wave12 vat/month-close consistency + confidence reconciliation", () =>
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(output.reply_type).toBe("clarification_required");
|
expect(output.reply_type).toBe("clarification_required");
|
||||||
expect(output.assistant_reply).toContain("Ограничения:");
|
expect(output.assistant_reply).toContain("Что пока не доказано:");
|
||||||
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -331,7 +331,7 @@ describe("wave12 vat/month-close consistency + confidence reconciliation", () =>
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(output.reply_type).toBe("clarification_required");
|
expect(output.reply_type).toBe("clarification_required");
|
||||||
expect(output.assistant_reply).toContain("Ограничения:");
|
expect(output.assistant_reply).toContain("Что пока не доказано:");
|
||||||
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -364,7 +364,7 @@ describe("wave12 vat/month-close consistency + confidence reconciliation", () =>
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(output.answer_structure_v11?.mechanism_block?.status).toBe("limited");
|
expect(output.answer_structure_v11?.mechanism_block?.status).toBe("limited");
|
||||||
expect(output.assistant_reply).toContain("Ограничения:");
|
expect(output.assistant_reply).toContain("Что пока не доказано:");
|
||||||
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
expect(output.assistant_reply).not.toContain("Опора достаточна для первичного вывода.");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,11 +213,11 @@ function extractSection(text: string, title: string): string {
|
||||||
const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
const stopTitles = [
|
const stopTitles = [
|
||||||
"Коротко",
|
"Коротко",
|
||||||
"Что сломано",
|
"Что именно проверено",
|
||||||
"Почему это похоже на проблему",
|
"Что найдено",
|
||||||
"На чем это основано",
|
"Что пока не доказано",
|
||||||
"Что проверить первым",
|
"Что проверить первым",
|
||||||
"Ограничения"
|
"Что могу сделать сейчас"
|
||||||
];
|
];
|
||||||
const stopPattern = stopTitles.map((item) => item.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
const stopPattern = stopTitles.map((item) => item.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
||||||
const re = new RegExp(`${escaped}:([\\s\\S]*?)(?=(?:${stopPattern}):|$)`, "i");
|
const re = new RegExp(`${escaped}:([\\s\\S]*?)(?=(?:${stopPattern}):|$)`, "i");
|
||||||
|
|
@ -238,7 +238,7 @@ describe("assistant wave6 problem-first answer contract", () => {
|
||||||
it("keeps narrative mechanism-first and avoids entity-list direct answer", () => {
|
it("keeps narrative mechanism-first and avoids entity-list direct answer", () => {
|
||||||
const units = [buildProblemUnit({ id: "pu-1", type: "broken_chain_segment", defect: "failed_edge:payment_to_settlement", account: "60" })];
|
const units = [buildProblemUnit({ id: "pu-1", type: "broken_chain_segment", defect: "failed_edge:payment_to_settlement", account: "60" })];
|
||||||
const output = composeCase("Проверь по 60 счету, где разрыв.", buildRetrieval(units));
|
const output = composeCase("Проверь по 60 счету, где разрыв.", buildRetrieval(units));
|
||||||
const brokenSection = extractSection(output.assistant_reply, "Что сломано");
|
const brokenSection = extractSection(output.assistant_reply, "Что найдено");
|
||||||
|
|
||||||
expect(brokenSection).toMatch(/не подтвержден|разрыв|зависл|закрыти/i);
|
expect(brokenSection).toMatch(/не подтвержден|разрыв|зависл|закрыти/i);
|
||||||
expect(brokenSection).not.toMatch(/^\s*-\s*(Document|Record|Entity)\b/i);
|
expect(brokenSection).not.toMatch(/^\s*-\s*(Document|Record|Entity)\b/i);
|
||||||
|
|
@ -257,19 +257,22 @@ describe("assistant wave6 problem-first answer contract", () => {
|
||||||
buildProblemUnit({ id: "pu-2", type: "unresolved_settlement_cluster", defect: "payment_to_settlement", account: "60" })
|
buildProblemUnit({ id: "pu-2", type: "unresolved_settlement_cluster", defect: "payment_to_settlement", account: "60" })
|
||||||
];
|
];
|
||||||
const output = composeCase("Проверь хвост по расчетам.", buildRetrieval(units));
|
const output = composeCase("Проверь хвост по расчетам.", buildRetrieval(units));
|
||||||
const brokenSection = extractSection(output.assistant_reply, "Что сломано");
|
const brokenSection = extractSection(output.assistant_reply, "Что найдено");
|
||||||
const bulletLines = brokenSection
|
const bulletLines = brokenSection
|
||||||
.split(/\r?\n/g)
|
.split(/\r?\n/g)
|
||||||
.map((line) => line.trim())
|
.map((line) => line.trim())
|
||||||
.filter((line) => line.startsWith("- "));
|
.filter((line) => line.startsWith("- "));
|
||||||
|
const normalized = bulletLines.map((line) => line.replace(/\s+/g, " ").trim().toLowerCase());
|
||||||
|
const dedupedCount = new Set(normalized).size;
|
||||||
|
|
||||||
expect(bulletLines.length).toBe(1);
|
expect(bulletLines.length).toBeGreaterThan(0);
|
||||||
|
expect(dedupedCount).toBe(bulletLines.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows explicit limitation when period is missing", () => {
|
it("shows explicit limitation when period is missing", () => {
|
||||||
const units = [buildProblemUnit({ id: "pu-1", type: "lifecycle_anomaly_node", defect: "missing_expected_transition", account: "97", lifecycleDomain: "deferred_expense" })];
|
const units = [buildProblemUnit({ id: "pu-1", type: "lifecycle_anomaly_node", defect: "missing_expected_transition", account: "97", lifecycleDomain: "deferred_expense" })];
|
||||||
const output = composeCase("Проверь по 97 счету зависание списания.", buildRetrieval(units));
|
const output = composeCase("Проверь по 97 счету зависание списания.", buildRetrieval(units));
|
||||||
const limitationsSection = extractSection(output.assistant_reply, "Ограничения");
|
const limitationsSection = extractSection(output.assistant_reply, "Что пока не доказано");
|
||||||
|
|
||||||
expect(limitationsSection).toMatch(/период/i);
|
expect(limitationsSection).toMatch(/период/i);
|
||||||
});
|
});
|
||||||
|
|
@ -307,11 +310,12 @@ describe("assistant wave6 problem-first answer contract", () => {
|
||||||
const output = composeCase(testCase.message, testCase.retrieval);
|
const output = composeCase(testCase.message, testCase.retrieval);
|
||||||
expect(output.assistant_reply).toMatch(testCase.domainHint);
|
expect(output.assistant_reply).toMatch(testCase.domainHint);
|
||||||
expect(output.assistant_reply).toContain("Коротко:");
|
expect(output.assistant_reply).toContain("Коротко:");
|
||||||
expect(output.assistant_reply).toContain("Что сломано:");
|
expect(output.assistant_reply).toContain("Что именно проверено:");
|
||||||
expect(output.assistant_reply).toContain("Почему это похоже на проблему:");
|
expect(output.assistant_reply).toContain("Что найдено:");
|
||||||
expect(output.assistant_reply).toContain("На чем это основано:");
|
expect(output.assistant_reply).not.toContain("Почему это похоже на проблему:");
|
||||||
|
expect(output.assistant_reply).not.toContain("На чем это основано:");
|
||||||
|
expect(output.assistant_reply).toContain("Что пока не доказано:");
|
||||||
expect(output.assistant_reply).toContain("Что проверить первым:");
|
expect(output.assistant_reply).toContain("Что проверить первым:");
|
||||||
expect(output.assistant_reply).toContain("Ограничения:");
|
|
||||||
expect(output.assistant_reply.length).toBeLessThan(1800);
|
expect(output.assistant_reply.length).toBeLessThan(1800);
|
||||||
expect(output.assistant_reply).not.toMatch(/graph_|domain_scope|relation_patterns|semantic_profile|route|profile/i);
|
expect(output.assistant_reply).not.toMatch(/graph_|domain_scope|relation_patterns|semantic_profile|route|profile/i);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue