Этап 4 / Волна 18 закрытие блокеров по времени, доменной полярности и допуску доказательной базы

This commit is contained in:
2026-03-29 00:40:06 +03:00
parent 7eb1410501
commit d7e145010b
140 changed files with 417053 additions and 42196 deletions
@@ -0,0 +1,85 @@
export type ConversationExportMode = "default" | "technical";
export interface ConversationExportItem {
message_id: string;
role: "user" | "assistant";
text: string;
reply_type: string | null;
created_at: string;
trace_id: string | null;
debug?: unknown | null;
}
const DEBUG_SECTION_PATTERN =
/(?:^|\n)\s*#{0,6}\s*(?:debug_payload_json|technical_breakdown_json|route_summary_json|debug_payload|technical_breakdown)\b/i;
const INLINE_TECH_LINE_PATTERNS: RegExp[] = [
/\b(?:debug_payload_json|technical_breakdown_json)\b/i,
/\b(?:route_summary|semantic_profile|domain_scope|relation_patterns|account_scope)\b/i,
/\b(?:coverage_report|retrieval_status|problem_unit_state|candidate_evidence)\b/i,
/\b(?:graph_domain_scope|graph_runtime|selection_reason|why_included)\b/i
];
function stringifyDebug(value: unknown): string {
try {
return JSON.stringify(value, null, 2);
} catch {
return String(value);
}
}
export function sanitizeConversationExportText(value: string): string {
const raw = String(value ?? "");
const cutMatch = raw.match(DEBUG_SECTION_PATTERN);
const preCut = cutMatch ? raw.slice(0, cutMatch.index) : raw;
const withoutDebugHeadings = preCut
.replace(/###\s*(?:debug_payload_json|technical_breakdown_json|route_summary_json)[\s\S]*?(?:```[\s\S]*?```|$)/gi, "")
.replace(/(?:^|\n)\s*#{0,6}\s*(?:debug_payload_json|technical_breakdown_json|route_summary_json)\b[\s\S]*$/gi, "");
const lines = withoutDebugHeadings
.split(/\r?\n/g)
.map((line) => line.trimEnd())
.filter((line) => line.trim().length > 0)
.filter((line) => !INLINE_TECH_LINE_PATTERNS.some((pattern) => pattern.test(line)));
return lines.join("\n").trim();
}
export function buildConversationExportForCopy(
sessionId: string,
conversation: ConversationExportItem[],
mode: ConversationExportMode = "default"
): string {
const includeDebug = mode === "technical";
const lines: string[] = [];
lines.push("# Assistant conversation export");
lines.push(`session_id: ${sessionId || "n/a"}`);
lines.push(`export_mode: ${mode}`);
lines.push(`exported_at: ${new Date().toISOString()}`);
lines.push("");
for (let index = 0; index < conversation.length; index += 1) {
const item = conversation[index];
const safeText = sanitizeConversationExportText(item.text || "");
lines.push(`## ${index + 1}. ${item.role}`);
lines.push(`message_id: ${item.message_id}`);
lines.push(`created_at: ${item.created_at}`);
lines.push(`reply_type: ${item.reply_type ?? "n/a"}`);
if (item.trace_id) {
lines.push(`trace_id: ${item.trace_id}`);
}
lines.push("");
lines.push(safeText || "(empty)");
lines.push("");
if (includeDebug && item.role === "assistant" && item.debug) {
lines.push("### technical_debug_payload_json");
lines.push("```json");
lines.push(stringifyDebug(item.debug));
lines.push("```");
lines.push("");
}
}
return lines.join("\n");
}