ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Этап 4.3: унификация контракта ответов и добавление теста формы Stage 4
This commit is contained in:
@@ -733,6 +733,50 @@ function formatList(items: string[]): string {
|
||||
return items.map((item) => `- ${item}`).join("\n");
|
||||
}
|
||||
|
||||
function renderStage4ContractReply(input: {
|
||||
shortLine: string;
|
||||
checkedLines: string[];
|
||||
foundLines: string[];
|
||||
unresolvedLines: string[];
|
||||
nextStepLines: string[];
|
||||
nextStepTitle: "Что проверить первым" | "Что могу сделать сейчас";
|
||||
contextLead?: string | null;
|
||||
}): string {
|
||||
const shortLine = ensureSentence(input.shortLine);
|
||||
const checkedLines = dedupeNarrativeLines(input.checkedLines, 6);
|
||||
const foundLines = dedupeNarrativeLines(input.foundLines, 6);
|
||||
const unresolvedLines = dedupeNarrativeLines(input.unresolvedLines, 6);
|
||||
const nextStepLines = dedupeNarrativeLines(input.nextStepLines, 5);
|
||||
const contextLead = ensureSentence(String(input.contextLead ?? ""));
|
||||
|
||||
return sanitizeUserFacingReply(
|
||||
[
|
||||
`Коротко: ${shortLine}`,
|
||||
contextLead || "",
|
||||
`Что именно проверено:\n${formatList(
|
||||
checkedLines.length > 0
|
||||
? checkedLines
|
||||
: ["Подтвержденная опора собрана частично; для полного вывода нужен дополнительный проход."]
|
||||
)}`,
|
||||
`Что найдено:\n${formatList(
|
||||
foundLines.length > 0 ? foundLines : ["Явные отклонения по текущей опоре не подтверждены."]
|
||||
)}`,
|
||||
`Что пока не доказано:\n${formatList(
|
||||
unresolvedLines.length > 0
|
||||
? unresolvedLines
|
||||
: ["Существенных ограничений в текущем срезе не выявлено."]
|
||||
)}`,
|
||||
`${input.nextStepTitle}:\n${formatList(
|
||||
nextStepLines.length > 0
|
||||
? nextStepLines
|
||||
: ["Уточните период, объект или контрагента, чтобы продолжить проверку по 1С."]
|
||||
)}`
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
);
|
||||
}
|
||||
|
||||
function formatSafeItemLine(entity: unknown, sourceId: unknown, riskScore?: unknown): string {
|
||||
const entityLabel = sanitizeUserText(String(entity ?? "")) ?? "Record";
|
||||
const idRaw = String(sourceId ?? "").trim();
|
||||
@@ -2023,30 +2067,23 @@ function buildBoundaryFallbackReply(input: {
|
||||
"Сейчас у меня нет надежного доменного маршрута по этому запросу, поэтому даю мягкий отказ вместо шаблонной технички."
|
||||
]
|
||||
);
|
||||
return sanitizeUserFacingReply(
|
||||
[
|
||||
`Коротко: ${ensureSentence(heading)}`,
|
||||
`Что именно проверено:\n${formatList([
|
||||
"Проверен доступный контур 1С и возможность маршрутизации запроса.",
|
||||
"Надежный доменный путь для текущей формулировки не подтвержден."
|
||||
])}`,
|
||||
`Что найдено:\n${formatList(
|
||||
nearbyCapabilities.length > 0
|
||||
? nearbyCapabilities
|
||||
: ["Близких поддерживаемых сценариев по текущей формулировке не найдено."]
|
||||
)}`,
|
||||
`Что пока не доказано:\n${formatList([
|
||||
"Запрос не подтвержден в поддерживаемом контуре как надежный бухгалтерский сценарий."
|
||||
])}`,
|
||||
`Что могу сделать сейчас:\n${formatList(
|
||||
quickActionItems.length > 0
|
||||
? quickActionItems
|
||||
: [quickActionLine ?? "Переформулируйте вопрос через период, счет или объект, и я сразу продолжу проверку."]
|
||||
)}`
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
);
|
||||
return renderStage4ContractReply({
|
||||
shortLine: heading,
|
||||
checkedLines: [
|
||||
"Проверен доступный контур 1С и возможность маршрутизации запроса.",
|
||||
"Надежный доменный путь для текущей формулировки не подтвержден."
|
||||
],
|
||||
foundLines:
|
||||
nearbyCapabilities.length > 0
|
||||
? nearbyCapabilities
|
||||
: ["Близких поддерживаемых сценариев по текущей формулировке не найдено."],
|
||||
unresolvedLines: ["Запрос не подтвержден в поддерживаемом контуре как надежный бухгалтерский сценарий."],
|
||||
nextStepLines:
|
||||
quickActionItems.length > 0
|
||||
? quickActionItems
|
||||
: [quickActionLine ?? "Переформулируйте вопрос через период, счет или объект, и я сразу продолжу проверку."],
|
||||
nextStepTitle: "Что могу сделать сейчас"
|
||||
});
|
||||
}
|
||||
|
||||
const clarificationHints = buildNaturalClarificationHints({
|
||||
@@ -2060,32 +2097,26 @@ function buildBoundaryFallbackReply(input: {
|
||||
`По сценарию ${formatNarrativeDomainLabel(input.focusDomain)} пока не хватает подтвержденной опоры для надежного вывода.`
|
||||
]
|
||||
);
|
||||
return sanitizeUserFacingReply(
|
||||
[
|
||||
`Коротко: ${ensureSentence(domainHeading)}`,
|
||||
`Что именно проверено:\n${formatList([
|
||||
`Проверен сценарий ${formatNarrativeDomainLabel(input.focusDomain)} в текущем контуре 1С.`,
|
||||
"Оценена достаточность подтвержденной опоры для прямого вывода."
|
||||
])}`,
|
||||
`Что найдено:\n${formatList(
|
||||
nearbyCapabilities.length > 0
|
||||
? nearbyCapabilities.slice(0, 2)
|
||||
: ["Подтвержденных близких сценариев в текущем проходе не найдено."]
|
||||
)}`,
|
||||
`Что пока не доказано:\n${formatList(
|
||||
clarificationHints.length > 0
|
||||
? clarificationHints
|
||||
: ["Без дополнительного ориентира (период, объект или контрагент) вывод останется частичным."]
|
||||
)}`,
|
||||
`Что могу сделать сейчас:\n${formatList(
|
||||
quickActionItems.length > 0
|
||||
? quickActionItems
|
||||
: [quickActionLine ?? "Добавьте один уточняющий ориентир, и я продолжу проверку без смены контура."]
|
||||
)}`
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
);
|
||||
return renderStage4ContractReply({
|
||||
shortLine: domainHeading,
|
||||
checkedLines: [
|
||||
`Проверен сценарий ${formatNarrativeDomainLabel(input.focusDomain)} в текущем контуре 1С.`,
|
||||
"Оценена достаточность подтвержденной опоры для прямого вывода."
|
||||
],
|
||||
foundLines:
|
||||
nearbyCapabilities.length > 0
|
||||
? nearbyCapabilities.slice(0, 2)
|
||||
: ["Подтвержденных близких сценариев в текущем проходе не найдено."],
|
||||
unresolvedLines:
|
||||
clarificationHints.length > 0
|
||||
? clarificationHints
|
||||
: ["Без дополнительного ориентира (период, объект или контрагент) вывод останется частичным."],
|
||||
nextStepLines:
|
||||
quickActionItems.length > 0
|
||||
? quickActionItems
|
||||
: [quickActionLine ?? "Добавьте один уточняющий ориентир, и я продолжу проверку без смены контура."],
|
||||
nextStepTitle: "Что могу сделать сейчас"
|
||||
});
|
||||
}
|
||||
|
||||
function ensureSentence(value: string): string {
|
||||
@@ -4377,36 +4408,14 @@ function renderPolicyReply(structure: AnswerStructureV11, context?: AnswerRender
|
||||
limitationLines
|
||||
};
|
||||
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(
|
||||
[
|
||||
`Коротко: ${enriched.shortLine}`,
|
||||
`Что именно проверено:\n${formatList(
|
||||
checkedLines.length > 0
|
||||
? checkedLines
|
||||
: ["Подтвержденная опора собрана частично; для полного вывода нужен дополнительный проход."]
|
||||
)}`,
|
||||
`Что найдено:\n${formatList(
|
||||
foundLines.length > 0 ? foundLines : ["Явные отклонения по текущей опоре не подтверждены."]
|
||||
)}`,
|
||||
`Что пока не доказано:\n${formatList(
|
||||
unresolvedLines.length > 0
|
||||
? unresolvedLines
|
||||
: ["Существенных ограничений в текущем срезе не выявлено."]
|
||||
)}`,
|
||||
`Что проверить первым:\n${formatList(
|
||||
nextStepLines.length > 0
|
||||
? nextStepLines
|
||||
: ["Уточните период, объект или контрагента, чтобы продолжить проверку по 1С."]
|
||||
)}`
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
);
|
||||
return renderStage4ContractReply({
|
||||
shortLine: enriched.shortLine,
|
||||
checkedLines: enriched.evidenceLines,
|
||||
foundLines: [...enriched.brokenLines, ...enriched.whyLines],
|
||||
unresolvedLines: enriched.limitationLines,
|
||||
nextStepLines: enriched.checkLines,
|
||||
nextStepTitle: "Что проверить первым"
|
||||
});
|
||||
}
|
||||
|
||||
function shouldUseSoftPolicyReply(input: {
|
||||
@@ -4468,32 +4477,22 @@ function renderSoftPolicyReply(input: {
|
||||
: input.mode === "no_grounded" || input.mode === "empty"
|
||||
? "Сейчас подтвержденной опоры недостаточно для прямого вывода."
|
||||
: "Есть рабочие сигналы, но часть вывода пока ограничена.";
|
||||
return sanitizeUserFacingReply(
|
||||
[
|
||||
`Коротко: ${shortLine}`,
|
||||
modeLine,
|
||||
`Что именно проверено:\n${formatList(
|
||||
evidenceLines.length > 0
|
||||
? evidenceLines
|
||||
: ["Подтвержденная опора собрана частично; для полного вывода нужна дополнительная проверка."]
|
||||
)}`,
|
||||
`Что найдено:\n${formatList(
|
||||
foundLines.length > 0 ? foundLines : ["Пока подтверждена только часть сигнала, без финальной фиксации причины."]
|
||||
)}`,
|
||||
`Что пока не доказано:\n${formatList(
|
||||
limitationLines.length > 0
|
||||
? limitationLines
|
||||
: ["Для полного вывода не хватает деталей по части требований."]
|
||||
)}`,
|
||||
`Что могу сделать сейчас:\n${formatList(
|
||||
actionLines.length > 0
|
||||
? actionLines
|
||||
: ["Уточните период, объект или контрагента, чтобы завершить проверку в следующем ходе."]
|
||||
)}`
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
);
|
||||
return renderStage4ContractReply({
|
||||
shortLine,
|
||||
checkedLines:
|
||||
evidenceLines.length > 0
|
||||
? evidenceLines
|
||||
: ["Подтвержденная опора собрана частично; для полного вывода нужна дополнительная проверка."],
|
||||
foundLines:
|
||||
foundLines.length > 0 ? foundLines : ["Пока подтверждена только часть сигнала, без финальной фиксации причины."],
|
||||
unresolvedLines:
|
||||
limitationLines.length > 0 ? [modeLine, ...limitationLines] : [modeLine, "Для полного вывода не хватает деталей по части требований."],
|
||||
nextStepLines:
|
||||
actionLines.length > 0
|
||||
? actionLines
|
||||
: ["Уточните период, объект или контрагента, чтобы завершить проверку в следующем ходе."],
|
||||
nextStepTitle: "Что могу сделать сейчас"
|
||||
});
|
||||
}
|
||||
|
||||
function composeAssistantAnswerV11(input: ComposeAnswerInput): ComposeAnswerOutput {
|
||||
|
||||
Reference in New Issue
Block a user