АРЧ АП11 - Архитектура: вынести reply packaging из composeStage в отдельный owner

This commit is contained in:
2026-04-17 17:21:26 +03:00
parent 18e4eba54e
commit c2bafcff9b
6 changed files with 188 additions and 46 deletions
@@ -5,6 +5,16 @@ import type {
AddressResultMode
} from "../../types/addressQuery";
import { normalizeOrganizationScopeValue } from "../assistantOrganizationMatcher";
import {
finalizeComposeReplyResult,
inferAddressReplyType,
joinComposeReplyLines,
type ComposeFactualReplyOptions as ComposeFactualReplyOptionsBase,
type ComposeReplyResult,
type ComposeReplySemantics
} from "./replyPackaging";
export type { ComposeFactualReplyOptions, ComposeReplySemantics } from "./replyPackaging";
export interface ComposeStageRow {
period: string | null;
@@ -39,26 +49,7 @@ export interface VatDirectSourceProbeSummary {
errors: string[];
}
interface ComposeFactualReplyOptions {
userMessage?: string;
itemHint?: string;
counterpartyHint?: string;
organizationHint?: string;
accountHint?: string;
periodFrom?: string;
periodTo?: string;
asOfDate?: string;
requestedResultMode?: AddressResultMode;
vatDirectSourceProbe?: VatDirectSourceProbeSummary | null;
emphasizeNumbers?: boolean;
useRubCurrency?: boolean;
}
export interface ComposeReplySemantics {
result_mode?: AddressResultMode;
evidence_strength?: AddressEvidenceStrength;
balance_confirmed?: boolean;
}
type ComposeFactualReplyOptions = ComposeFactualReplyOptionsBase<VatDirectSourceProbeSummary>;
type PeriodProfileFocus =
| "full_profile"
@@ -2725,9 +2716,19 @@ export function composeFactualReply(
intent: AddressIntent,
rows: ComposeStageRow[],
options: ComposeFactualReplyOptions = {}
): { responseType: AddressResponseType; text: string; semantics?: ComposeReplySemantics } {
const applyNumericEmphasis = (line: string): string => (options.emphasizeNumbers ? emphasizeNumericTokens(line) : line);
const joinLines = (lines: string[]): string => lines.map(applyNumericEmphasis).join("\n");
) {
return finalizeComposeReplyResult(composeFactualReplyBody(intent, rows, options), {
emphasizeNumbers: options.emphasizeNumbers,
emphasizeNumericTokens
});
}
function composeFactualReplyBody(
intent: AddressIntent,
rows: ComposeStageRow[],
options: ComposeFactualReplyOptions = {}
): ComposeReplyResult {
const joinLines = joinComposeReplyLines;
if (intent === "document_type_and_account_section_profile") {
const rowsByMarker = new Map<string, ComposeStageRow[]>();
@@ -5496,8 +5497,5 @@ export function composeFactualReply(
}
export function inferReplyType(responseType: AddressResponseType): "factual" | "partial_coverage" {
if (responseType === "FACTUAL_LIST" || responseType === "FACTUAL_SUMMARY") {
return "factual";
}
return "partial_coverage";
return inferAddressReplyType(responseType);
}
@@ -0,0 +1,61 @@
import type { AddressEvidenceStrength, AddressResponseType, AddressResultMode } from "../../types/addressQuery";
export interface ComposeFactualReplyOptions<TVatDirectSourceProbe = unknown> {
userMessage?: string;
itemHint?: string;
counterpartyHint?: string;
organizationHint?: string;
accountHint?: string;
periodFrom?: string;
periodTo?: string;
asOfDate?: string;
requestedResultMode?: AddressResultMode;
vatDirectSourceProbe?: TVatDirectSourceProbe | null;
emphasizeNumbers?: boolean;
useRubCurrency?: boolean;
}
export interface ComposeReplySemantics {
result_mode?: AddressResultMode;
evidence_strength?: AddressEvidenceStrength;
balance_confirmed?: boolean;
}
export interface ComposeReplyResult {
responseType: AddressResponseType;
text: string;
semantics?: ComposeReplySemantics;
}
export interface FinalizeComposeReplyOptions {
emphasizeNumbers?: boolean;
emphasizeNumericTokens?: (line: string) => string;
}
export function joinComposeReplyLines(lines: string[]): string {
return lines.join("\n");
}
export function finalizeComposeReplyResult(
result: ComposeReplyResult,
options: FinalizeComposeReplyOptions = {}
): ComposeReplyResult {
if (!options.emphasizeNumbers || typeof options.emphasizeNumericTokens !== "function") {
return result;
}
return {
...result,
text: String(result.text ?? "")
.split("\n")
.map((line) => options.emphasizeNumericTokens!(line))
.join("\n")
};
}
export function inferAddressReplyType(responseType: AddressResponseType): "factual" | "partial_coverage" {
if (responseType === "FACTUAL_LIST" || responseType === "FACTUAL_SUMMARY") {
return "factual";
}
return "partial_coverage";
}