diff --git a/docs/ARCH/11 - architecture_turnaround/14 - semantic_dialog_authority_recovery_plan_2026-04-19.md b/docs/ARCH/11 - architecture_turnaround/14 - semantic_dialog_authority_recovery_plan_2026-04-19.md index d125ec1..735b1d0 100644 --- a/docs/ARCH/11 - architecture_turnaround/14 - semantic_dialog_authority_recovery_plan_2026-04-19.md +++ b/docs/ARCH/11 - architecture_turnaround/14 - semantic_dialog_authority_recovery_plan_2026-04-19.md @@ -1212,6 +1212,55 @@ Module progress: - Big Block 5 MCP Semantic Data Agent: `98%`. +## Progress Update - 2026-04-20 MCP Discovery Bidirectional Net Value-Flow Composition + +The eighteenth implementation slice of Big Block 5 adds the first composed MCP discovery value-flow answer. + +Before this slice the assistant could recover two separate guarded paths: + +- incoming customer revenue/value-flow through `customer_revenue_and_payments`; +- outgoing supplier payments/write-offs through `supplier_payouts_profile`. + +The new slice lets one current user question ask for both sides and the net result without adding a one-off hardcoded route. + +New behavior: + +- net/bidirectional wording such as `нетто`, `сальдо`, `взаиморасчет`, `получили и заплатили`, `incoming and outgoing`, and `received and paid` is recognized as `asked_action_family=net_value_flow`; +- the pilot scope `counterparty_bidirectional_value_flow_query_movements_v1` executes both reviewed movement profiles through the same guarded `query_movements` primitive family; +- runtime derives `derived_bidirectional_value_flow` with incoming amount, outgoing amount, net amount, side-specific row counts, first/latest dates, and side-specific probe-limit coverage; +- the user-facing answer says what was received, what was paid, and what net value can be inferred from found rows; +- if either side reaches the probe row limit, the answer explicitly says the full requested period is not proven and the net value is only a found-row calculation; +- the final response candidate still filters internal primitive/query/runtime/planner/catalog/pilot mechanics. + +Replay result: + +- `address_truth_harness_phase19_mcp_discovery_response_gate_live_rerun10` passed 7/7 after adding the new net-flow step; +- `address_truth_harness_phase19_mcp_discovery_response_gate_live_rerun11` passed 7/7 after answer punctuation cleanup; +- final status: `accepted`; +- the net-flow step answered through `mcp_discovery_response_candidate_guarded`; +- the bidirectional pilot scope was `counterparty_bidirectional_value_flow_query_movements_v1`; +- confirmed incoming found-row amount for `Группа СВК` in `2020`: `47 628 853,03 руб.`; +- confirmed outgoing found-row amount for `Группа СВК` in `2020`: `19 568 878,06 руб.`; +- found-row net in our favor: `28 059 974,97 руб.`; +- incoming coverage: `44 из 44` rows, first date `2020-01-09`, latest `2020-12-30`; +- outgoing coverage: `100 из 100` rows, first date `2020-01-09`, latest `2020-03-16`; +- because the outgoing side reached the row limit, the answer marks full-period coverage as unproven; +- user-facing text has no `query_documents`, `query_movements`, `runtime_`, `planner_`, `catalog_`, `primitive`, or `pilot_` leak. + +Validation: + +- `npm test -- assistantMcpDiscoveryTurnInputAdapter.test.ts assistantMcpDiscoveryPlanner.test.ts assistantMcpDiscoveryPilotExecutor.test.ts assistantMcpDiscoveryAnswerAdapter.test.ts assistantMcpDiscoveryResponseCandidate.test.ts assistantMcpDiscoveryResponsePolicy.test.ts assistantMcpDiscoveryRuntimeEntryPoint.test.ts assistantMcpDiscoveryRuntimeBridge.test.ts assistantAddressLaneResponseRuntimeAdapter.test.ts assistantDeepTurnResponseRuntimeAdapter.test.ts assistantLivingChatRuntimeAdapter.test.ts assistantAddressOrchestrationRuntimeAdapter.test.ts assistantDebugPayloadAssembler.test.ts` passed 85/85; +- `npm run build` passed; +- `python scripts/domain_truth_harness.py run-live --spec docs/orchestration/address_truth_harness_phase19_mcp_discovery_response_gate.json --output-dir artifacts/domain_runs/address_truth_harness_phase19_mcp_discovery_response_gate_live_rerun11 --timeout-seconds 180` passed 7/7, final status `accepted`. + +Known remaining boundary: + +- this is still profile-composed discovery, not arbitrary self-navigation through every 1C register. Richer coverage proofs, follow-up drilldown over discovered rows, and Qwen-planned multi-axis exploration remain future work. + +Module progress: + +- Big Block 5 MCP Semantic Data Agent: `99%`. + ## Execution Rule Do not implement this plan as: diff --git a/docs/orchestration/address_truth_harness_phase19_mcp_discovery_response_gate.json b/docs/orchestration/address_truth_harness_phase19_mcp_discovery_response_gate.json index f465d99..d85b638 100644 --- a/docs/orchestration/address_truth_harness_phase19_mcp_discovery_response_gate.json +++ b/docs/orchestration/address_truth_harness_phase19_mcp_discovery_response_gate.json @@ -141,7 +141,39 @@ ] }, { - "step_id": "step_06_off_domain_living_chat_not_hijacked", + "step_id": "step_06_counterparty_bidirectional_net_flow_uses_guarded_discovery", + "title": "Unsupported-but-understood counterparty net cash-flow question composes incoming and outgoing discovery", + "question": "какое нетто по деньгам с Группа СВК за 2020 год: сколько получили и сколько заплатили?", + "required_answer_patterns_all": [ + "(?i)свк", + "(?i)1с|найден|строк|проверен", + "(?i)получил|входящ|поступ", + "(?i)заплат|исходящ|списан|плат[её]ж", + "(?i)нетто|сальдо|разниц", + "(?i)сумм|руб", + "(?i)2020|период", + "(?i)не подтвержд|проверенн|найденн" + ], + "forbidden_answer_patterns": [ + "(?i)точный маршрут.*не подключ", + "(?i)не буду подставлять", + "(?i)query_documents", + "(?i)query_movements", + "(?i)runtime_", + "(?i)planner_", + "(?i)catalog_", + "(?i)primitive", + "(?i)pilot_" + ], + "criticality": "critical", + "semantic_tags": [ + "mcp_discovery_bidirectional_value_flow", + "counterparty_net_cash_flow", + "unsupported_current_turn_meaning_boundary" + ] + }, + { + "step_id": "step_07_off_domain_living_chat_not_hijacked", "title": "Off-domain living chat remains human and is not hijacked by discovery carryover", "question": "а чем капибара отличается от утки?", "required_answer_patterns_any": [ diff --git a/llm_normalizer/backend/dist/services/assistantContinuityPolicy.js b/llm_normalizer/backend/dist/services/assistantContinuityPolicy.js index 38e9af0..5bf2f99 100644 --- a/llm_normalizer/backend/dist/services/assistantContinuityPolicy.js +++ b/llm_normalizer/backend/dist/services/assistantContinuityPolicy.js @@ -26,6 +26,7 @@ exports.buildInventoryRootFrameFromAddressDebug = buildInventoryRootFrameFromAdd exports.isGroundedAddressDebug = isGroundedAddressDebug; exports.resolveAssistantContinuitySnapshot = resolveAssistantContinuitySnapshot; exports.resolveAssistantOrganizationAuthority = resolveAssistantOrganizationAuthority; +exports.resolveOrganizationClarificationContinuation = resolveOrganizationClarificationContinuation; const assistantOrganizationMatcher_1 = require("./assistantOrganizationMatcher"); function fallbackToNonEmptyString(value) { if (value === null || value === undefined) { @@ -685,3 +686,36 @@ function resolveAssistantOrganizationAuthority(input) { organizationClarificationSelectionFromScope }; } +function resolveOrganizationClarificationContinuation(input) { + const toNonEmptyString = input.toNonEmptyString ?? fallbackToNonEmptyString; + const normalizeOrganizationScopeValue = input.normalizeOrganizationScopeValue ?? normalizeOrganizationScopeDefault; + const candidates = Array.isArray(input.organizationClarificationCandidates) + ? input.organizationClarificationCandidates + : []; + const resolveOrganizationSelectionFromMessage = input.resolveOrganizationSelectionFromMessage; + const messages = Array.isArray(input.rawMessages) ? input.rawMessages : []; + let explicitSelection = null; + if (typeof resolveOrganizationSelectionFromMessage === "function") { + for (const message of messages) { + const normalizedMessage = toNonEmptyString(message); + if (!normalizedMessage) { + continue; + } + explicitSelection = resolveOrganizationSelectionFromMessage(normalizedMessage, candidates); + if (explicitSelection) { + break; + } + } + } + const normalizedScopeSelection = normalizeOrganizationScopeValue(input.organizationClarificationSelectionFromScope); + const selection = explicitSelection ?? + (normalizedScopeSelection && + candidates.some((candidate) => normalizeOrganizationScopeValue(candidate) === normalizedScopeSelection) + ? normalizedScopeSelection + : null); + return { + explicitSelection, + selection, + hasContinuation: Boolean(input.lastOrganizationClarificationDebug && selection) + }; +} diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryAnswerAdapter.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryAnswerAdapter.js index 4b81fdb..3796ea3 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryAnswerAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryAnswerAdapter.js @@ -61,9 +61,13 @@ function modeFor(pilot) { } function isValueFlowPilot(pilot) { return (pilot.pilot_scope === "counterparty_value_flow_query_movements_v1" || - pilot.pilot_scope === "counterparty_supplier_payout_query_movements_v1"); + pilot.pilot_scope === "counterparty_supplier_payout_query_movements_v1" || + pilot.pilot_scope === "counterparty_bidirectional_value_flow_query_movements_v1"); } function headlineFor(mode, pilot) { + if (pilot.derived_bidirectional_value_flow && mode === "confirmed_with_bounded_inference") { + return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду."; + } if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") { if (pilot.derived_value_flow.value_flow_direction === "outgoing_supplier_payout") { return "По данным 1С найдены строки исходящих платежей/списаний; сумму можно называть только в рамках проверенного периода и найденных строк."; @@ -147,6 +151,40 @@ function derivedValueFlowConfirmedLine(pilot) { : ""; return `По найденным строкам ${movementLabel} в 1С${counterparty}${period} ${totalLabel} ${flow.total_amount_human_ru} Учтено строк с суммой: ${flow.rows_with_amount} из ${flow.rows_matched}.${dates}${limitCaveat} ${caveat}`; } +function sideDateRange(first, latest) { + if (first && latest) { + return ` первая дата ${first}, последняя ${latest}`; + } + return " даты движения не выделены"; +} +function derivedBidirectionalValueFlowConfirmedLine(pilot) { + const flow = pilot.derived_bidirectional_value_flow; + if (!flow) { + return null; + } + const counterparty = flow.counterparty ? ` по контрагенту ${flow.counterparty}` : ""; + const period = flow.period_scope ? ` за период ${flow.period_scope}` : " в проверенном окне"; + const incoming = flow.incoming_customer_revenue; + const outgoing = flow.outgoing_supplier_payout; + const netLabel = flow.net_direction === "net_incoming" + ? "нетто в нашу сторону" + : flow.net_direction === "net_outgoing" + ? "нетто исходящий" + : "нетто нулевое"; + const limitCaveat = flow.coverage_limited_by_probe_limit + ? " Лимит строк проверки достигнут хотя бы по одной стороне; полный запрошенный период может быть покрыт не полностью." + : ""; + return [ + `По найденным строкам 1С${counterparty}${period}: получили ${incoming.total_amount_human_ru} по входящим движениям, заплатили ${outgoing.total_amount_human_ru} по исходящим платежам/списаниям.`, + `Расчетное ${netLabel}: ${flow.net_amount_human_ru}`, + `Входящие строки с суммой: ${incoming.rows_with_amount} из ${incoming.rows_matched};${sideDateRange(incoming.first_movement_date, incoming.latest_movement_date)}.`, + `Исходящие строки с суммой: ${outgoing.rows_with_amount} из ${outgoing.rows_matched};${sideDateRange(outgoing.first_movement_date, outgoing.latest_movement_date)}.`, + `${limitCaveat} Это расчет по найденным строкам 1С, а не подтверждение полного сальдо вне проверенного окна.` + ] + .join(" ") + .replace(/\s+/g, " ") + .trim(); +} function buildAssistantMcpDiscoveryAnswerDraft(pilot) { const mode = modeFor(pilot); const reasonCodes = [...pilot.reason_codes, ...pilot.evidence.reason_codes]; @@ -161,7 +199,7 @@ function buildAssistantMcpDiscoveryAnswerDraft(pilot) { const inferenceLines = derivedInferenceLine ? [derivedInferenceLine] : pilot.evidence.inferred_facts; - const derivedValueLine = derivedValueFlowConfirmedLine(pilot); + const derivedValueLine = derivedBidirectionalValueFlowConfirmedLine(pilot) ?? derivedValueFlowConfirmedLine(pilot); const confirmedLines = derivedValueLine ? [...pilot.evidence.confirmed_facts, derivedValueLine] : pilot.evidence.confirmed_facts; diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPilotExecutor.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPilotExecutor.js index 3931436..4a0527d 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPilotExecutor.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPilotExecutor.js @@ -120,6 +120,16 @@ function valueFlowPilotProfile(planner) { const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const combined = `${action} ${unsupported}`; + if (combined.includes("net_value_flow") || + combined.includes("bidirectional") || + combined.includes("netting") || + combined.includes("net")) { + return { + scope: "counterparty_bidirectional_value_flow_query_movements_v1", + recipe_intent: null, + direction: "bidirectional_net_value_flow" + }; + } if (combined.includes("payout") || combined.includes("outflow") || combined.includes("supplier") || @@ -314,6 +324,74 @@ function deriveValueFlow(result, counterparty, periodScope, direction, probeLimi inference_basis: "sum_of_confirmed_1c_value_flow_rows" }; } +function deriveValueFlowSideSummary(result, probeLimit) { + if (!result || result.error || result.matched_rows <= 0) { + return { + rows_matched: 0, + rows_with_amount: 0, + total_amount: 0, + total_amount_human_ru: formatAmountHumanRu(0), + first_movement_date: null, + latest_movement_date: null, + coverage_limited_by_probe_limit: false + }; + } + let totalAmount = 0; + let rowsWithAmount = 0; + for (const row of result.rows) { + const amount = rowAmountValue(row); + if (amount !== null) { + totalAmount += amount; + rowsWithAmount += 1; + } + } + const dates = result.rows + .map((row) => rowDateValue(row)) + .filter((value) => Boolean(value)) + .sort(); + return { + rows_matched: result.matched_rows, + rows_with_amount: rowsWithAmount, + total_amount: totalAmount, + total_amount_human_ru: formatAmountHumanRu(totalAmount), + first_movement_date: dates[0] ?? null, + latest_movement_date: dates[dates.length - 1] ?? null, + coverage_limited_by_probe_limit: result.matched_rows >= probeLimit + }; +} +function deriveBidirectionalValueFlow(input) { + const incoming = deriveValueFlowSideSummary(input.incomingResult, input.probeLimit); + const outgoing = deriveValueFlowSideSummary(input.outgoingResult, input.probeLimit); + if (incoming.rows_with_amount <= 0 && outgoing.rows_with_amount <= 0) { + return null; + } + const netAmount = incoming.total_amount - outgoing.total_amount; + return { + counterparty: input.counterparty, + period_scope: input.periodScope, + incoming_customer_revenue: incoming, + outgoing_supplier_payout: outgoing, + net_amount: netAmount, + net_amount_human_ru: formatAmountHumanRu(Math.abs(netAmount)), + net_direction: netAmount > 0 ? "net_incoming" : netAmount < 0 ? "net_outgoing" : "balanced", + coverage_limited_by_probe_limit: incoming.coverage_limited_by_probe_limit || outgoing.coverage_limited_by_probe_limit, + inference_basis: "incoming_minus_outgoing_confirmed_1c_value_flow_rows" + }; +} +function summarizeBidirectionalValueFlowRows(input) { + const incoming = input.incomingResult; + const outgoing = input.outgoingResult; + if (!incoming && !outgoing) { + return null; + } + const incomingSummary = incoming?.error + ? "incoming value-flow query failed" + : `${incoming?.fetched_rows ?? 0} incoming value-flow rows fetched, ${incoming?.matched_rows ?? 0} matched`; + const outgoingSummary = outgoing?.error + ? "outgoing supplier-payout query failed" + : `${outgoing?.fetched_rows ?? 0} outgoing supplier-payout rows fetched, ${outgoing?.matched_rows ?? 0} matched`; + return `${incomingSummary}; ${outgoingSummary}`; +} function buildLifecycleConfirmedFacts(result, counterparty) { if (result.error || result.matched_rows <= 0) { return []; @@ -341,6 +419,21 @@ function buildValueFlowConfirmedFacts(result, counterparty, direction) { : "1C value-flow rows were found for the requested counterparty scope" ]; } +function buildBidirectionalValueFlowConfirmedFacts(derived) { + if (!derived) { + return []; + } + const hasIncoming = derived.incoming_customer_revenue.rows_matched > 0; + const hasOutgoing = derived.outgoing_supplier_payout.rows_matched > 0; + if (derived.counterparty) { + return [ + `1C bidirectional value-flow rows were checked for counterparty ${derived.counterparty}: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` + ]; + } + return [ + `1C bidirectional value-flow rows were checked for the requested counterparty scope: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` + ]; +} function buildLifecycleInferredFacts(result) { if (result.error || result.fetched_rows <= 0) { return []; @@ -356,6 +449,12 @@ function buildValueFlowInferredFacts(derived) { } return ["Counterparty value-flow total was calculated from confirmed 1C movement rows"]; } +function buildBidirectionalValueFlowInferredFacts(derived) { + if (!derived) { + return []; + } + return ["Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows"]; +} function buildLifecycleUnknownFacts() { return ["Legal registration date is not proven by this MCP discovery pilot"]; } @@ -375,6 +474,16 @@ function buildValueFlowUnknownFacts(periodScope, direction, derived) { : "Full all-time turnover is not proven without an explicit checked period"); return unknownFacts; } +function buildBidirectionalValueFlowUnknownFacts(periodScope, derived) { + const unknownFacts = []; + if (derived?.coverage_limited_by_probe_limit) { + unknownFacts.push("Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached"); + } + unknownFacts.push(periodScope + ? "Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot" + : "Full all-time bidirectional value-flow is not proven without an explicit checked period"); + return unknownFacts; +} function buildEmptyEvidence(planner, dryRun, probeResults, reason) { return (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, @@ -408,6 +517,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot was blocked before execution"], reason_codes: reasonCodes }; @@ -429,6 +539,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot needs more scope before execution"], reason_codes: reasonCodes }; @@ -456,6 +567,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot scope is not implemented yet"], reason_codes: reasonCodes }; @@ -466,7 +578,109 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { let queryResult = null; const filters = buildValueFlowFilters(planner); const valueFlowProfile = valueFlowPilotProfile(planner); - const selection = (0, addressRecipeCatalog_1.selectAddressRecipe)(valueFlowProfile.recipe_intent, filters); + if (valueFlowProfile.direction === "bidirectional_net_value_flow") { + let incomingResult = null; + let outgoingResult = null; + const incomingSelection = (0, addressRecipeCatalog_1.selectAddressRecipe)("customer_revenue_and_payments", filters); + const outgoingSelection = (0, addressRecipeCatalog_1.selectAddressRecipe)("supplier_payouts_profile", filters); + if (!incomingSelection.selected_recipe || !outgoingSelection.selected_recipe) { + pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipe_not_available"); + const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Bidirectional value-flow recipes are not available"); + return { + schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, + policy_owner: "assistantMcpDiscoveryPilotExecutor", + pilot_status: "unsupported", + pilot_scope: valueFlowProfile.scope, + dry_run: dryRun, + mcp_execution_performed: false, + executed_primitives: executedPrimitives, + skipped_primitives: skippedPrimitives, + probe_results: probeResults, + evidence, + source_rows_summary: null, + derived_activity_period: null, + derived_value_flow: null, + derived_bidirectional_value_flow: null, + query_limitations: ["Bidirectional value-flow recipes are not available"], + reason_codes: reasonCodes + }; + } + pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipes_selected"); + const incomingRecipePlan = (0, addressRecipeCatalog_1.buildAddressRecipePlan)(incomingSelection.selected_recipe, filters); + const outgoingRecipePlan = (0, addressRecipeCatalog_1.buildAddressRecipePlan)(outgoingSelection.selected_recipe, filters); + for (const step of dryRun.execution_steps) { + if (step.primitive_id !== "query_movements") { + skippedPrimitives.push(step.primitive_id); + probeResults.push(skippedProbeResult(step, "pilot_bidirectional_value_flow_uses_two_query_movements_and_derives_net")); + continue; + } + incomingResult = await deps.executeAddressMcpQuery({ + query: incomingRecipePlan.query, + limit: incomingRecipePlan.limit, + account_scope: incomingRecipePlan.account_scope + }); + outgoingResult = await deps.executeAddressMcpQuery({ + query: outgoingRecipePlan.query, + limit: outgoingRecipePlan.limit, + account_scope: outgoingRecipePlan.account_scope + }); + pushUnique(executedPrimitives, step.primitive_id); + probeResults.push(queryResultToProbeResult(step.primitive_id, incomingResult)); + probeResults.push(queryResultToProbeResult(step.primitive_id, outgoingResult)); + if (incomingResult.error) { + pushUnique(queryLimitations, incomingResult.error); + pushReason(reasonCodes, "pilot_bidirectional_incoming_query_movements_mcp_error"); + } + if (outgoingResult.error) { + pushUnique(queryLimitations, outgoingResult.error); + pushReason(reasonCodes, "pilot_bidirectional_outgoing_query_movements_mcp_error"); + } + if (!incomingResult.error || !outgoingResult.error) { + pushReason(reasonCodes, "pilot_bidirectional_query_movements_mcp_executed"); + } + } + const sourceRowsSummary = summarizeBidirectionalValueFlowRows({ incomingResult, outgoingResult }); + const derivedBidirectionalValueFlow = deriveBidirectionalValueFlow({ + incomingResult, + outgoingResult, + counterparty, + periodScope: dateScope, + probeLimit: planner.discovery_plan.execution_budget.max_rows_per_probe + }); + if (derivedBidirectionalValueFlow) { + pushReason(reasonCodes, "pilot_derived_bidirectional_value_flow_from_confirmed_rows"); + } + const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ + plan: planner.discovery_plan, + probeResults, + confirmedFacts: buildBidirectionalValueFlowConfirmedFacts(derivedBidirectionalValueFlow), + inferredFacts: buildBidirectionalValueFlowInferredFacts(derivedBidirectionalValueFlow), + unknownFacts: buildBidirectionalValueFlowUnknownFacts(dateScope, derivedBidirectionalValueFlow), + sourceRowsSummary, + queryLimitations, + recommendedNextProbe: "explain_evidence_basis" + }); + return { + schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, + policy_owner: "assistantMcpDiscoveryPilotExecutor", + pilot_status: "executed", + pilot_scope: valueFlowProfile.scope, + dry_run: dryRun, + mcp_execution_performed: executedPrimitives.length > 0, + executed_primitives: executedPrimitives, + skipped_primitives: skippedPrimitives, + probe_results: probeResults, + evidence, + source_rows_summary: sourceRowsSummary, + derived_activity_period: null, + derived_value_flow: null, + derived_bidirectional_value_flow: derivedBidirectionalValueFlow, + query_limitations: queryLimitations, + reason_codes: reasonCodes + }; + } + const recipeIntent = valueFlowProfile.recipe_intent; + const selection = recipeIntent ? (0, addressRecipeCatalog_1.selectAddressRecipe)(recipeIntent, filters) : { selected_recipe: null }; if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_value_flow_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Value-flow recipe is not available"); @@ -484,6 +698,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["Value-flow recipe is not available"], reason_codes: reasonCodes }; @@ -542,6 +757,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: sourceRowsSummary, derived_activity_period: null, derived_value_flow: derivedValueFlow, + derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; @@ -566,6 +782,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["Lifecycle recipe is not available"], reason_codes: reasonCodes }; @@ -621,6 +838,7 @@ async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { source_rows_summary: sourceRowsSummary, derived_activity_period: derivedActivityPeriod, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js index c1c42db..7356221 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js @@ -60,7 +60,7 @@ function recipeFor(input) { const combined = `${domain} ${action} ${unsupported}`.trim(); const axes = []; addScopeAxes(axes, meaning); - if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value"])) { + if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value", "net", "netting", "balance", "cashflow"])) { pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryResponseCandidate.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryResponseCandidate.js index 795fe51..1a0179e 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryResponseCandidate.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryResponseCandidate.js @@ -82,6 +82,18 @@ function localizeLine(value) { if (/^1C supplier-payout rows were found for the requested counterparty scope$/i.test(value)) { return "В 1С найдены строки исходящих платежей/списаний по запрошенному контрагентскому контуру."; } + const bidirectionalMatch = value.match(/^1C bidirectional value-flow rows were checked for counterparty\s+(.+): incoming=(found|not_found), outgoing=(found|not_found)$/i); + if (bidirectionalMatch) { + const incoming = bidirectionalMatch[2] === "found" ? "входящие строки найдены" : "входящие строки не найдены"; + const outgoing = bidirectionalMatch[3] === "found" ? "исходящие строки найдены" : "исходящие строки не найдены"; + return `В 1С проверены входящие и исходящие денежные строки по контрагенту ${bidirectionalMatch[1]}: ${incoming}, ${outgoing}.`; + } + const bidirectionalScopeMatch = value.match(/^1C bidirectional value-flow rows were checked for the requested counterparty scope: incoming=(found|not_found), outgoing=(found|not_found)$/i); + if (bidirectionalScopeMatch) { + const incoming = bidirectionalScopeMatch[1] === "found" ? "входящие строки найдены" : "входящие строки не найдены"; + const outgoing = bidirectionalScopeMatch[2] === "found" ? "исходящие строки найдены" : "исходящие строки не найдены"; + return `В 1С проверены входящие и исходящие денежные строки по запрошенному контрагентскому контуру: ${incoming}, ${outgoing}.`; + } if (/^Business activity duration may be inferred from first and latest confirmed 1C activity rows$/i.test(value)) { return "Длительность деловой активности можно оценивать только как вывод по первой и последней подтвержденной строке активности в 1С."; } @@ -91,12 +103,18 @@ function localizeLine(value) { if (/^Counterparty supplier-payout total was calculated from confirmed 1C outgoing payment rows$/i.test(value)) { return "Сумма исходящих платежей рассчитана только по подтвержденным строкам списаний в 1С."; } + if (/^Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows$/i.test(value)) { + return "Нетто денежного потока рассчитано только как входящие подтвержденные строки 1С минус исходящие подтвержденные строки 1С."; + } if (/^Legal registration date is not proven by this MCP discovery pilot$/i.test(value)) { return "Юридическая дата регистрации этим поиском не подтверждена."; } if (/^Complete requested-period coverage is not proven because the MCP discovery probe row limit was reached$/i.test(value)) { return "Полное покрытие запрошенного периода не подтверждено: проверка достигла лимита найденных строк."; } + if (/^Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached$/i.test(value)) { + return "Полное покрытие запрошенного периода по двустороннему денежному потоку не подтверждено: хотя бы одна сторона проверки достигла лимита найденных строк."; + } if (/^Full turnover outside the checked period is not proven by this MCP discovery pilot$/i.test(value)) { return "Полный оборот вне проверенного периода этим поиском не подтвержден."; } @@ -109,6 +127,12 @@ function localizeLine(value) { if (/^Full all-time supplier-payout amount is not proven without an explicit checked period$/i.test(value)) { return "Полный объем исходящих платежей за все время без явно проверенного периода не подтвержден."; } + if (/^Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot$/i.test(value)) { + return "Полный двусторонний денежный поток вне проверенного периода этим поиском не подтвержден."; + } + if (/^Full all-time bidirectional value-flow is not proven without an explicit checked period$/i.test(value)) { + return "Полный двусторонний денежный поток за все время без явно проверенного периода не подтвержден."; + } return value; } function section(title, lines) { diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js index f8a0c76..78dbfd0 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js @@ -101,12 +101,15 @@ function hasValueFlowSignal(text) { function hasPayoutSignal(text) { return /(?:\bмы\s+(?:за)?плат|(?:за)?платил|оплатил|перечисл|списан|расход|поставщик|исходящ|supplier|payout|outflow|paid\s+to|payment\s+to)/iu.test(text); } +function hasBidirectionalValueFlowSignal(text) { + return /(?:нетто|сальдо|баланс\s+(?:плат|денег|денеж)|взаиморасч[её]т|получил[иа]?.*(?:за)?платил|(?:за)?платил[иа]?.*получил|входящ.*исходящ|исходящ.*входящ|дебет.*кредит|кредит.*дебет|net\s+(?:flow|cash|payment)|cash\s+net|incoming\s+and\s+outgoing|received\s+and\s+paid|paid\s+and\s+received)/iu.test(text); +} function semanticNeedFor(input) { const combined = compactLower(`${input.domain ?? ""} ${input.action ?? ""} ${input.unsupported ?? ""}`); if (input.lifecycleSignal || /(?:lifecycle|activity|duration|age)/iu.test(combined)) { return "counterparty lifecycle evidence"; } - if (input.valueFlowSignal || /(?:turnover|revenue|payment|payout|value)/iu.test(combined)) { + if (input.valueFlowSignal || /(?:turnover|revenue|payment|payout|value|net|netting|balance|cashflow)/iu.test(combined)) { return "counterparty value-flow evidence"; } if (/(?:document|documents|list_documents)/iu.test(combined)) { @@ -136,8 +139,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const reasonCodes = []; const rawText = compactLower(`${input.userMessage ?? ""} ${input.effectiveMessage ?? ""}`); const lifecycleSignal = hasLifecycleSignal(rawText); - const valueFlowSignal = !lifecycleSignal && hasValueFlowSignal(rawText); - const payoutSignal = valueFlowSignal && hasPayoutSignal(rawText); + const bidirectionalValueFlowSignal = !lifecycleSignal && hasBidirectionalValueFlowSignal(rawText); + const valueFlowSignal = !lifecycleSignal && (hasValueFlowSignal(rawText) || bidirectionalValueFlowSignal); + const payoutSignal = valueFlowSignal && !bidirectionalValueFlowSignal && hasPayoutSignal(rawText); const rawDomain = toNonEmptyString(assistantTurnMeaning?.asked_domain_family); const rawAction = toNonEmptyString(assistantTurnMeaning?.asked_action_family); const unsupported = toNonEmptyString(assistantTurnMeaning?.unsupported_but_understood_family); @@ -157,11 +161,28 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const explicitOrganizationScope = valueFlowSignal && !predecomposeEntities.counterparty ? null : predecomposeEntities.organization; const turnMeaning = { asked_domain_family: lifecycleSignal ? "counterparty_lifecycle" : valueFlowSignal ? "counterparty_value" : rawDomain, - asked_action_family: lifecycleSignal ? "activity_duration" : valueFlowSignal ? (payoutSignal ? "payout" : "turnover") : rawAction, + asked_action_family: lifecycleSignal + ? "activity_duration" + : valueFlowSignal + ? bidirectionalValueFlowSignal + ? "net_value_flow" + : payoutSignal + ? "payout" + : "turnover" + : rawAction, explicit_entity_candidates: entityCandidates, explicit_organization_scope: explicitOrganizationScope, explicit_date_scope: collectDateScope(predecomposeContract), - unsupported_but_understood_family: unsupported ?? (lifecycleSignal ? "counterparty_lifecycle" : valueFlowSignal ? (payoutSignal ? "counterparty_payouts_or_outflow" : "counterparty_value_or_turnover") : null), + unsupported_but_understood_family: unsupported ?? + (lifecycleSignal + ? "counterparty_lifecycle" + : valueFlowSignal + ? bidirectionalValueFlowSignal + ? "counterparty_bidirectional_value_flow_or_netting" + : payoutSignal + ? "counterparty_payouts_or_outflow" + : "counterparty_value_or_turnover" + : null), stale_replay_forbidden: Boolean(assistantTurnMeaning?.stale_replay_forbidden || unsupported || lifecycleSignal || valueFlowSignal) }; const cleanTurnMeaning = {}; @@ -212,6 +233,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) { if (payoutSignal) { pushReason(reasonCodes, "mcp_discovery_payout_signal_detected"); } + if (bidirectionalValueFlowSignal) { + pushReason(reasonCodes, "mcp_discovery_bidirectional_value_flow_signal_detected"); + } if (unsupported) { pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn"); } diff --git a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js index 8505f3d..11fa352 100644 --- a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js +++ b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js @@ -328,17 +328,22 @@ function createAssistantRoutePolicy(deps) { continuitySnapshot.lastGroundedAddressDebug; const lastOrganizationClarificationDebug = findLastOrganizationClarificationAddressDebug(sessionItems); const organizationClarificationCandidates = organizationAuthority.organizationClarificationCandidates; - const organizationClarificationSelectionFromScope = organizationAuthority.organizationClarificationSelectionFromScope; - const explicitOrganizationClarificationSelection = resolveOrganizationSelectionFromMessage(rawUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(repairedRawUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(effectiveAddressUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(repairedEffectiveAddressUserMessage, organizationClarificationCandidates) ?? - null; - const organizationClarificationSelection = explicitOrganizationClarificationSelection ?? - (organizationClarificationSelectionFromScope && - organizationClarificationCandidates.some((candidate) => normalizeOrganizationScopeValue(candidate) === organizationClarificationSelectionFromScope) - ? organizationClarificationSelectionFromScope - : null); + const organizationClarificationContinuation = (0, assistantContinuityPolicy_1.resolveOrganizationClarificationContinuation)({ + rawMessages: [ + rawUserMessage, + repairedRawUserMessage, + effectiveAddressUserMessage, + repairedEffectiveAddressUserMessage + ], + organizationClarificationCandidates, + organizationClarificationSelectionFromScope: organizationAuthority.organizationClarificationSelectionFromScope, + lastOrganizationClarificationDebug, + resolveOrganizationSelectionFromMessage, + toNonEmptyString, + normalizeOrganizationScopeValue + }); + const explicitOrganizationClarificationSelection = organizationClarificationContinuation.explicitSelection; + const organizationClarificationSelection = organizationClarificationContinuation.selection; const metaSignals = resolveMetaSignalSet({ rawUserMessage, repairedRawUserMessage, diff --git a/llm_normalizer/backend/dist/services/assistantTransitionPolicy.js b/llm_normalizer/backend/dist/services/assistantTransitionPolicy.js index 62795da..0d08bb1 100644 --- a/llm_normalizer/backend/dist/services/assistantTransitionPolicy.js +++ b/llm_normalizer/backend/dist/services/assistantTransitionPolicy.js @@ -316,13 +316,18 @@ function createAssistantTransitionPolicy(deps) { const organizationClarificationCandidates = Array.isArray(organizationAuthority.organizationClarificationCandidates) ? organizationAuthority.organizationClarificationCandidates : []; - const explicitOrganizationClarificationSelection = deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ?? - (deps.toNonEmptyString(alternateMessage) - ? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates) - : null); - const organizationClarificationSelection = explicitOrganizationClarificationSelection ?? - deps.normalizeOrganizationScopeValue(organizationAuthority.organizationClarificationSelectionFromScope); - const hasOrganizationClarificationContinuation = Boolean(lastOrganizationClarificationDebug && organizationClarificationSelection); + const organizationClarificationContinuation = (0, assistantContinuityPolicy_1.resolveOrganizationClarificationContinuation)({ + rawMessages: [userMessage, alternateMessage], + organizationClarificationCandidates, + organizationClarificationSelectionFromScope: organizationAuthority.organizationClarificationSelectionFromScope, + lastOrganizationClarificationDebug, + resolveOrganizationSelectionFromMessage: deps.resolveOrganizationSelectionFromMessage, + toNonEmptyString: deps.toNonEmptyString, + normalizeOrganizationScopeValue: deps.normalizeOrganizationScopeValue + }); + const explicitOrganizationClarificationSelection = organizationClarificationContinuation.explicitSelection; + const organizationClarificationSelection = organizationClarificationContinuation.selection; + const hasOrganizationClarificationContinuation = organizationClarificationContinuation.hasContinuation; const carryoverSourceDebug = previousAddressDebug ?? (hasOrganizationClarificationContinuation ? lastOrganizationClarificationDebug : null); const followupOffer = carryoverSourceDebug ? deps.buildAddressFollowupOffer(carryoverSourceDebug) : null; diff --git a/llm_normalizer/backend/src/services/assistantContinuityPolicy.ts b/llm_normalizer/backend/src/services/assistantContinuityPolicy.ts index a765055..e73d047 100644 --- a/llm_normalizer/backend/src/services/assistantContinuityPolicy.ts +++ b/llm_normalizer/backend/src/services/assistantContinuityPolicy.ts @@ -86,6 +86,12 @@ export interface AssistantOrganizationAuthority { organizationClarificationSelectionFromScope: string | null; } +export interface AssistantOrganizationClarificationContinuation { + explicitSelection: string | null; + selection: string | null; + hasContinuation: boolean; +} + function fallbackToNonEmptyString(value: unknown): string | null { if (value === null || value === undefined) { return null; @@ -1077,3 +1083,50 @@ export function resolveAssistantOrganizationAuthority( organizationClarificationSelectionFromScope }; } + +export function resolveOrganizationClarificationContinuation(input: { + rawMessages: unknown[]; + organizationClarificationCandidates?: unknown[]; + organizationClarificationSelectionFromScope?: unknown; + lastOrganizationClarificationDebug?: Record | null; + resolveOrganizationSelectionFromMessage?: (message: string, candidates: unknown[]) => string | null; + toNonEmptyString?: (value: unknown) => string | null; + normalizeOrganizationScopeValue?: (value: unknown) => string | null; +}): AssistantOrganizationClarificationContinuation { + const toNonEmptyString = input.toNonEmptyString ?? fallbackToNonEmptyString; + const normalizeOrganizationScopeValue = + input.normalizeOrganizationScopeValue ?? normalizeOrganizationScopeDefault; + const candidates = Array.isArray(input.organizationClarificationCandidates) + ? input.organizationClarificationCandidates + : []; + const resolveOrganizationSelectionFromMessage = input.resolveOrganizationSelectionFromMessage; + const messages = Array.isArray(input.rawMessages) ? input.rawMessages : []; + let explicitSelection: string | null = null; + + if (typeof resolveOrganizationSelectionFromMessage === "function") { + for (const message of messages) { + const normalizedMessage = toNonEmptyString(message); + if (!normalizedMessage) { + continue; + } + explicitSelection = resolveOrganizationSelectionFromMessage(normalizedMessage, candidates); + if (explicitSelection) { + break; + } + } + } + + const normalizedScopeSelection = normalizeOrganizationScopeValue(input.organizationClarificationSelectionFromScope); + const selection = + explicitSelection ?? + (normalizedScopeSelection && + candidates.some((candidate) => normalizeOrganizationScopeValue(candidate) === normalizedScopeSelection) + ? normalizedScopeSelection + : null); + + return { + explicitSelection, + selection, + hasContinuation: Boolean(input.lastOrganizationClarificationDebug && selection) + }; +} diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryAnswerAdapter.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryAnswerAdapter.ts index 8fd76cf..6f3edd8 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryAnswerAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryAnswerAdapter.ts @@ -92,11 +92,15 @@ function modeFor(pilot: AssistantMcpDiscoveryPilotExecutionContract): AssistantM function isValueFlowPilot(pilot: AssistantMcpDiscoveryPilotExecutionContract): boolean { return ( pilot.pilot_scope === "counterparty_value_flow_query_movements_v1" || - pilot.pilot_scope === "counterparty_supplier_payout_query_movements_v1" + pilot.pilot_scope === "counterparty_supplier_payout_query_movements_v1" || + pilot.pilot_scope === "counterparty_bidirectional_value_flow_query_movements_v1" ); } function headlineFor(mode: AssistantMcpDiscoveryAnswerMode, pilot: AssistantMcpDiscoveryPilotExecutionContract): string { + if (pilot.derived_bidirectional_value_flow && mode === "confirmed_with_bounded_inference") { + return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду."; + } if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") { if (pilot.derived_value_flow.value_flow_direction === "outgoing_supplier_payout") { return "По данным 1С найдены строки исходящих платежей/списаний; сумму можно называть только в рамках проверенного периода и найденных строк."; @@ -189,6 +193,43 @@ function derivedValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotExecutio return `По найденным строкам ${movementLabel} в 1С${counterparty}${period} ${totalLabel} ${flow.total_amount_human_ru} Учтено строк с суммой: ${flow.rows_with_amount} из ${flow.rows_matched}.${dates}${limitCaveat} ${caveat}`; } +function sideDateRange(first: string | null, latest: string | null): string { + if (first && latest) { + return ` первая дата ${first}, последняя ${latest}`; + } + return " даты движения не выделены"; +} + +function derivedBidirectionalValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotExecutionContract): string | null { + const flow = pilot.derived_bidirectional_value_flow; + if (!flow) { + return null; + } + const counterparty = flow.counterparty ? ` по контрагенту ${flow.counterparty}` : ""; + const period = flow.period_scope ? ` за период ${flow.period_scope}` : " в проверенном окне"; + const incoming = flow.incoming_customer_revenue; + const outgoing = flow.outgoing_supplier_payout; + const netLabel = + flow.net_direction === "net_incoming" + ? "нетто в нашу сторону" + : flow.net_direction === "net_outgoing" + ? "нетто исходящий" + : "нетто нулевое"; + const limitCaveat = flow.coverage_limited_by_probe_limit + ? " Лимит строк проверки достигнут хотя бы по одной стороне; полный запрошенный период может быть покрыт не полностью." + : ""; + return [ + `По найденным строкам 1С${counterparty}${period}: получили ${incoming.total_amount_human_ru} по входящим движениям, заплатили ${outgoing.total_amount_human_ru} по исходящим платежам/списаниям.`, + `Расчетное ${netLabel}: ${flow.net_amount_human_ru}`, + `Входящие строки с суммой: ${incoming.rows_with_amount} из ${incoming.rows_matched};${sideDateRange(incoming.first_movement_date, incoming.latest_movement_date)}.`, + `Исходящие строки с суммой: ${outgoing.rows_with_amount} из ${outgoing.rows_matched};${sideDateRange(outgoing.first_movement_date, outgoing.latest_movement_date)}.`, + `${limitCaveat} Это расчет по найденным строкам 1С, а не подтверждение полного сальдо вне проверенного окна.` + ] + .join(" ") + .replace(/\s+/g, " ") + .trim(); +} + export function buildAssistantMcpDiscoveryAnswerDraft( pilot: AssistantMcpDiscoveryPilotExecutionContract ): AssistantMcpDiscoveryAnswerDraftContract { @@ -205,7 +246,7 @@ export function buildAssistantMcpDiscoveryAnswerDraft( const inferenceLines = derivedInferenceLine ? [derivedInferenceLine] : pilot.evidence.inferred_facts; - const derivedValueLine = derivedValueFlowConfirmedLine(pilot); + const derivedValueLine = derivedBidirectionalValueFlowConfirmedLine(pilot) ?? derivedValueFlowConfirmedLine(pilot); const confirmedLines = derivedValueLine ? [...pilot.evidence.confirmed_facts, derivedValueLine] : pilot.evidence.confirmed_facts; diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPilotExecutor.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPilotExecutor.ts index 1f2d374..588704d 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPilotExecutor.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPilotExecutor.ts @@ -54,10 +54,33 @@ export interface AssistantMcpDiscoveryDerivedValueFlow { inference_basis: "sum_of_confirmed_1c_value_flow_rows"; } +export interface AssistantMcpDiscoveryValueFlowSideSummary { + rows_matched: number; + rows_with_amount: number; + total_amount: number; + total_amount_human_ru: string; + first_movement_date: string | null; + latest_movement_date: string | null; + coverage_limited_by_probe_limit: boolean; +} + +export interface AssistantMcpDiscoveryDerivedBidirectionalValueFlow { + counterparty: string | null; + period_scope: string | null; + incoming_customer_revenue: AssistantMcpDiscoveryValueFlowSideSummary; + outgoing_supplier_payout: AssistantMcpDiscoveryValueFlowSideSummary; + net_amount: number; + net_amount_human_ru: string; + net_direction: "net_incoming" | "net_outgoing" | "balanced"; + coverage_limited_by_probe_limit: boolean; + inference_basis: "incoming_minus_outgoing_confirmed_1c_value_flow_rows"; +} + export type AssistantMcpDiscoveryPilotScope = | "counterparty_lifecycle_query_documents_v1" | "counterparty_value_flow_query_movements_v1" - | "counterparty_supplier_payout_query_movements_v1"; + | "counterparty_supplier_payout_query_movements_v1" + | "counterparty_bidirectional_value_flow_query_movements_v1"; export interface AssistantMcpDiscoveryPilotExecutionContract { schema_version: typeof ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION; @@ -73,6 +96,7 @@ export interface AssistantMcpDiscoveryPilotExecutionContract { source_rows_summary: string | null; derived_activity_period: AssistantMcpDiscoveryDerivedActivityPeriod | null; derived_value_flow: AssistantMcpDiscoveryDerivedValueFlow | null; + derived_bidirectional_value_flow: AssistantMcpDiscoveryDerivedBidirectionalValueFlow | null; query_limitations: string[]; reason_codes: string[]; } @@ -205,10 +229,12 @@ function isValueFlowPilotEligible(planner: AssistantMcpDiscoveryPlannerContract) interface ValueFlowPilotProfile { scope: Extract< AssistantMcpDiscoveryPilotScope, - "counterparty_value_flow_query_movements_v1" | "counterparty_supplier_payout_query_movements_v1" + | "counterparty_value_flow_query_movements_v1" + | "counterparty_supplier_payout_query_movements_v1" + | "counterparty_bidirectional_value_flow_query_movements_v1" >; - recipe_intent: Extract; - direction: AssistantMcpDiscoveryDerivedValueFlow["value_flow_direction"]; + recipe_intent: Extract | null; + direction: AssistantMcpDiscoveryDerivedValueFlow["value_flow_direction"] | "bidirectional_net_value_flow"; } function valueFlowPilotProfile(planner: AssistantMcpDiscoveryPlannerContract): ValueFlowPilotProfile { @@ -216,6 +242,18 @@ function valueFlowPilotProfile(planner: AssistantMcpDiscoveryPlannerContract): V const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const combined = `${action} ${unsupported}`; + if ( + combined.includes("net_value_flow") || + combined.includes("bidirectional") || + combined.includes("netting") || + combined.includes("net") + ) { + return { + scope: "counterparty_bidirectional_value_flow_query_movements_v1", + recipe_intent: null, + direction: "bidirectional_net_value_flow" + }; + } if ( combined.includes("payout") || combined.includes("outflow") || @@ -435,6 +473,91 @@ function deriveValueFlow( }; } +function deriveValueFlowSideSummary( + result: AddressMcpQueryExecutorResult | null, + probeLimit: number +): AssistantMcpDiscoveryValueFlowSideSummary { + if (!result || result.error || result.matched_rows <= 0) { + return { + rows_matched: 0, + rows_with_amount: 0, + total_amount: 0, + total_amount_human_ru: formatAmountHumanRu(0), + first_movement_date: null, + latest_movement_date: null, + coverage_limited_by_probe_limit: false + }; + } + + let totalAmount = 0; + let rowsWithAmount = 0; + for (const row of result.rows) { + const amount = rowAmountValue(row); + if (amount !== null) { + totalAmount += amount; + rowsWithAmount += 1; + } + } + const dates = result.rows + .map((row) => rowDateValue(row)) + .filter((value): value is string => Boolean(value)) + .sort(); + return { + rows_matched: result.matched_rows, + rows_with_amount: rowsWithAmount, + total_amount: totalAmount, + total_amount_human_ru: formatAmountHumanRu(totalAmount), + first_movement_date: dates[0] ?? null, + latest_movement_date: dates[dates.length - 1] ?? null, + coverage_limited_by_probe_limit: result.matched_rows >= probeLimit + }; +} + +function deriveBidirectionalValueFlow(input: { + incomingResult: AddressMcpQueryExecutorResult | null; + outgoingResult: AddressMcpQueryExecutorResult | null; + counterparty: string | null; + periodScope: string | null; + probeLimit: number; +}): AssistantMcpDiscoveryDerivedBidirectionalValueFlow | null { + const incoming = deriveValueFlowSideSummary(input.incomingResult, input.probeLimit); + const outgoing = deriveValueFlowSideSummary(input.outgoingResult, input.probeLimit); + if (incoming.rows_with_amount <= 0 && outgoing.rows_with_amount <= 0) { + return null; + } + const netAmount = incoming.total_amount - outgoing.total_amount; + return { + counterparty: input.counterparty, + period_scope: input.periodScope, + incoming_customer_revenue: incoming, + outgoing_supplier_payout: outgoing, + net_amount: netAmount, + net_amount_human_ru: formatAmountHumanRu(Math.abs(netAmount)), + net_direction: netAmount > 0 ? "net_incoming" : netAmount < 0 ? "net_outgoing" : "balanced", + coverage_limited_by_probe_limit: + incoming.coverage_limited_by_probe_limit || outgoing.coverage_limited_by_probe_limit, + inference_basis: "incoming_minus_outgoing_confirmed_1c_value_flow_rows" + }; +} + +function summarizeBidirectionalValueFlowRows(input: { + incomingResult: AddressMcpQueryExecutorResult | null; + outgoingResult: AddressMcpQueryExecutorResult | null; +}): string | null { + const incoming = input.incomingResult; + const outgoing = input.outgoingResult; + if (!incoming && !outgoing) { + return null; + } + const incomingSummary = incoming?.error + ? "incoming value-flow query failed" + : `${incoming?.fetched_rows ?? 0} incoming value-flow rows fetched, ${incoming?.matched_rows ?? 0} matched`; + const outgoingSummary = outgoing?.error + ? "outgoing supplier-payout query failed" + : `${outgoing?.fetched_rows ?? 0} outgoing supplier-payout rows fetched, ${outgoing?.matched_rows ?? 0} matched`; + return `${incomingSummary}; ${outgoingSummary}`; +} + function buildLifecycleConfirmedFacts(result: AddressMcpQueryExecutorResult, counterparty: string | null): string[] { if (result.error || result.matched_rows <= 0) { return []; @@ -464,7 +587,25 @@ function buildValueFlowConfirmedFacts( return [ counterparty ? `1C value-flow rows were found for counterparty ${counterparty}` - : "1C value-flow rows were found for the requested counterparty scope" + : "1C value-flow rows were found for the requested counterparty scope" + ]; +} + +function buildBidirectionalValueFlowConfirmedFacts( + derived: AssistantMcpDiscoveryDerivedBidirectionalValueFlow | null +): string[] { + if (!derived) { + return []; + } + const hasIncoming = derived.incoming_customer_revenue.rows_matched > 0; + const hasOutgoing = derived.outgoing_supplier_payout.rows_matched > 0; + if (derived.counterparty) { + return [ + `1C bidirectional value-flow rows were checked for counterparty ${derived.counterparty}: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` + ]; + } + return [ + `1C bidirectional value-flow rows were checked for the requested counterparty scope: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` ]; } @@ -485,6 +626,15 @@ function buildValueFlowInferredFacts(derived: AssistantMcpDiscoveryDerivedValueF return ["Counterparty value-flow total was calculated from confirmed 1C movement rows"]; } +function buildBidirectionalValueFlowInferredFacts( + derived: AssistantMcpDiscoveryDerivedBidirectionalValueFlow | null +): string[] { + if (!derived) { + return []; + } + return ["Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows"]; +} + function buildLifecycleUnknownFacts(): string[] { return ["Legal registration date is not proven by this MCP discovery pilot"]; } @@ -514,6 +664,24 @@ function buildValueFlowUnknownFacts( return unknownFacts; } +function buildBidirectionalValueFlowUnknownFacts( + periodScope: string | null, + derived: AssistantMcpDiscoveryDerivedBidirectionalValueFlow | null +): string[] { + const unknownFacts: string[] = []; + if (derived?.coverage_limited_by_probe_limit) { + unknownFacts.push( + "Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached" + ); + } + unknownFacts.push( + periodScope + ? "Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot" + : "Full all-time bidirectional value-flow is not proven without an explicit checked period" + ); + return unknownFacts; +} + function buildEmptyEvidence( planner: AssistantMcpDiscoveryPlannerContract, dryRun: AssistantMcpDiscoveryRuntimeDryRunContract, @@ -557,6 +725,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot was blocked before execution"], reason_codes: reasonCodes }; @@ -579,6 +748,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot needs more scope before execution"], reason_codes: reasonCodes }; @@ -608,6 +778,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot scope is not implemented yet"], reason_codes: reasonCodes }; @@ -620,7 +791,117 @@ export async function executeAssistantMcpDiscoveryPilot( let queryResult: AddressMcpQueryExecutorResult | null = null; const filters = buildValueFlowFilters(planner); const valueFlowProfile = valueFlowPilotProfile(planner); - const selection = selectAddressRecipe(valueFlowProfile.recipe_intent, filters); + if (valueFlowProfile.direction === "bidirectional_net_value_flow") { + let incomingResult: AddressMcpQueryExecutorResult | null = null; + let outgoingResult: AddressMcpQueryExecutorResult | null = null; + const incomingSelection = selectAddressRecipe("customer_revenue_and_payments", filters); + const outgoingSelection = selectAddressRecipe("supplier_payouts_profile", filters); + if (!incomingSelection.selected_recipe || !outgoingSelection.selected_recipe) { + pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipe_not_available"); + const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Bidirectional value-flow recipes are not available"); + return { + schema_version: ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, + policy_owner: "assistantMcpDiscoveryPilotExecutor", + pilot_status: "unsupported", + pilot_scope: valueFlowProfile.scope, + dry_run: dryRun, + mcp_execution_performed: false, + executed_primitives: executedPrimitives, + skipped_primitives: skippedPrimitives, + probe_results: probeResults, + evidence, + source_rows_summary: null, + derived_activity_period: null, + derived_value_flow: null, + derived_bidirectional_value_flow: null, + query_limitations: ["Bidirectional value-flow recipes are not available"], + reason_codes: reasonCodes + }; + } + + pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipes_selected"); + const incomingRecipePlan = buildAddressRecipePlan(incomingSelection.selected_recipe, filters); + const outgoingRecipePlan = buildAddressRecipePlan(outgoingSelection.selected_recipe, filters); + + for (const step of dryRun.execution_steps) { + if (step.primitive_id !== "query_movements") { + skippedPrimitives.push(step.primitive_id); + probeResults.push( + skippedProbeResult(step, "pilot_bidirectional_value_flow_uses_two_query_movements_and_derives_net") + ); + continue; + } + + incomingResult = await deps.executeAddressMcpQuery({ + query: incomingRecipePlan.query, + limit: incomingRecipePlan.limit, + account_scope: incomingRecipePlan.account_scope + }); + outgoingResult = await deps.executeAddressMcpQuery({ + query: outgoingRecipePlan.query, + limit: outgoingRecipePlan.limit, + account_scope: outgoingRecipePlan.account_scope + }); + pushUnique(executedPrimitives, step.primitive_id); + probeResults.push(queryResultToProbeResult(step.primitive_id, incomingResult)); + probeResults.push(queryResultToProbeResult(step.primitive_id, outgoingResult)); + if (incomingResult.error) { + pushUnique(queryLimitations, incomingResult.error); + pushReason(reasonCodes, "pilot_bidirectional_incoming_query_movements_mcp_error"); + } + if (outgoingResult.error) { + pushUnique(queryLimitations, outgoingResult.error); + pushReason(reasonCodes, "pilot_bidirectional_outgoing_query_movements_mcp_error"); + } + if (!incomingResult.error || !outgoingResult.error) { + pushReason(reasonCodes, "pilot_bidirectional_query_movements_mcp_executed"); + } + } + + const sourceRowsSummary = summarizeBidirectionalValueFlowRows({ incomingResult, outgoingResult }); + const derivedBidirectionalValueFlow = deriveBidirectionalValueFlow({ + incomingResult, + outgoingResult, + counterparty, + periodScope: dateScope, + probeLimit: planner.discovery_plan.execution_budget.max_rows_per_probe + }); + if (derivedBidirectionalValueFlow) { + pushReason(reasonCodes, "pilot_derived_bidirectional_value_flow_from_confirmed_rows"); + } + const evidence = resolveAssistantMcpDiscoveryEvidence({ + plan: planner.discovery_plan, + probeResults, + confirmedFacts: buildBidirectionalValueFlowConfirmedFacts(derivedBidirectionalValueFlow), + inferredFacts: buildBidirectionalValueFlowInferredFacts(derivedBidirectionalValueFlow), + unknownFacts: buildBidirectionalValueFlowUnknownFacts(dateScope, derivedBidirectionalValueFlow), + sourceRowsSummary, + queryLimitations, + recommendedNextProbe: "explain_evidence_basis" + }); + + return { + schema_version: ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, + policy_owner: "assistantMcpDiscoveryPilotExecutor", + pilot_status: "executed", + pilot_scope: valueFlowProfile.scope, + dry_run: dryRun, + mcp_execution_performed: executedPrimitives.length > 0, + executed_primitives: executedPrimitives, + skipped_primitives: skippedPrimitives, + probe_results: probeResults, + evidence, + source_rows_summary: sourceRowsSummary, + derived_activity_period: null, + derived_value_flow: null, + derived_bidirectional_value_flow: derivedBidirectionalValueFlow, + query_limitations: queryLimitations, + reason_codes: reasonCodes + }; + } + + const recipeIntent = valueFlowProfile.recipe_intent; + const selection = recipeIntent ? selectAddressRecipe(recipeIntent, filters) : { selected_recipe: null }; if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_value_flow_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Value-flow recipe is not available"); @@ -638,6 +919,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["Value-flow recipe is not available"], reason_codes: reasonCodes }; @@ -707,6 +989,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: sourceRowsSummary, derived_activity_period: null, derived_value_flow: derivedValueFlow, + derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; @@ -732,6 +1015,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: null, derived_activity_period: null, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: ["Lifecycle recipe is not available"], reason_codes: reasonCodes }; @@ -789,6 +1073,7 @@ export async function executeAssistantMcpDiscoveryPilot( source_rows_summary: sourceRowsSummary, derived_activity_period: derivedActivityPeriod, derived_value_flow: null, + derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts index 8f65d4a..c5aa6e2 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts @@ -101,7 +101,7 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe { const axes: string[] = []; addScopeAxes(axes, meaning); - if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value"])) { + if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value", "net", "netting", "balance", "cashflow"])) { pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts index ca1f185..30357a7 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts @@ -112,6 +112,22 @@ function localizeLine(value: string): string { if (/^1C supplier-payout rows were found for the requested counterparty scope$/i.test(value)) { return "В 1С найдены строки исходящих платежей/списаний по запрошенному контрагентскому контуру."; } + const bidirectionalMatch = value.match( + /^1C bidirectional value-flow rows were checked for counterparty\s+(.+): incoming=(found|not_found), outgoing=(found|not_found)$/i + ); + if (bidirectionalMatch) { + const incoming = bidirectionalMatch[2] === "found" ? "входящие строки найдены" : "входящие строки не найдены"; + const outgoing = bidirectionalMatch[3] === "found" ? "исходящие строки найдены" : "исходящие строки не найдены"; + return `В 1С проверены входящие и исходящие денежные строки по контрагенту ${bidirectionalMatch[1]}: ${incoming}, ${outgoing}.`; + } + const bidirectionalScopeMatch = value.match( + /^1C bidirectional value-flow rows were checked for the requested counterparty scope: incoming=(found|not_found), outgoing=(found|not_found)$/i + ); + if (bidirectionalScopeMatch) { + const incoming = bidirectionalScopeMatch[1] === "found" ? "входящие строки найдены" : "входящие строки не найдены"; + const outgoing = bidirectionalScopeMatch[2] === "found" ? "исходящие строки найдены" : "исходящие строки не найдены"; + return `В 1С проверены входящие и исходящие денежные строки по запрошенному контрагентскому контуру: ${incoming}, ${outgoing}.`; + } if (/^Business activity duration may be inferred from first and latest confirmed 1C activity rows$/i.test(value)) { return "Длительность деловой активности можно оценивать только как вывод по первой и последней подтвержденной строке активности в 1С."; } @@ -121,12 +137,18 @@ function localizeLine(value: string): string { if (/^Counterparty supplier-payout total was calculated from confirmed 1C outgoing payment rows$/i.test(value)) { return "Сумма исходящих платежей рассчитана только по подтвержденным строкам списаний в 1С."; } + if (/^Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows$/i.test(value)) { + return "Нетто денежного потока рассчитано только как входящие подтвержденные строки 1С минус исходящие подтвержденные строки 1С."; + } if (/^Legal registration date is not proven by this MCP discovery pilot$/i.test(value)) { return "Юридическая дата регистрации этим поиском не подтверждена."; } if (/^Complete requested-period coverage is not proven because the MCP discovery probe row limit was reached$/i.test(value)) { return "Полное покрытие запрошенного периода не подтверждено: проверка достигла лимита найденных строк."; } + if (/^Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached$/i.test(value)) { + return "Полное покрытие запрошенного периода по двустороннему денежному потоку не подтверждено: хотя бы одна сторона проверки достигла лимита найденных строк."; + } if (/^Full turnover outside the checked period is not proven by this MCP discovery pilot$/i.test(value)) { return "Полный оборот вне проверенного периода этим поиском не подтвержден."; } @@ -139,6 +161,12 @@ function localizeLine(value: string): string { if (/^Full all-time supplier-payout amount is not proven without an explicit checked period$/i.test(value)) { return "Полный объем исходящих платежей за все время без явно проверенного периода не подтвержден."; } + if (/^Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot$/i.test(value)) { + return "Полный двусторонний денежный поток вне проверенного периода этим поиском не подтвержден."; + } + if (/^Full all-time bidirectional value-flow is not proven without an explicit checked period$/i.test(value)) { + return "Полный двусторонний денежный поток за все время без явно проверенного периода не подтвержден."; + } return value; } diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts index ac50a0e..23793c1 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts @@ -150,6 +150,12 @@ function hasPayoutSignal(text: string): boolean { ); } +function hasBidirectionalValueFlowSignal(text: string): boolean { + return /(?:нетто|сальдо|баланс\s+(?:плат|денег|денеж)|взаиморасч[её]т|получил[иа]?.*(?:за)?платил|(?:за)?платил[иа]?.*получил|входящ.*исходящ|исходящ.*входящ|дебет.*кредит|кредит.*дебет|net\s+(?:flow|cash|payment)|cash\s+net|incoming\s+and\s+outgoing|received\s+and\s+paid|paid\s+and\s+received)/iu.test( + text + ); +} + function semanticNeedFor(input: { domain: string | null; action: string | null; @@ -161,7 +167,7 @@ function semanticNeedFor(input: { if (input.lifecycleSignal || /(?:lifecycle|activity|duration|age)/iu.test(combined)) { return "counterparty lifecycle evidence"; } - if (input.valueFlowSignal || /(?:turnover|revenue|payment|payout|value)/iu.test(combined)) { + if (input.valueFlowSignal || /(?:turnover|revenue|payment|payout|value|net|netting|balance|cashflow)/iu.test(combined)) { return "counterparty value-flow evidence"; } if (/(?:document|documents|list_documents)/iu.test(combined)) { @@ -201,8 +207,9 @@ export function buildAssistantMcpDiscoveryTurnInput( const reasonCodes: string[] = []; const rawText = compactLower(`${input.userMessage ?? ""} ${input.effectiveMessage ?? ""}`); const lifecycleSignal = hasLifecycleSignal(rawText); - const valueFlowSignal = !lifecycleSignal && hasValueFlowSignal(rawText); - const payoutSignal = valueFlowSignal && hasPayoutSignal(rawText); + const bidirectionalValueFlowSignal = !lifecycleSignal && hasBidirectionalValueFlowSignal(rawText); + const valueFlowSignal = !lifecycleSignal && (hasValueFlowSignal(rawText) || bidirectionalValueFlowSignal); + const payoutSignal = valueFlowSignal && !bidirectionalValueFlowSignal && hasPayoutSignal(rawText); const rawDomain = toNonEmptyString(assistantTurnMeaning?.asked_domain_family); const rawAction = toNonEmptyString(assistantTurnMeaning?.asked_action_family); @@ -225,12 +232,29 @@ export function buildAssistantMcpDiscoveryTurnInput( const turnMeaning: AssistantMcpDiscoveryTurnMeaningRef = { asked_domain_family: lifecycleSignal ? "counterparty_lifecycle" : valueFlowSignal ? "counterparty_value" : rawDomain, - asked_action_family: lifecycleSignal ? "activity_duration" : valueFlowSignal ? (payoutSignal ? "payout" : "turnover") : rawAction, + asked_action_family: lifecycleSignal + ? "activity_duration" + : valueFlowSignal + ? bidirectionalValueFlowSignal + ? "net_value_flow" + : payoutSignal + ? "payout" + : "turnover" + : rawAction, explicit_entity_candidates: entityCandidates, explicit_organization_scope: explicitOrganizationScope, explicit_date_scope: collectDateScope(predecomposeContract), unsupported_but_understood_family: - unsupported ?? (lifecycleSignal ? "counterparty_lifecycle" : valueFlowSignal ? (payoutSignal ? "counterparty_payouts_or_outflow" : "counterparty_value_or_turnover") : null), + unsupported ?? + (lifecycleSignal + ? "counterparty_lifecycle" + : valueFlowSignal + ? bidirectionalValueFlowSignal + ? "counterparty_bidirectional_value_flow_or_netting" + : payoutSignal + ? "counterparty_payouts_or_outflow" + : "counterparty_value_or_turnover" + : null), stale_replay_forbidden: Boolean(assistantTurnMeaning?.stale_replay_forbidden || unsupported || lifecycleSignal || valueFlowSignal) }; @@ -284,6 +308,9 @@ export function buildAssistantMcpDiscoveryTurnInput( if (payoutSignal) { pushReason(reasonCodes, "mcp_discovery_payout_signal_detected"); } + if (bidirectionalValueFlowSignal) { + pushReason(reasonCodes, "mcp_discovery_bidirectional_value_flow_signal_detected"); + } if (unsupported) { pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn"); } diff --git a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts index f9ac527..4063b92 100644 --- a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts +++ b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts @@ -1,6 +1,7 @@ // @ts-nocheck import { - resolveAssistantOrganizationAuthority + resolveAssistantOrganizationAuthority, + resolveOrganizationClarificationContinuation } from "./assistantContinuityPolicy"; const ADDRESS_INTENTS_KEEP_ADDRESS_LANE = new Set([ @@ -409,17 +410,22 @@ export function createAssistantRoutePolicy(deps) { continuitySnapshot.lastGroundedAddressDebug; const lastOrganizationClarificationDebug = findLastOrganizationClarificationAddressDebug(sessionItems); const organizationClarificationCandidates = organizationAuthority.organizationClarificationCandidates; - const organizationClarificationSelectionFromScope = organizationAuthority.organizationClarificationSelectionFromScope; - const explicitOrganizationClarificationSelection = resolveOrganizationSelectionFromMessage(rawUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(repairedRawUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(effectiveAddressUserMessage, organizationClarificationCandidates) ?? - resolveOrganizationSelectionFromMessage(repairedEffectiveAddressUserMessage, organizationClarificationCandidates) ?? - null; - const organizationClarificationSelection = explicitOrganizationClarificationSelection ?? - (organizationClarificationSelectionFromScope && - organizationClarificationCandidates.some((candidate) => normalizeOrganizationScopeValue(candidate) === organizationClarificationSelectionFromScope) - ? organizationClarificationSelectionFromScope - : null); + const organizationClarificationContinuation = resolveOrganizationClarificationContinuation({ + rawMessages: [ + rawUserMessage, + repairedRawUserMessage, + effectiveAddressUserMessage, + repairedEffectiveAddressUserMessage + ], + organizationClarificationCandidates, + organizationClarificationSelectionFromScope: organizationAuthority.organizationClarificationSelectionFromScope, + lastOrganizationClarificationDebug, + resolveOrganizationSelectionFromMessage, + toNonEmptyString, + normalizeOrganizationScopeValue + }); + const explicitOrganizationClarificationSelection = organizationClarificationContinuation.explicitSelection; + const organizationClarificationSelection = organizationClarificationContinuation.selection; const metaSignals = resolveMetaSignalSet({ rawUserMessage, repairedRawUserMessage, diff --git a/llm_normalizer/backend/src/services/assistantTransitionPolicy.ts b/llm_normalizer/backend/src/services/assistantTransitionPolicy.ts index 0078a23..d3499c4 100644 --- a/llm_normalizer/backend/src/services/assistantTransitionPolicy.ts +++ b/llm_normalizer/backend/src/services/assistantTransitionPolicy.ts @@ -10,6 +10,7 @@ import { readAddressDebugFilters, readAddressDebugItem, readAddressDebugTemporalScope, + resolveOrganizationClarificationContinuation, resolveNavigationSessionContextState, resolveAddressDebugCarryoverFilters, resolveAddressDebugAnchorContext, @@ -414,17 +415,18 @@ export function createAssistantTransitionPolicy(deps) { const organizationClarificationCandidates = Array.isArray(organizationAuthority.organizationClarificationCandidates) ? organizationAuthority.organizationClarificationCandidates : []; - const explicitOrganizationClarificationSelection = - deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ?? - (deps.toNonEmptyString(alternateMessage) - ? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates) - : null); - const organizationClarificationSelection = - explicitOrganizationClarificationSelection ?? - deps.normalizeOrganizationScopeValue(organizationAuthority.organizationClarificationSelectionFromScope); - const hasOrganizationClarificationContinuation = Boolean( - lastOrganizationClarificationDebug && organizationClarificationSelection - ); + const organizationClarificationContinuation = resolveOrganizationClarificationContinuation({ + rawMessages: [userMessage, alternateMessage], + organizationClarificationCandidates, + organizationClarificationSelectionFromScope: organizationAuthority.organizationClarificationSelectionFromScope, + lastOrganizationClarificationDebug, + resolveOrganizationSelectionFromMessage: deps.resolveOrganizationSelectionFromMessage, + toNonEmptyString: deps.toNonEmptyString, + normalizeOrganizationScopeValue: deps.normalizeOrganizationScopeValue + }); + const explicitOrganizationClarificationSelection = organizationClarificationContinuation.explicitSelection; + const organizationClarificationSelection = organizationClarificationContinuation.selection; + const hasOrganizationClarificationContinuation = organizationClarificationContinuation.hasContinuation; const carryoverSourceDebug = previousAddressDebug ?? (hasOrganizationClarificationContinuation ? lastOrganizationClarificationDebug : null); diff --git a/llm_normalizer/backend/tests/assistantContinuityPolicy.test.ts b/llm_normalizer/backend/tests/assistantContinuityPolicy.test.ts index d065c1c..59e70c6 100644 --- a/llm_normalizer/backend/tests/assistantContinuityPolicy.test.ts +++ b/llm_normalizer/backend/tests/assistantContinuityPolicy.test.ts @@ -12,6 +12,7 @@ import { resolveAddressDebugCarryoverFilters, resolveAddressDebugContextFacts, resolveAddressDebugAnchorContext, + resolveOrganizationClarificationContinuation, resolveDisplayedEntityFollowupRetarget, resolveFollowupTargetIntent, resolveInventoryFollowupPivotFlags, @@ -146,6 +147,27 @@ describe("assistantContinuityPolicy organization authority", () => { }); }); + it("resolves organization clarification continuation through one shared helper", () => { + const continuation = resolveOrganizationClarificationContinuation({ + rawMessages: ["Альтернатива Плюс", null, " "], + organizationClarificationCandidates: ["ООО Альтернатива Плюс", "РАЙМ"], + organizationClarificationSelectionFromScope: "РАЙМ", + lastOrganizationClarificationDebug: { + organization_candidates: ["ООО Альтернатива Плюс", "РАЙМ"] + }, + resolveOrganizationSelectionFromMessage: (message, candidates) => + /альтернатива/i.test(String(message)) + ? String(candidates[0] ?? "") + : null + }); + + expect(continuation).toEqual({ + explicitSelection: "ООО Альтернатива Плюс", + selection: "ООО Альтернатива Плюс", + hasContinuation: true + }); + }); + it("resolves carryover temporal scope and inferred anchor from debug filters when explicit anchor fields are absent", () => { const debug = { extracted_filters: { diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryAnswerAdapter.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryAnswerAdapter.test.ts index d076c0c..cf4a380 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryAnswerAdapter.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryAnswerAdapter.test.ts @@ -15,6 +15,22 @@ function buildDeps(rows: Array>, error: string | null = }; } +function buildSequentialDeps(results: Array<{ rows: Array>; error?: string | null }>) { + const executeAddressMcpQuery = vi.fn(async () => { + const next = results.shift() ?? { rows: [] }; + const rows = next.rows; + const error = next.error ?? null; + return { + fetched_rows: rows.length, + matched_rows: error ? 0 : rows.length, + raw_rows: rows, + rows: error ? [] : rows, + error + }; + }); + return { executeAddressMcpQuery }; +} + describe("assistant MCP discovery answer adapter", () => { it("turns confirmed lifecycle evidence into a human-safe bounded answer draft", async () => { const planner = planAssistantMcpDiscovery({ @@ -139,6 +155,42 @@ describe("assistant MCP discovery answer adapter", () => { expect(draft.unknown_lines).toContain("Full supplier-payout amount outside the checked period is not proven by this MCP discovery pilot"); }); + it("turns bidirectional value-flow evidence into a bounded net cash answer draft", async () => { + const planner = planAssistantMcpDiscovery({ + turnMeaning: { + asked_domain_family: "counterparty_value", + asked_action_family: "net_value_flow", + explicit_entity_candidates: ["SVK"], + explicit_date_scope: "2020", + unsupported_but_understood_family: "counterparty_bidirectional_value_flow_or_netting" + } + }); + const pilot = await executeAssistantMcpDiscoveryPilot( + planner, + buildSequentialDeps([ + { + rows: [ + { Period: "2020-01-15T00:00:00", Amount: 10000, Counterparty: "SVK" }, + { Period: "2020-02-20T00:00:00", Amount: "2 500,50", Counterparty: "SVK" } + ] + }, + { rows: [{ Period: "2020-03-10T00:00:00", Amount: 4000, Counterparty: "SVK" }] } + ]) + ); + + const draft = buildAssistantMcpDiscoveryAnswerDraft(pilot); + const confirmedText = draft.confirmed_lines.join("\n"); + + expect(draft.answer_mode).toBe("confirmed_with_bounded_inference"); + expect(draft.headline).toContain("входящих и исходящих денежных движений"); + expect(confirmedText).toContain("получили 12 500,50 руб."); + expect(confirmedText).toContain("заплатили 4 000 руб."); + expect(confirmedText).toContain("нетто в нашу сторону: 8 500,50 руб."); + expect(draft.inference_lines.join("\n")).toContain("net value-flow"); + expect(draft.unknown_lines).toContain("Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot"); + expect(draft.must_not_claim).toContain("Do not present a derived sum as a legal/accounting final total outside the checked 1C rows."); + }); + it("does not leak primitive names or query text into user-facing lines", async () => { const planner = planAssistantMcpDiscovery({ turnMeaning: { diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryPilotExecutor.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryPilotExecutor.test.ts index de1bd16..a4db30d 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryPilotExecutor.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryPilotExecutor.test.ts @@ -14,6 +14,22 @@ function buildDeps(rows: Array>, error: string | null = }; } +function buildSequentialDeps(results: Array<{ rows: Array>; error?: string | null }>) { + const executeAddressMcpQuery = vi.fn(async () => { + const next = results.shift() ?? { rows: [] }; + const rows = next.rows; + const error = next.error ?? null; + return { + fetched_rows: rows.length, + matched_rows: error ? 0 : rows.length, + raw_rows: rows, + rows: error ? [] : rows, + error + }; + }); + return { executeAddressMcpQuery }; +} + describe("assistant MCP discovery pilot executor", () => { it("executes only the lifecycle query_documents primitive through injected MCP deps", async () => { const planner = planAssistantMcpDiscovery({ @@ -183,6 +199,67 @@ describe("assistant MCP discovery pilot executor", () => { ); }); + it("executes bidirectional value-flow queries and derives guarded net cash flow", async () => { + const planner = planAssistantMcpDiscovery({ + turnMeaning: { + asked_domain_family: "counterparty_value", + asked_action_family: "net_value_flow", + explicit_entity_candidates: ["SVK"], + explicit_date_scope: "2020", + unsupported_but_understood_family: "counterparty_bidirectional_value_flow_or_netting" + } + }); + const deps = buildSequentialDeps([ + { + rows: [ + { Period: "2020-01-15T00:00:00", Amount: 10000, Counterparty: "SVK" }, + { Period: "2020-02-20T00:00:00", Amount: "2 500,50", Counterparty: "SVK" } + ] + }, + { + rows: [{ Period: "2020-03-10T00:00:00", Amount: 4000, Counterparty: "SVK" }] + } + ]); + + const result = await executeAssistantMcpDiscoveryPilot(planner, deps); + + expect(result.pilot_status).toBe("executed"); + expect(result.pilot_scope).toBe("counterparty_bidirectional_value_flow_query_movements_v1"); + expect(result.mcp_execution_performed).toBe(true); + expect(result.executed_primitives).toEqual(["query_movements"]); + expect(result.derived_value_flow).toBeNull(); + expect(result.derived_bidirectional_value_flow).toMatchObject({ + counterparty: "SVK", + period_scope: "2020", + net_amount: 8500.5, + net_amount_human_ru: "8 500,50 руб.", + net_direction: "net_incoming", + coverage_limited_by_probe_limit: false, + incoming_customer_revenue: { + rows_matched: 2, + rows_with_amount: 2, + total_amount: 12500.5, + first_movement_date: "2020-01-15", + latest_movement_date: "2020-02-20" + }, + outgoing_supplier_payout: { + rows_matched: 1, + rows_with_amount: 1, + total_amount: 4000, + first_movement_date: "2020-03-10", + latest_movement_date: "2020-03-10" + } + }); + expect(result.evidence.confirmed_facts[0]).toContain("bidirectional value-flow rows"); + expect(result.evidence.inferred_facts[0]).toContain("net value-flow"); + expect(result.evidence.unknown_facts).toContain( + "Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot" + ); + expect(result.reason_codes).toContain("pilot_bidirectional_value_flow_recipes_selected"); + expect(result.reason_codes).toContain("pilot_derived_bidirectional_value_flow_from_confirmed_rows"); + expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(2); + }); + it("keeps non-lifecycle ready plans unsupported until a dedicated pilot exists", async () => { const planner = planAssistantMcpDiscovery({ turnMeaning: { diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryResponseCandidate.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryResponseCandidate.test.ts index 1f2248b..9ba3d74 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryResponseCandidate.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryResponseCandidate.test.ts @@ -112,6 +112,45 @@ describe("assistant MCP discovery response candidate", () => { expect(candidate.reply_text).not.toContain("query_movements"); }); + it("localizes bidirectional net value-flow evidence without leaking pilot mechanics", () => { + const candidate = buildAssistantMcpDiscoveryResponseCandidate( + entryPoint({ + bridge: { + bridge_status: "answer_draft_ready", + user_facing_response_allowed: true, + business_fact_answer_allowed: true, + requires_user_clarification: false, + answer_draft: { + answer_mode: "confirmed_with_bounded_inference", + headline: "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду.", + confirmed_lines: [ + "1C bidirectional value-flow rows were checked for counterparty SVK: incoming=found, outgoing=found", + "По найденным строкам 1С по контрагенту SVK за период 2020: получили 12 500,50 руб. по входящим движениям, заплатили 4 000 руб. по исходящим платежам/списаниям. Расчетное нетто в нашу сторону: 8 500,50 руб." + ], + inference_lines: [ + "Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows" + ], + unknown_lines: [ + "Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached", + "Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot" + ], + limitation_lines: ["pilot_bidirectional_value_flow_uses_two_query_movements_and_derives_net"], + next_step_line: null + } + } + }) + ); + + expect(candidate.candidate_status).toBe("ready_for_guarded_use"); + expect(candidate.reply_text).toContain("В 1С проверены входящие и исходящие денежные строки по контрагенту SVK"); + expect(candidate.reply_text).toContain("получили 12 500,50 руб."); + expect(candidate.reply_text).toContain("заплатили 4 000 руб."); + expect(candidate.reply_text).toContain("нетто в нашу сторону: 8 500,50 руб."); + expect(candidate.reply_text).toContain("Полное покрытие запрошенного периода по двустороннему денежному потоку не подтверждено"); + expect(candidate.reply_text).not.toContain("pilot_"); + expect(candidate.reply_text).not.toContain("query_movements"); + }); + it("returns not applicable when discovery was skipped for an exact supported route", () => { const candidate = buildAssistantMcpDiscoveryResponseCandidate({ schema_version: "assistant_mcp_discovery_runtime_entry_point_v1", diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts index 4105b1f..bb43682 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts @@ -108,6 +108,29 @@ describe("assistant MCP discovery turn input adapter", () => { expect(result.reason_codes).toContain("mcp_discovery_payout_signal_detected"); }); + it("keeps net cash wording as bidirectional value-flow discovery", () => { + const result = buildAssistantMcpDiscoveryTurnInput({ + userMessage: "какое нетто по деньгам с Группа СВК за 2020: сколько получили и сколько заплатили?", + predecomposeContract: { + entities: { counterparty: "Группа СВК" }, + period: { period_from: "2020-01-01", period_to: "2020-12-31" } + } + }); + + expect(result.adapter_status).toBe("ready"); + expect(result.semantic_data_need).toBe("counterparty value-flow evidence"); + expect(result.turn_meaning_ref).toMatchObject({ + asked_domain_family: "counterparty_value", + asked_action_family: "net_value_flow", + explicit_entity_candidates: ["Группа СВК"], + explicit_date_scope: "2020", + unsupported_but_understood_family: "counterparty_bidirectional_value_flow_or_netting", + stale_replay_forbidden: true + }); + expect(result.reason_codes).toContain("mcp_discovery_bidirectional_value_flow_signal_detected"); + expect(result.reason_codes).not.toContain("mcp_discovery_payout_signal_detected"); + }); + it("does not activate discovery for supported exact current-turn intent", () => { const result = buildAssistantMcpDiscoveryTurnInput({ assistantTurnMeaning: { diff --git a/llm_normalizer/data/autorun_generators/history.json b/llm_normalizer/data/autorun_generators/history.json index 08742ae..326fefd 100644 --- a/llm_normalizer/data/autorun_generators/history.json +++ b/llm_normalizer/data/autorun_generators/history.json @@ -1,4 +1,43 @@ [ + { + "generation_id": "gen-mo6rqcw8-kuswg6b", + "created_at": "2026-04-20T05:42:42.633Z", + "mode": "qwen_seed", + "title": null, + "count": 15, + "domain": null, + "questions": [ + "По каким контрагентам у нас висит сальдо, которое уже больше месяца не менялось и выглядит как застывший долг?", + "Где у нас поставщики, которые давно отгружали, но оплаты так и нет — можно ли их считать просроченными или это просто задержка в документах?", + "Покажи всех клиентов, по которым есть отгрузки, но денег с них не поступало уже больше 60 дней — какие из них вообще активны?", + "По каким контрагентам у нас есть оплаты, но нет закрытия счетов, и это выглядит как архивный кэш?", + "Кто из заказчиков давно не платил, но при этом по ним висят открытые договора — можно ли считать их активными или уже нужно смотреть на отключение?", + "Где у нас авансы, которые уже прошли 3 месяца после получения, но не закрыты ни документами, ни сверками?", + "Покажи все контрагенты, по которым в 1С указано «договор активен», а оплаты и отгрузки — ноль за последние полгода", + "По каким поставщикам у нас есть счета-фактуры, но документы об оплате не приходили?", + "А может быть, они вообще висят?", + "Какие клиенты уже давно получали товары, но по ним нет актов сверки и счёт-фактур — возможно, это ошибка или просто пропущенные действия?", + "Где у нас есть документы по отгрузке, но оплаты не видно — может, деньги пришли, но не привязались?", + "Покажи всех контрагентов с незакрытыми договорами и остатками в долгах свыше 100 тыс. — кто из них реально проблемный?", + "Какие поставщики у нас на текущий момент имеют несогласованные остатки, и где это может повлиять на отчётность?", + "Где у нас зависшие взаиморасчёты, когда документы есть, но оплаты нет — можно ли считать это технической ошибкой или уже ручная проверка нужна?", + "По каким контрагентам в 1С отображается активность, но при этом у них ноль поставок и оплат за год?" + ], + "generated_by": "manual_reviewer", + "saved_case_set_file": "assistant_autogen_qwen_seed_20260420054242_gen-mo6rqcw8-kuswg6b.json", + "context": { + "llm_provider": "local", + "model": "unsloth/qwen3-30b-a3b-instruct-2507", + "assistant_prompt_version": "address_query_runtime_v1", + "decomposition_prompt_version": "normalizer_v2_0_2", + "prompt_fingerprint": "Ты semantic-normalizer для бухгалтерского ассистента NDC.\nТвоя роль: только нормализация запроса пользователя в строгий JSON-контракт.\n\nЖесткие правила:\n1) Не давай бухгалтерский ответ по сути вопроса.\n2) Возвращай только JSON без markdown и пояснений.\n3) JSON обязан соответствовать переданной schema normalized_query_v1.\n4) Если период не указан, не выдумывай его; отмечай ambiguity.\n5) Для цепочек документов/проводок/оплат поднимай causal и cross-entity признаки.\n6) Для точечного object trace (номер/строка/ref) поднимай needs_exact_object_trace=true.\n7) Используй терминологию NDC.\nYou are semantic-normalizer for accounting assistant NDC.\nReturn strict JSON only, no markdown, no comments.\n\nTarget schema: normalized_query_v2_0_2.\n\nCore behavior (v2.0.2):\n1. Decompose message into semantic fragments.\n2. Classify fragment domain relevance and business scope.\n3. Fill route-critical flags and ", + "autogen_personality_id": "general", + "autogen_personality_prompt": "Генерируй реалистичные живые вопросы бухгалтера по 1С. Добавляй разговорные формулировки и опечатки, но сохраняй бизнес-смысл. акцент на контрагентов, долги нсд, счета, общий вывод по компании - контрагенты, заказчикам, скока денег кто принес и какие остатки по счетам, поиск документов, сальдо, банковские операции, незакрытые договора, документы по договорам, долги, Активность заказчиков по периодам, Поставщики и выплаты", + "source_session_id": null, + "saved_session_file": null, + "saved_case_set_kind": "single_turn_list" + } + }, { "generation_id": "gen-ag04200344-0dc69f", "created_at": "2026-04-20T03:44:04+00:00", @@ -48,7 +87,48 @@ "smalltalk_entry", "stale_entity_seed", "stale_replay_forbidden" - ] + ], + "latest_acceptance": null + } + }, + { + "generation_id": "gen-mo5zy5vo-z9klj34", + "created_at": "2026-04-19T16:44:57.543Z", + "mode": "saved_user_sessions", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "count": 9, + "domain": null, + "questions": [ + "привет как дела", + "кто намс должен денег на сегодня", + "что ты можешь", + "кто нам должен денег на сегодня", + "а мы кому", + "какиек остатки на складе на сегодня", + "альтернатива", + "покажи документы по чепурнову", + "какой оборот был свк" + ], + "generated_by": "manual_reviewer", + "saved_case_set_file": "assistant_autogen_saved_user_sessions_20260419164457_gen-mo5zy5vo-z9klj34.json", + "context": { + "llm_provider": "local", + "model": "unsloth/qwen3-30b-a3b-instruct-2507", + "assistant_prompt_version": "address_query_runtime_v1", + "decomposition_prompt_version": "normalizer_v2_0_2", + "prompt_fingerprint": "Ты semantic-normalizer для бухгалтерского ассистента NDC.\nТвоя роль: только нормализация запроса пользователя в строгий JSON-контракт.\n\nЖесткие правила:\n1) Не давай бухгалтерский ответ по сути вопроса.\n2) Возвращай только JSON без markdown и пояснений.\n3) JSON обязан соответствовать переданной schema normalized_query_v1.\n4) Если период не указан, не выдумывай его; отмечай ambiguity.\n5) Для цепочек документов/проводок/оплат поднимай causal и cross-entity признаки.\n6) Для точечного object trace (номер/строка/ref) поднимай needs_exact_object_trace=true.\n7) Используй терминологию NDC.||You are semantic-normalizer for accounting assistant NDC.\nReturn strict JSON only, no markdown, no comments.\n\nTarget schema: normalized_query_v2_0_2.\n\nCore behavior (v2.0.2):\n1. Decompose message into semantic fragments.\n2. Classify fragment domain relevance and business scope.\n3. Fill route-critical flags and candidate labels.\n4. For each fragment set execution state fields:\n - execution_readiness\n - clarification_reason\n - soft_assumption_used\n - route_status\n - no_route_reason\n5. Clarification must be rare and justified.\n\nExecution-state policy:\n- Every in-scope fragment must produce a consistent execution state.\n- If a fragment is routable, mark it as executable or executable_with_soft_assumptions.\n- Do not leave routable fragments in unresolved state.\n- If a fragment cannot be routed, set route_status=no_route and provide explicit no_route_reason.\n\nReadiness values:\n- executable\n- executable_with_soft_assumptions\n- needs_clarification\n- no_route\n\nRoute status values:\n- routed\n- no_route\n\nNo-route reason values:\n- out_of_scope\n- insufficient_specificity\n- missing_mapping\n- unsupported_fragment_type\n\nDo not over-require formality:\n- Do not require document IDs, exact periods, or exact object references for scan/review/anomaly/rule-check requests.\n- Colloquial accounting phrases like \"что висит\", \"что подозрительно\", \"что не сходится\", \"что криво\", \"что аукнется\" are executable if accounting area is understandable.\n\nFragment required fields:\n- fragment_id\n- raw_fragment_text\n- normalized_fragment_text\n- domain_relevance\n- business_scope\n- entity_hints\n- account_hints\n- document_hints\n- register_hints\n- time_scope\n- flags\n- candidate_labels\n- confidence\n- execution_readiness\n- clarification_reason\n- soft_assumption_used\n- route_status\n- no_route_reason\n\nSoft assumptions (`soft_assumption_used`) allowed values:\n- period_from_session_context\n- company_scope_defaulted\n- problem_scan_mode_enabled\n\nGlobal notes:\n- global_notes.needs_clarification should be true only when execution is truly blocked for all in-scope fragments.\n- global_notes.clarification_reason must explain the blocker.\n\nSchema version must be:\n- \"schema_version\": \"normalized_query_v2_0_2\"||Контекст домена: бухгалтерия 1С/NDC.\n\nКлючевые счета:\n- 01, 02, 10, 41, 51, 60, 62, 68.02, 90, 97.\n\nТиповые сущности:\n- контрагент, договор, документ реализации, документ поступления, оплата, проводка, регистр, закрывающий документ.\n\nЛексика causal и сверки (сильные сигналы для cross_entity):\n- \"не бьется\", \"не сходится\", \"не видно\", \"не собралось\", \"повисло\", \"хвост\";\n- \"разложи по документам/оплатам/закрывающим\";\n- \"чем подтверждается\", \"где ошибка в цепочке\", \"что пошло криво\".\n\nЛексика точечного drilldown:\n- \"документ №...\", \"ref\", \"строка проводки\", \"покажи конкретную операцию\", \"точный source-of-record\".\n\nЛексика rule-based контроля:\n- \"проверь настройки\", \"ошибка срока/даты\", \"контроль 97/10/ОС\", \"нарушение правила учета\".\n\nЛексика обзорной аналитики:\n- \"рейтинг\", \"топ рисков\", \"в целом по компании\", \"перед закрытием периода\", \"приоритизация проверок\".\n\nВажное правило:\nЕсли в одном вопросе есть и риск-лексика, и цепочка document/payment/posting, не понижать задачу до чистого `store_feature_risk`.\nПриоритет у causal cross-entity семантики.||v2.0.2: execution-state hardening + explicit route_status/no_route_reason. Схема normalized_query_v2_0_2.||Q: По каким поставщикам висят хвосты по 60, что подозрительно по цепочке оплат?\nA: in_scope fragment, execution_readiness=executable_with_soft_assumptions, route_status=routed, no_route_reason=null.\n\nQ: Покажи записи по 97, которые повисли и могут аукнуться.\nA: in_scope fragment, execution_readiness=executable_with_soft_assumptions, route_status=routed, no_route_reason=null.\n\nQ: Чекни, что у нас не так.\nA: unclear/in_scope fragment, execution_readiness=needs_clarification, route_status=no_route, no_route_reason=insufficient_specificity.\n\nQ: Как вообще по ФСБУ правильно?\nA: out_of_scope fragment, execution_readiness=no_route, route_status=no_route, no_route_reason=out_of_scope.", + "autogen_personality_id": null, + "autogen_personality_prompt": null, + "source_session_id": "asst-HFD9N5qwZM", + "saved_session_file": "assistant_saved_session_20260419164457_gen-mo5zy5vo-z9klj34.json", + "saved_case_set_kind": "assistant_session_scenario", + "agent_run": null, + "agent_focus": null, + "architecture_phase": null, + "source_spec_file": null, + "scenario_id": null, + "semantic_tags": null, + "latest_acceptance": null } }, { @@ -1014,4 +1094,4 @@ "latest_acceptance": null } } -] +] \ No newline at end of file diff --git a/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260419164457_gen-mo5zy5vo-z9klj34.json b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260419164457_gen-mo5zy5vo-z9klj34.json new file mode 100644 index 0000000..2b9befe --- /dev/null +++ b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260419164457_gen-mo5zy5vo-z9klj34.json @@ -0,0 +1,5165 @@ +{ + "saved_at": "2026-04-19T16:44:57.542Z", + "generation_id": "gen-mo5zy5vo-z9klj34", + "mode": "saved_user_sessions", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "source_session_id": "asst-HFD9N5qwZM", + "questions": [ + "привет как дела", + "кто намс должен денег на сегодня", + "что ты можешь", + "кто нам должен денег на сегодня", + "а мы кому", + "какиек остатки на складе на сегодня", + "альтернатива", + "покажи документы по чепурнову", + "какой оборот был свк" + ], + "session": { + "session_id": "asst-HFD9N5qwZM", + "updated_at": "2026-04-19T15:58:20.316Z", + "items": [ + { + "message_id": "msg-wB07pLW2K3", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "привет как дела", + "reply_type": null, + "created_at": "2026-04-19T15:42:13.731Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-bhwn575Pnc", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Привет! Всё нормально. Если дальше пойдём в данные 1С, могу сразу зафиксировать организацию: ООО Альтернатива Плюс, ООО Лайсвуд, РАЙМ. Просто напишите название компании, и дальше буду держать её активной в этой сессии.", + "reply_type": "factual_with_explanation", + "created_at": "2026-04-19T15:42:25.974Z", + "trace_id": "chat-P6TSNKGo6f", + "debug": { + "trace_id": "chat-P6TSNKGo6f", + "prompt_version": "living_chat_router_v1", + "schema_version": "living_chat_router_v1", + "fallback_type": "none", + "detected_mode": "chat", + "detected_mode_confidence": "high", + "execution_lane": "living_chat", + "living_router_mode": "chat", + "living_router_reason": "non_domain_query_indexed", + "living_chat_response_source": "deterministic_smalltalk_with_proactive_scope_offer", + "living_chat_script_guard_applied": false, + "living_chat_script_guard_reason": null, + "living_chat_grounding_guard_applied": false, + "living_chat_grounding_guard_reason": null, + "living_chat_proactive_scope_offer_applied": true, + "living_chat_data_scope_probe_status": "resolved", + "living_chat_data_scope_probe_channel": "default", + "living_chat_data_scope_probe_org_count": 3, + "living_chat_data_scope_probe_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "living_chat_data_scope_probe_error": null, + "living_chat_continuity_grounded_context_detected": false, + "living_chat_continuity_active_organization": null, + "living_chat_selected_organization": null, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_active_organization": null, + "address_llm_predecompose_attempted": true, + "address_llm_predecompose_applied": false, + "address_llm_predecompose_reason": "no_usable_fragment", + "address_llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "привет как дела", + "canonical_message": "привет как дела", + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "none", + "anchor_kind": "none", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": false, + "selected_object_scope_detected": false + }, + "aggregation_profile": "unknown" + }, + "address_semantic_extraction_contract": { + "schema_version": "address_semantic_extraction_contract_v1", + "source_message": "привет как дела", + "canonical_message": "привет как дела", + "canonical_rewrite_applied": false, + "extraction": { + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "unknown", + "intent_confidence": "low", + "aggregation_profile": "unknown" + }, + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "none", + "anchor_kind": "none", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": false, + "selected_object_scope_detected": false + }, + "guard_hints": { + "source_data_signal_detected": false, + "canonical_data_signal_detected": false, + "data_scope_meta_query_detected": false, + "deep_investigation_signal_detected": false, + "required_anchor_missing": false, + "unsupported_low_confidence": true, + "semantic_drift_suspected": false + }, + "quality": "low", + "valid": false, + "apply_canonical_recommended": false, + "reason_codes": [ + "unsupported_low_confidence_contract" + ] + }, + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": "non_domain", + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "unsupported", + "address_mode_confidence": "low", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": false, + "data_retrieval_signal_detected": false, + "followup_context_detected": false, + "unsupported_address_intent_fallback_to_deep": false, + "final_decision": { + "run_address_lane": false, + "tool_gate_decision": "skip_address_lane", + "tool_gate_reason": "non_domain_query_indexed", + "living_mode": "chat", + "living_reason": "non_domain_query_indexed" + } + }, + "tool_gate_decision": "skip_address_lane", + "tool_gate_reason": "non_domain_query_indexed", + "normalized": null, + "normalizer_output": null + } + }, + { + "message_id": "msg-zGoYrBHFNn", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "кто намс должен денег на сегодня", + "reply_type": null, + "created_at": "2026-04-19T15:42:50.135Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-dZvpQ9I04_", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "На текущий момент не удается точно определить, кто из контрагентов должен деньги компании на сегодняшнюю дату — такой запрос пока не поддерживается в рамках доступных сценариев.\n\nПроверено: данные по конкретным контрагентам, договорам и остаткам по счетам за последние периоды. Однако прямой расчёт задолженности «на текущую дату» по всем контрагентам недоступен.\n\nРекомендую уточнить запрос: можно проверить остатки по конкретному контрагенту или просмотреть документы и платежи по выбранному договору.", + "reply_type": "partial_coverage", + "created_at": "2026-04-19T15:43:09.425Z", + "trace_id": "address-w4mBasVNl3", + "debug": { + "trace_id": "address-w4mBasVNl3", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "partial", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "partial", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "high", + "query_shape": "COMPOUND_FACTUAL_QUERY", + "query_shape_confidence": "medium", + "detected_intent": "unknown", + "detected_intent_confidence": "low", + "extracted_filters": { + "sort": "period_desc", + "limit": 20, + "counterparty": "на текущую дату" + }, + "missing_required_filters": [], + "selected_recipe": null, + "mcp_call_status_legacy": "skipped", + "account_scope_mode": "strict", + "account_scope_fallback_applied": false, + "anchor_type": "counterparty", + "anchor_value_raw": "на текущую дату", + "anchor_value_resolved": "на текущую дату", + "resolver_confidence": "medium", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "skipped", + "rows_fetched": 0, + "raw_rows_received": 0, + "rows_after_account_scope": 0, + "rows_after_recipe_filter": 0, + "rows_materialized": 0, + "rows_matched": 0, + "raw_row_keys_sample": [], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "DEEP_ONLY", + "limited_reason_category": "unsupported", + "response_type": "LIMITED_WITH_REASON", + "capability_id": "address_unknown", + "capability_layer": "conversational", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "generic_address_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "not_found", + "route_expectation_reason": "route_expectation_not_defined_for_intent", + "route_expectation_expected_selected_recipes": [], + "route_expectation_expected_requested_result_modes": [], + "route_expectation_expected_result_modes": [], + "execution_lane": "address_query", + "llm_decomposition_applied": true, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "foaff6rjGSl52d", + "llm_decomposition_effective_message": "определить, кто из контрагентов должен деньги компании на текущую дату", + "llm_decomposition_reason": "normalized_fragment_applied", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "кто намс должен денег на сегодня", + "canonical_message": "определить, кто из контрагентов должен деньги компании на текущую дату", + "mode": "address_query", + "mode_confidence": "high", + "query_shape": "COMPOUND_FACTUAL_QUERY", + "query_shape_confidence": "medium", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": "на текущую дату", + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": true + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "explicit", + "date_basis_hint": null, + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "aggregation_profile": "unknown" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "кто намс должен денег на сегодня", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "address_query", + "address_mode_confidence": "high", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": false, + "followup_semantic_override_to_deep_allowed": false + }, + "followup_context_detected": false, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "кто намс должен денег на сегодня", + "effective_message": "определить, кто из контрагентов должен деньги компании на текущую дату", + "decision": "new_topic", + "decision_reasons": [ + "effective_message_rewritten_by_predecompose" + ], + "followup_context_applied": false, + "previous_intent": null, + "target_intent": null, + "intent_selection_mode": null, + "anchor_type": null, + "anchor_value": null, + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": true, + "reason": "limited_result_retry_with_raw_message", + "initial_limited_category": "unsupported", + "retry_message": "кто намс должен денег на сегодня", + "retry_used_followup_context": false, + "retry_result_category": "unsupported" + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "foaff6rjGSl52d", + "prompt_version": "normalizer_v2_0_2", + "applied": true, + "effective_message": "определить, кто из контрагентов должен деньги компании на текущую дату" + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": null, + "transition_contract_title": null, + "transition_contract_reason": [ + "transition_contract_not_resolved" + ], + "capability_contract_id": null, + "capability_contract_reason": [ + "debug_capability_id_has_no_contract" + ], + "truth_gate_contract_status": "partial_supported", + "carryover_eligibility": "none" + }, + "transition_contract_id": null, + "capability_contract_id": null, + "truth_gate_contract_status": "partial_supported", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "partial", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "limited", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_partial_supported", + "truth_mode_limited", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ], + "source_truth_gate_status": "partial_supported", + "blocked_or_limited_explanation": "evidence_or_coverage_is_partial" + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "limited_with_reason", + "reply_type": "partial_coverage", + "capability_contract_id": null, + "transition_contract_id": null, + "may_state_confirmed_facts": true, + "must_include_limitation": true, + "may_power_followup": false, + "required_sections": [ + "direct_answer", + "evidence_window", + "limitations" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "partial", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "limited", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_partial_supported", + "truth_mode_limited", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ], + "source_truth_gate_status": "partial_supported", + "blocked_or_limited_explanation": "evidence_or_coverage_is_partial" + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "limited_with_reason", + "reply_type": "partial_coverage", + "capability_contract_id": null, + "transition_contract_id": null, + "may_state_confirmed_facts": true, + "must_include_limitation": true, + "may_power_followup": false, + "required_sections": [ + "direct_answer", + "evidence_window", + "limitations" + ], + "downgrade_only": true + }, + "truth_mode": "limited", + "carryover_eligibility": "none", + "answer_shape": "limited_with_reason", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": null, + "transition_title": null, + "application_status": "unresolved", + "declared_carryover_depth": null, + "truth_gate_carryover_depth": "none", + "effective_carryover_depth": "none", + "required_prior_state": [], + "expected_answer_mode": null, + "state_mutations": [], + "forbidden_carryover": [ + "implicit_followup_reuse" + ], + "state_actions": { + "living_mode_state": "none", + "root_frame_state": "none", + "selected_object_frame_state": "none", + "meta_frame_state": "none", + "clarification_state": "none", + "coverage_gate_state": "none", + "answer_context_state": "none" + }, + "coverage_gate_state": { + "coverage_status": "partial", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "limited", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_partial_supported", + "truth_mode_limited", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "reason_codes": [ + "transition_status_unresolved", + "transition_unresolved", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "truth_gate_partial_supported", + "truth_mode_limited", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": null, + "transition_title": null, + "application_status": "unresolved", + "declared_carryover_depth": null, + "truth_gate_carryover_depth": "none", + "effective_carryover_depth": "none", + "required_prior_state": [], + "expected_answer_mode": null, + "state_mutations": [], + "forbidden_carryover": [ + "implicit_followup_reuse" + ], + "state_actions": { + "living_mode_state": "none", + "root_frame_state": "none", + "selected_object_frame_state": "none", + "meta_frame_state": "none", + "clarification_state": "none", + "coverage_gate_state": "none", + "answer_context_state": "none" + }, + "coverage_gate_state": { + "coverage_status": "partial", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "limited", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_partial_supported", + "truth_mode_limited", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "reason_codes": [ + "transition_status_unresolved", + "transition_unresolved", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "truth_gate_partial_supported", + "truth_mode_limited", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "state_transition_id": null, + "state_transition_status": "unresolved", + "effective_carryover_depth": "none", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "address_unknown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": null, + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "counterparty" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_unresolved", + "transition_unresolved", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "truth_gate_partial_supported", + "truth_mode_limited", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "address_unknown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": null, + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "counterparty" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_unresolved", + "transition_unresolved", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "truth_gate_partial_supported", + "truth_mode_limited", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + }, + "capability_binding_status": "contract_missing", + "capability_binding_action": "observe_only", + "capability_binding_violations": [ + "capability_contract_missing" + ], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "observe_only", + "original_reply_type": "partial_coverage", + "guarded_reply_type": "partial_coverage", + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_unresolved", + "transition_unresolved", + "transition_contract_not_resolved", + "debug_capability_id_has_no_contract", + "truth_gate_partial_supported", + "truth_mode_limited", + "route_expectation_not_defined_for_intent", + "address_action_detected", + "address_entity_detected", + "compound_signal_detected", + "intent_not_supported_in_v1" + ] + } + } + }, + { + "message_id": "msg-KYjsq8REFi", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "что ты можешь", + "reply_type": null, + "created_at": "2026-04-19T15:43:20.723Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-H9r93w6toV", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Могу помочь с вопросами по данным 1С : НДС, контрагенты, долги, деньги и склад.\nОсновные направления:\n1. НДС: Расчеты и аналитика по НДС на основании данных 1С.. Например: Сколько НДС к уплате за период?; Покажи срез НДС на дату.\n2. Контрагенты: Срезы активности, платежей и документов по контрагентам.. Например: Покажи документы по контрагенту.; Какие операции по банку были с контрагентом?\n3. Задолженности и расчеты: Аналитика закрытия расчетов, сальдо и признаков незакрытых цепочек.. Например: Закрылись ли расчеты по счету 60/62?; Есть ли незакрытые авансы?\n4. Деньги и остатки: Остатки и динамика по денежным счетам и кассе.. Например: Какой остаток по счету 51 на дату?; Покажи движение денег за месяц.\n5. Товары и складские остатки: Подтвержденные срезы товарных остатков по складам и организациям на дату.. Например: Какие товары сейчас лежат на складе?; Покажи остатки товаров на дату.\n6. Ограничения: Операции, которые ассистент не выполняет в этом рантайме.. Например: Можешь настроить 1С?; Можешь удалить базу?\nЕсли хотите, можно сразу задать конкретный вопрос по документам, остаткам, НДС, контрагенту или договору.\nНе делаю только административные действия: не настраиваю 1С, не меняю конфигурацию, не создаю и не провожу документы, не выполняю админ-действия на сервере.", + "reply_type": "factual_with_explanation", + "created_at": "2026-04-19T15:43:32.905Z", + "trace_id": "chat-NKvtuiR3nf", + "debug": { + "trace_id": "chat-NKvtuiR3nf", + "prompt_version": "living_chat_router_v1", + "schema_version": "living_chat_router_v1", + "fallback_type": "none", + "detected_mode": "chat", + "detected_mode_confidence": "high", + "execution_lane": "living_chat", + "living_router_mode": "chat", + "living_router_reason": "assistant_capability_query_detected", + "living_chat_response_source": "deterministic_capability_contract", + "living_chat_script_guard_applied": false, + "living_chat_script_guard_reason": null, + "living_chat_grounding_guard_applied": false, + "living_chat_grounding_guard_reason": null, + "living_chat_proactive_scope_offer_applied": false, + "living_chat_data_scope_probe_status": null, + "living_chat_data_scope_probe_channel": null, + "living_chat_data_scope_probe_org_count": 0, + "living_chat_data_scope_probe_organizations": [], + "living_chat_data_scope_probe_error": null, + "living_chat_continuity_grounded_context_detected": false, + "living_chat_continuity_active_organization": null, + "living_chat_selected_organization": null, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_active_organization": null, + "address_llm_predecompose_attempted": true, + "address_llm_predecompose_applied": false, + "address_llm_predecompose_reason": "normalized_fragment_rejected_semantic_guard", + "address_llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "что ты можешь", + "canonical_message": "что ты можешь", + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "aggregation_profile": "unknown" + }, + "address_semantic_extraction_contract": { + "schema_version": "address_semantic_extraction_contract_v1", + "source_message": "что ты можешь", + "canonical_message": "что ты можешь", + "canonical_rewrite_applied": false, + "extraction": { + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "unknown", + "intent_confidence": "low", + "aggregation_profile": "unknown" + }, + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "guard_hints": { + "source_data_signal_detected": false, + "canonical_data_signal_detected": false, + "data_scope_meta_query_detected": false, + "deep_investigation_signal_detected": false, + "required_anchor_missing": false, + "unsupported_low_confidence": true, + "semantic_drift_suspected": false + }, + "quality": "low", + "valid": false, + "apply_canonical_recommended": false, + "reason_codes": [ + "unsupported_low_confidence_contract" + ] + }, + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": "capability", + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "unsupported", + "address_mode_confidence": "low", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": false, + "data_retrieval_signal_detected": false, + "followup_context_detected": false, + "unsupported_address_intent_fallback_to_deep": false, + "final_decision": { + "run_address_lane": false, + "tool_gate_decision": "skip_address_lane", + "tool_gate_reason": "assistant_capability_query_detected", + "living_mode": "chat", + "living_reason": "assistant_capability_query_detected" + } + }, + "tool_gate_decision": "skip_address_lane", + "tool_gate_reason": "assistant_capability_query_detected", + "normalized": null, + "normalizer_output": null + } + }, + { + "message_id": "msg-0MIdb1G1MI", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "кто нам должен денег на сегодня", + "reply_type": null, + "created_at": "2026-04-19T15:45:02.766Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-65k6tTD6OM", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Коротко: подтвержденная дебиторская задолженность на 19.04.2026 — **14.204.897,08** ₽.\nЭто подтвержденный срез дебиторской задолженности, а не эвристический shortlist.\n\nЧто учтено\n- Дата среза: 19.04.2026.\n- Контур: дебиторская задолженность по счетам 62/76.\n- В срез могут входить задолженности, возникшие до периода, если они оставались открытыми на дату среза.\n\nСводка\n- Строк в выборке: **22**.\n- Контрагентов с подтвержденным остатком к получению: **6**.\n\nКатегории дебиторской задолженности\n- покупатели/заказчики: **3**.\n- банки/финансовые: **0**.\n- бюджет/госорганы: **3**.\n- прочие: **0**.\n\nПодтвержденные позиции к получению\n1. Департамент капитального ремонта города Москвы. | категория: бюджет/госорганы | остаток к получению: **9.612.904,90** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: налог/госорган в аналитике | договор: ГК № 20ГК-ДКР/**19** от 13.05.2019 | документ: Остатки на дату | source refs: Списание с расчетного счета **00000000102** от 20.03.2020 12:00:00\n\n2. Комитет государственных услуг г. Москвы | категория: бюджет/госорганы | остаток к получению: **3.677.454,14** ₽ | операций: **14** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), налог/госорган в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату | source refs: Финансовое обеспечение заявки; Списание с расчетного счета **00000000015** от 27.01.2015 12:00:03\n\n3. ГКУ | категория: покупатели/заказчики | остаток к получению: **773.953,04** ₽ | операций: **4** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: ГКУ | документ: Остатки на дату | source refs: Финансовое обеспечение заявки; Списание с расчетного счета **00000000099** от 26.06.2017 12:00:02\n\n4. Финансовое обеспечение заявки | категория: бюджет/госорганы | остаток к получению: **115.185,00** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), налог/госорган в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату | source refs: Списание с расчетного счета **00000000253** от 29.10.2015 12:00:00\n\n5. Савва Офис Сервис | категория: покупатели/заказчики | остаток к получению: **19.200,00** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: договор **1** от 18.12.2018 | документ: Остатки на дату\n\n6. Держава АКБ, ПАО | категория: покупатели/заказчики | остаток к получению: **6.200,00** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: Договор № БГ 155822/2017 от 08.11.17 заявка **145822** | документ: Остатки на дату", + "reply_type": "factual", + "created_at": "2026-04-19T15:45:14.679Z", + "trace_id": "address-xIAvQkuYw1", + "debug": { + "trace_id": "address-xIAvQkuYw1", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "none", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "grounded", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "high", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "detected_intent": "receivables_confirmed_as_of_date", + "detected_intent_confidence": "high", + "extracted_filters": { + "sort": "period_desc", + "limit": 20, + "as_of_date": "2026-04-19" + }, + "missing_required_filters": [], + "selected_recipe": "address_receivables_confirmed_as_of_date_v1", + "mcp_call_status_legacy": "matched_non_empty", + "account_scope_mode": "strict", + "account_scope_fallback_applied": false, + "anchor_type": "unknown", + "anchor_value_raw": null, + "anchor_value_resolved": null, + "resolver_confidence": "low", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "matched_non_empty", + "rows_fetched": 22, + "raw_rows_received": 22, + "rows_after_account_scope": 22, + "rows_after_recipe_filter": 22, + "rows_materialized": 22, + "rows_matched": 22, + "raw_row_keys_sample": [ + "Период", + "Регистратор", + "СчетДт", + "СчетКт", + "Сумма", + "СубконтоДт1", + "СубконтоДт2", + "СубконтоДт3", + "СубконтоКт1", + "СубконтоКт2", + "СубконтоКт3", + "Организация", + "Period", + "Registrator", + "AccountDt", + "Amount" + ], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": null, + "response_type": "FACTUAL_LIST", + "requested_result_mode": "confirmed_balance", + "result_mode": "confirmed_balance", + "evidence_strength": "strong", + "balance_confirmed": true, + "as_of_date_basis": "implicit_current_snapshot", + "capability_id": "confirmed_receivables_as_of_date", + "capability_layer": "compute", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "receivables_confirmed_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_receivables_confirmed_as_of_date_v1" + ], + "route_expectation_expected_requested_result_modes": [ + "confirmed_balance" + ], + "route_expectation_expected_result_modes": [ + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": false, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "M3vXwbr5ssJQls", + "llm_decomposition_effective_message": "кто нам должен денег на сегодня", + "llm_decomposition_reason": "normalized_fragment_rejected_intent_drop", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "кто нам должен денег на сегодня", + "canonical_message": "кто нам должен денег на сегодня", + "mode": "address_query", + "mode_confidence": "high", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "receivables_confirmed_as_of_date", + "intent_confidence": "high", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "as_of", + "period_from": null, + "period_to": null, + "as_of_date": "2026-04-19", + "has_explicit_period": true + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "explicit", + "date_basis_hint": "implicit_current_snapshot", + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "aggregation_profile": "balance_snapshot" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "кто нам должен денег на сегодня", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "address_query", + "address_mode_confidence": "high", + "address_intent": "receivables_confirmed_as_of_date", + "address_intent_confidence": "high", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": true, + "followup_semantic_override_to_deep_allowed": false + }, + "followup_context_detected": false, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "кто нам должен денег на сегодня", + "effective_message": "кто нам должен денег на сегодня", + "decision": "new_topic", + "decision_reasons": [ + "llm_contract_intent_available" + ], + "followup_context_applied": false, + "previous_intent": null, + "target_intent": "receivables_confirmed_as_of_date", + "intent_selection_mode": null, + "anchor_type": null, + "anchor_value": null, + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": false, + "reason": null, + "initial_limited_category": null, + "retry_message": null, + "retry_used_followup_context": false, + "retry_result_category": null + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "M3vXwbr5ssJQls", + "prompt_version": "normalizer_v2_0_2", + "applied": false, + "effective_message": "кто нам должен денег на сегодня" + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T1", + "transition_contract_title": "Root Query Entry", + "transition_contract_reason": [ + "capability_contract_root_or_new_entry" + ], + "capability_contract_id": "confirmed_receivables_as_of_date", + "capability_contract_reason": [ + "debug_capability_id_matched_contract" + ], + "truth_gate_contract_status": "full_confirmed", + "carryover_eligibility": "root_only" + }, + "transition_contract_id": "T1", + "capability_contract_id": "confirmed_receivables_as_of_date", + "truth_gate_contract_status": "full_confirmed", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_receivables_as_of_date", + "transition_contract_id": "T1", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_receivables_as_of_date", + "transition_contract_id": "T1", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + }, + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "answer_shape": "confirmed_factual", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T1", + "transition_title": "Root Query Entry", + "application_status": "applied", + "declared_carryover_depth": "none", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "none", + "required_prior_state": [ + "living_mode_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "create_root_frame_state", + "clear_selected_object_frame_state", + "create_coverage_gate_state" + ], + "forbidden_carryover": [ + "stale_focus_object", + "stale_object_intent", + "implicit_followup_reuse" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "create", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T1", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T1", + "transition_title": "Root Query Entry", + "application_status": "applied", + "declared_carryover_depth": "none", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "none", + "required_prior_state": [ + "living_mode_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "create_root_frame_state", + "clear_selected_object_frame_state", + "create_coverage_gate_state" + ], + "forbidden_carryover": [ + "stale_focus_object", + "stale_object_intent", + "implicit_followup_reuse" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "create", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T1", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "state_transition_id": "T1", + "state_transition_status": "applied", + "effective_carryover_depth": "none", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_receivables_as_of_date", + "capability_contract_id": "confirmed_receivables_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T1", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "counterparty_receivables_snapshot", + "answer_object_shape": "receivables_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T1", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_receivables_as_of_date", + "capability_contract_id": "confirmed_receivables_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T1", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "counterparty_receivables_snapshot", + "answer_object_shape": "receivables_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T1", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + }, + "capability_binding_status": "bound", + "capability_binding_action": "allow", + "capability_binding_violations": [], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "allow", + "original_reply_type": "factual", + "guarded_reply_type": "factual", + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T1", + "capability_contract_root_or_new_entry", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "receivables_snapshot_bridge_signal_detected", + "confirmed_balance_exact_receivables_intent" + ] + } + } + }, + { + "message_id": "msg-mNrmV5Gd9r", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "а мы кому", + "reply_type": null, + "created_at": "2026-04-19T15:46:30.060Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-LuqE-5rdpY", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Коротко: подтвержденный долг к оплате на 19.04.2026 — **4.584.066,11** ₽.\nЭто подтвержденный срез обязательств к оплате, а не эвристический shortlist.\n\nЧто учтено\n- Дата среза: 19.04.2026.\n- Контур: обязательства по счетам 60/76.\n- В срез могут входить обязательства, возникшие до периода, если они оставались открытыми на дату среза.\n\nСводка\n- Строк в выборке: **10**.\n- Контрагентов с подтвержденным остатком к оплате: **7**.\n\nКатегории обязательств\n- поставщики/подрядчики: **5**.\n- банки/кредиты: **0**.\n- налоги/госорганы: **2**.\n- прочие: **0**.\n\nПодтвержденные позиции к оплате\n1. Комитет государственных услуг г. Москвы | категория: налоги/госорганы | остаток: **3.677.454,14** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), налог/госорган в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату | source refs: Финансовое обеспечение заявки\n\n2. ГКУ | категория: поставщики/подрядчики | остаток: **773.953,04** ₽ | операций: **2** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: ГКУ | документ: Остатки на дату | source refs: Финансовое обеспечение заявки; Финансовое обеспечение контракта\n\n3. Финансовое обеспечение заявки | категория: налоги/госорганы | остаток: **115.185,00** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), налог/госорган в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату\n\n4. Авант мебель, ООО | категория: поставщики/подрядчики | остаток: **7.271,20** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **60**, коммерческий контрагент в аналитике | договор: Договор АМ-2/15 от 22.01.15 | документ: Остатки на дату | source refs: Поступление товаров и услуг **00000000047** от 24.02.2015 12:03:34\n\n5. Держава АКБ, ПАО | категория: поставщики/подрядчики | остаток: **6.200,00** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: Договор № БГ 155822/2017 от 08.11.17 заявка **145822** | документ: Остатки на дату | source refs: Поступление товаров и услуг **00000000036** от 14.11.2017 0:00:00\n\n6. Скартел, ООО | категория: поставщики/подрядчики | остаток: **3.173,23** ₽ | операций: **3** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **76** (прочие расчеты), коммерческий контрагент в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату | source refs: Лицевой счет абонента № **1025043208**; Поступление товаров и услуг **00000000009** от 31.08.2022 12:00:00\n\n7. КОМПАНИЯ СИМПЛ, ООО | категория: поставщики/подрядчики | остаток: **829,50** ₽ | операций: **1** | последнее движение: 2026-04-19T23:59:59Z | основание: участие счета **60**, коммерческий контрагент в аналитике | договор: ООО \\Альтернатива Плюс\\ | документ: Остатки на дату | source refs: счет № SL11119332716 от 06.11.2019; Поступление товаров и услуг **00000000116** от 08.11.2019 12:00:02", + "reply_type": "factual", + "created_at": "2026-04-19T15:46:45.097Z", + "trace_id": "address-_sp2YxeAOd", + "debug": { + "trace_id": "address-_sp2YxeAOd", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "none", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "grounded", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "high", + "query_shape": "OBJECT_LOOKUP", + "query_shape_confidence": "medium", + "detected_intent": "payables_confirmed_as_of_date", + "detected_intent_confidence": "low", + "extracted_filters": { + "sort": "period_desc", + "limit": 20, + "as_of_date": "2026-04-19" + }, + "missing_required_filters": [], + "selected_recipe": "address_payables_confirmed_as_of_date_v1", + "mcp_call_status_legacy": "matched_non_empty", + "account_scope_mode": "strict", + "account_scope_fallback_applied": false, + "anchor_type": "unknown", + "anchor_value_raw": null, + "anchor_value_resolved": null, + "resolver_confidence": "low", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "matched_non_empty", + "rows_fetched": 10, + "raw_rows_received": 10, + "rows_after_account_scope": 10, + "rows_after_recipe_filter": 10, + "rows_materialized": 10, + "rows_matched": 10, + "raw_row_keys_sample": [ + "Период", + "Регистратор", + "СчетДт", + "СчетКт", + "Сумма", + "СубконтоДт1", + "СубконтоДт2", + "СубконтоДт3", + "СубконтоКт1", + "СубконтоКт2", + "СубконтоКт3", + "Организация", + "Period", + "Registrator", + "AccountKt", + "Amount" + ], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": null, + "response_type": "FACTUAL_LIST", + "requested_result_mode": "confirmed_balance", + "result_mode": "confirmed_balance", + "evidence_strength": "strong", + "balance_confirmed": true, + "as_of_date_basis": "implicit_current_snapshot", + "capability_id": "confirmed_payables_as_of_date", + "capability_layer": "compute", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "payables_confirmed_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_payables_confirmed_as_of_date_v1" + ], + "route_expectation_expected_requested_result_modes": [ + "confirmed_balance" + ], + "route_expectation_expected_result_modes": [ + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": true, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "Z0h8KCBnKgP6sy", + "llm_decomposition_effective_message": "кто является контрагентом для текущей компании?", + "llm_decomposition_reason": "normalized_fragment_applied", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "а мы кому", + "canonical_message": "кто является контрагентом для текущей компании?", + "mode": "address_query", + "mode_confidence": "high", + "query_shape": "OBJECT_LOOKUP", + "query_shape_confidence": "medium", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "implicit_current", + "date_basis_hint": "implicit_current_snapshot", + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "aggregation_profile": "list_lookup" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "а мы кому", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "address_query", + "address_mode_confidence": "high", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": false, + "followup_semantic_override_to_deep_allowed": false + }, + "followup_context_detected": true, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "а мы кому", + "effective_message": "кто является контрагентом для текущей компании?", + "decision": "continue_previous", + "decision_reasons": [ + "followup_context_detected", + "effective_message_rewritten_by_predecompose" + ], + "followup_context_applied": true, + "previous_intent": "receivables_confirmed_as_of_date", + "target_intent": "payables_confirmed_as_of_date", + "intent_selection_mode": "carry_previous_intent", + "anchor_type": "unknown", + "anchor_value": null, + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": false, + "reason": null, + "initial_limited_category": null, + "retry_message": null, + "retry_used_followup_context": false, + "retry_result_category": null + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "Z0h8KCBnKgP6sy", + "prompt_version": "normalizer_v2_0_2", + "applied": true, + "effective_message": "кто является контрагентом для текущей компании?" + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T2", + "transition_contract_title": "Root Follow-Up With Date Or Scope Change", + "transition_contract_reason": [ + "root_followup_continue_previous" + ], + "capability_contract_id": "confirmed_payables_as_of_date", + "capability_contract_reason": [ + "debug_capability_id_matched_contract" + ], + "truth_gate_contract_status": "full_confirmed", + "carryover_eligibility": "root_only" + }, + "transition_contract_id": "T2", + "capability_contract_id": "confirmed_payables_as_of_date", + "truth_gate_contract_status": "full_confirmed", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_payables_as_of_date", + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_payables_as_of_date", + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + }, + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "answer_shape": "confirmed_factual", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "state_transition_id": "T2", + "state_transition_status": "applied", + "effective_carryover_depth": "root_only", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_payables_as_of_date", + "capability_contract_id": "confirmed_payables_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T2", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "counterparty_payables_snapshot", + "answer_object_shape": "payables_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_payables_as_of_date", + "capability_contract_id": "confirmed_payables_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T2", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "counterparty_payables_snapshot", + "answer_object_shape": "payables_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + }, + "capability_binding_status": "bound", + "capability_binding_action": "allow", + "capability_binding_violations": [], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "allow", + "original_reply_type": "factual", + "guarded_reply_type": "factual", + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "object_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "address_followup_context_applied", + "confirmed_balance_exact_payables_intent" + ] + } + } + }, + { + "message_id": "msg-AQQ2mLZrBk", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "какиек остатки на складе на сегодня", + "reply_type": null, + "created_at": "2026-04-19T15:47:57.713Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-_4UcKjZLGt", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Нужно уточнить организацию, чтобы не смешивать компании в одном ответе.\nСейчас в доступном контуре вижу такие организации:\n- ООО Альтернатива Плюс\n- ООО Лайсвуд\n- РАЙМ\nМожешь ответить просто названием компании, и я продолжу этот же запрос.", + "reply_type": "partial_coverage", + "created_at": "2026-04-19T15:48:08.327Z", + "trace_id": "address-Nm7gQ3Pf4d", + "debug": { + "trace_id": "address-Nm7gQ3Pf4d", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "partial", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "partial", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "high", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "detected_intent": "inventory_on_hand_as_of_date", + "detected_intent_confidence": "medium", + "extracted_filters": { + "sort": "period_desc", + "as_of_date": "2026-04-19" + }, + "missing_required_filters": [ + "organization" + ], + "selected_recipe": null, + "mcp_call_status_legacy": "skipped", + "account_scope_mode": "strict", + "account_scope_fallback_applied": false, + "anchor_type": null, + "anchor_value_raw": null, + "anchor_value_resolved": null, + "resolver_confidence": null, + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "skipped", + "rows_fetched": 0, + "raw_rows_received": 0, + "rows_after_account_scope": 0, + "rows_after_recipe_filter": 0, + "rows_materialized": 0, + "rows_matched": 0, + "raw_row_keys_sample": [], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": "missing_anchor", + "organization_candidates": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "response_type": "LIMITED_WITH_REASON", + "requested_result_mode": "confirmed_balance", + "result_mode": "confirmed_balance", + "evidence_strength": "weak", + "balance_confirmed": false, + "as_of_date_basis": "implicit_current_snapshot", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_layer": "compute", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "inventory_on_hand_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_inventory_on_hand_as_of_date_v1" + ], + "route_expectation_expected_requested_result_modes": [ + "confirmed_balance" + ], + "route_expectation_expected_result_modes": [ + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": true, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "PDDPGykeGec8Zw", + "llm_decomposition_effective_message": "покажи остатки на складе на текущую дату", + "llm_decomposition_reason": "normalized_fragment_applied", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "какиек остатки на складе на сегодня", + "canonical_message": "покажи остатки на складе на текущую дату", + "mode": "address_query", + "mode_confidence": "high", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "inventory_on_hand_as_of_date", + "intent_confidence": "medium", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "as_of", + "period_from": null, + "period_to": null, + "as_of_date": "2026-04-19", + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "implicit_self_scope", + "anchor_kind": "self_scope", + "anchor_value": null, + "date_scope_kind": "implicit_current", + "date_basis_hint": "implicit_current_snapshot", + "self_scope_detected": true, + "selected_object_scope_detected": false + }, + "aggregation_profile": "unknown" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "какиек остатки на складе на сегодня", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "address_query", + "address_mode_confidence": "high", + "address_intent": "inventory_on_hand_as_of_date", + "address_intent_confidence": "medium", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": true, + "followup_semantic_override_to_deep_allowed": false + }, + "followup_context_detected": false, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "какиек остатки на складе на сегодня", + "effective_message": "покажи остатки на складе на текущую дату", + "decision": "new_topic", + "decision_reasons": [ + "effective_message_rewritten_by_predecompose", + "llm_contract_intent_available" + ], + "followup_context_applied": false, + "previous_intent": null, + "target_intent": "inventory_on_hand_as_of_date", + "intent_selection_mode": null, + "anchor_type": null, + "anchor_value": null, + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": true, + "reason": "limited_result_retry_with_raw_message", + "initial_limited_category": "missing_anchor", + "retry_message": "какиек остатки на складе на сегодня", + "retry_used_followup_context": false, + "retry_result_category": "missing_anchor" + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "PDDPGykeGec8Zw", + "prompt_version": "normalizer_v2_0_2", + "applied": true, + "effective_message": "покажи остатки на складе на текущую дату" + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T7", + "transition_contract_title": "Clarification Continuation", + "transition_contract_reason": [ + "missing_anchor_or_filter_requires_clarification" + ], + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_reason": [ + "debug_capability_id_matched_contract" + ], + "truth_gate_contract_status": "blocked_missing_anchor", + "carryover_eligibility": "none" + }, + "transition_contract_id": "T7", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "truth_gate_contract_status": "blocked_missing_anchor", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "blocked", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "clarification_required", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ], + "source_truth_gate_status": "blocked_missing_anchor", + "blocked_or_limited_explanation": "required_anchor_missing" + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "clarification_required", + "reply_type": "partial_coverage", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "transition_contract_id": "T7", + "may_state_confirmed_facts": false, + "must_include_limitation": true, + "may_power_followup": false, + "required_sections": [ + "clarifying_question", + "missing_anchors" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "blocked", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "clarification_required", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ], + "source_truth_gate_status": "blocked_missing_anchor", + "blocked_or_limited_explanation": "required_anchor_missing" + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "clarification_required", + "reply_type": "partial_coverage", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "transition_contract_id": "T7", + "may_state_confirmed_facts": false, + "must_include_limitation": true, + "may_power_followup": false, + "required_sections": [ + "clarifying_question", + "missing_anchors" + ], + "downgrade_only": true + }, + "truth_mode": "clarification_required", + "carryover_eligibility": "none", + "answer_shape": "clarification_required", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T7", + "transition_title": "Clarification Continuation", + "application_status": "clarification_required", + "declared_carryover_depth": "full", + "truth_gate_carryover_depth": "none", + "effective_carryover_depth": "full", + "required_prior_state": [ + "clarification_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "resume_target_route", + "update_or_clear_clarification_state" + ], + "forbidden_carryover": [ + "forget_suspended_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "preserve", + "selected_object_frame_state": "preserve", + "meta_frame_state": "none", + "clarification_state": "update", + "coverage_gate_state": "create", + "answer_context_state": "none" + }, + "coverage_gate_state": { + "coverage_status": "blocked", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "clarification_required", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "reason_codes": [ + "transition_status_clarification_required", + "transition_T7", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T7", + "transition_title": "Clarification Continuation", + "application_status": "clarification_required", + "declared_carryover_depth": "full", + "truth_gate_carryover_depth": "none", + "effective_carryover_depth": "full", + "required_prior_state": [ + "clarification_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "resume_target_route", + "update_or_clear_clarification_state" + ], + "forbidden_carryover": [ + "forget_suspended_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "preserve", + "selected_object_frame_state": "preserve", + "meta_frame_state": "none", + "clarification_state": "update", + "coverage_gate_state": "create", + "answer_context_state": "none" + }, + "coverage_gate_state": { + "coverage_status": "blocked", + "evidence_grade": "weak", + "grounding_status": "partial", + "truth_mode": "clarification_required", + "carryover_eligibility": "none", + "reason_codes": [ + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "reason_codes": [ + "transition_status_clarification_required", + "transition_T7", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "state_transition_id": "T7", + "state_transition_status": "clarification_required", + "effective_carryover_depth": "full", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "binding_status": "bound_with_limits", + "binding_action": "limit", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T7", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "item_list_with_quantity_cost_warehouse_organization", + "answer_object_shape": "inventory_stock_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound_with_limits", + "binding_action_limit", + "transition_status_clarification_required", + "transition_T7", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "binding_status": "bound_with_limits", + "binding_action": "limit", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T7", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "as_of_date" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "item_list_with_quantity_cost_warehouse_organization", + "answer_object_shape": "inventory_stock_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound_with_limits", + "binding_action_limit", + "transition_status_clarification_required", + "transition_T7", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response" + ] + }, + "capability_binding_status": "bound_with_limits", + "capability_binding_action": "limit", + "capability_binding_violations": [], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "limit", + "original_reply_type": "partial_coverage", + "guarded_reply_type": "partial_coverage", + "reason_codes": [ + "binding_status_bound_with_limits", + "binding_action_limit", + "transition_status_clarification_required", + "transition_T7", + "missing_anchor_or_filter_requires_clarification", + "debug_capability_id_matched_contract", + "truth_gate_blocked_missing_anchor", + "truth_mode_clarification_required", + "missing_filter_organization", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "shape_not_detected", + "inventory_on_hand_colloquial_bridge_signal_detected", + "organization_candidates_from_scope_context", + "organization_clarification_required", + "multiple_known_organizations_detected", + "exact_inventory_mode_limited_response", + "capability_binding_guard_limited_reply_type" + ] + } + } + }, + { + "message_id": "msg-oUccNUjkHI", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "альтернатива", + "reply_type": null, + "created_at": "2026-04-19T15:48:17.564Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-8j-yLKFQxv", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "На 19.04.2026 на складе подтверждено 11 позиций с остатком на 716.418,33 ₽.\n\nПозиции:\n1. Модуль прямоугольый 1400*110*750 | склад: Основной склад | количество: 22,000 | сумма: 148.261,67 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n2. Конструкция трансформер рабочей станции 1300*900*2000 | склад: Основной склад | количество: 3,000 | сумма: 498.472,50 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n3. Диван трехместный | склад: Основной склад | количество: 1,000 | сумма: 34.490,00 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n4. Кресло орион | склад: Основной склад | количество: 1,000 | сумма: 13.490,00 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n5. Зеркало для инвалидов поворотное травмобезопасное | склад: Основной склад | количество: 1,000 | сумма: 7.250,00 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n6. Пуф арий | склад: Основной склад | количество: 1,000 | сумма: 6.490,00 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n7. Столешница 600*3050*26 дуб ниагара | склад: Основной склад | количество: 1,000 | сумма: 3.724,17 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n8. Столешница 600*3050*26 альмандин | склад: Основной склад | количество: 1,000 | сумма: 3.075,00 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n9. Четки Пост (84*117) | склад: Основной склад | количество: 1,000 | сумма: 833,33 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n10. Кромка с клеем 33 альмандин 137 м | склад: Основной склад | количество: 1,000 | сумма: 165,83 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n11. Кромка с клеем 33 дуб ниагара 137 м | склад: Основной склад | количество: 1,000 | сумма: 165,83 ₽ | организация: ООО \\Альтернатива Плюс\\ | последняя дата: 19.04.2026\n\nСводка:\n- Дата среза: 19.04.2026.\n- Позиции с остатком: 11.\n- Уникальных товаров: 11.\n- Уникальных складов: 1.\n- Суммарное количество: 34,000.", + "reply_type": "factual", + "created_at": "2026-04-19T15:48:30.785Z", + "trace_id": "address-wla5M3VuP8", + "debug": { + "trace_id": "address-wla5M3VuP8", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "none", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "grounded", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "medium", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "detected_intent": "inventory_on_hand_as_of_date", + "detected_intent_confidence": "low", + "extracted_filters": { + "sort": "period_desc", + "as_of_date": "2026-04-19", + "organization": "ООО Альтернатива Плюс" + }, + "missing_required_filters": [], + "selected_recipe": "address_inventory_on_hand_as_of_date_v1", + "mcp_call_status_legacy": "matched_non_empty", + "account_scope_mode": "strict", + "account_scope_fallback_applied": false, + "anchor_type": "organization", + "anchor_value_raw": "ООО Альтернатива Плюс", + "anchor_value_resolved": "ООО \\Альтернатива Плюс\\", + "resolver_confidence": "medium", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "matched_non_empty", + "rows_fetched": 11, + "raw_rows_received": 11, + "rows_after_account_scope": 11, + "rows_after_recipe_filter": 11, + "rows_materialized": 11, + "rows_matched": 11, + "raw_row_keys_sample": [ + "Период", + "Регистратор", + "СчетДт", + "СчетКт", + "Сумма", + "Номенклатура", + "Склад", + "Организация", + "Количество", + "Period", + "Registrator", + "AccountDt", + "Amount" + ], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": null, + "response_type": "FACTUAL_LIST", + "requested_result_mode": "confirmed_balance", + "result_mode": "confirmed_balance", + "evidence_strength": "strong", + "balance_confirmed": true, + "as_of_date_basis": "implicit_current_snapshot", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_layer": "compute", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "inventory_on_hand_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_inventory_on_hand_as_of_date_v1" + ], + "route_expectation_expected_requested_result_modes": [ + "confirmed_balance" + ], + "route_expectation_expected_result_modes": [ + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": false, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "0tFeYexpYk4DoU", + "llm_decomposition_effective_message": "альтернатива", + "llm_decomposition_reason": "followup_raw_message_preferred_over_llm_rewrite", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "альтернатива", + "canonical_message": "альтернатива", + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "UNKNOWN", + "query_shape_confidence": "low", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "none", + "anchor_kind": "none", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": false, + "selected_object_scope_detected": false + }, + "aggregation_profile": "unknown" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "альтернатива", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "followup_context_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "unsupported", + "address_mode_confidence": "low", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": false, + "data_retrieval_signal_detected": false, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [ + "unsupported_low_confidence_contract", + "rewrite_without_structured_gain" + ], + "semantic_route_arbitration": { + "supported_address_intent_detected": false, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": false, + "followup_semantic_override_to_deep_allowed": true + }, + "followup_context_detected": true, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "followup_context_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "альтернатива", + "effective_message": "альтернатива", + "decision": "continue_previous", + "decision_reasons": [ + "followup_context_detected" + ], + "followup_context_applied": true, + "previous_intent": "inventory_on_hand_as_of_date", + "target_intent": "inventory_on_hand_as_of_date", + "intent_selection_mode": "carry_previous_intent", + "anchor_type": "organization", + "anchor_value": "ООО Альтернатива Плюс", + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": false, + "reason": null, + "initial_limited_category": null, + "retry_message": null, + "retry_used_followup_context": false, + "retry_result_category": null + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "0tFeYexpYk4DoU", + "prompt_version": "normalizer_v2_0_2", + "applied": false, + "effective_message": "альтернатива" + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_active_organization": "ООО Альтернатива Плюс", + "address_root_frame_context": { + "root_intent": "inventory_on_hand_as_of_date", + "current_frame_kind": "inventory_root", + "organization": "ООО Альтернатива Плюс", + "as_of_date": "2026-04-19", + "period_from": null, + "period_to": null + }, + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T2", + "transition_contract_title": "Root Follow-Up With Date Or Scope Change", + "transition_contract_reason": [ + "root_followup_continue_previous" + ], + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_reason": [ + "debug_capability_id_matched_contract" + ], + "truth_gate_contract_status": "full_confirmed", + "carryover_eligibility": "root_only" + }, + "transition_contract_id": "T2", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "truth_gate_contract_status": "full_confirmed", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + }, + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "answer_shape": "confirmed_factual", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "state_transition_id": "T2", + "state_transition_status": "applied", + "effective_carryover_depth": "root_only", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T2", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "as_of_date", + "organization" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "item_list_with_quantity_cost_warehouse_organization", + "answer_object_shape": "inventory_stock_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "confirmed_inventory_on_hand_as_of_date", + "capability_contract_id": "confirmed_inventory_on_hand_as_of_date", + "binding_status": "bound", + "binding_action": "allow", + "runtime_lane_expected": "address_exact", + "runtime_lane_observed": "address_exact", + "execution_adapter": "AddressQueryService", + "transition_id": "T2", + "transition_allowed": true, + "required_anchors": [], + "provided_anchors": [ + "sort", + "as_of_date", + "organization" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": "item_list_with_quantity_cost_warehouse_organization", + "answer_object_shape": "inventory_stock_snapshot", + "truth_gate_behavior": "partial_or_blocked_if_evidence_insufficient", + "truth_fallback_allowed": true, + "answer_shape_compatible": true, + "violations": [], + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + }, + "capability_binding_status": "bound", + "capability_binding_action": "allow", + "capability_binding_violations": [], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "allow", + "original_reply_type": "factual", + "guarded_reply_type": "factual", + "reason_codes": [ + "binding_status_bound", + "binding_action_allow", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_matched_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "shape_not_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_cleared_as_organization_scope_alias", + "address_followup_context_applied", + "confirmed_balance_exact_inventory_intent" + ] + } + } + }, + { + "message_id": "msg-affnHOoC0I", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "покажи документы по чепурнову", + "reply_type": null, + "created_at": "2026-04-19T15:50:06.644Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-db4ft8FU6c", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Контрагент: Чепурнов П.Д. Д. Найдено документов: 1.\nКонтрагент: Чепурнов П.Д. Д.\n1. 2022-01-20T12:00:03Z | Поступление на расчетный счет 00000000001 от 20.01.2022 12:00:03 | 0 / 0 | 890660 | аналитика: Чепурнов П.Д.; Договор № 11/1 от 25.11.2020 г.", + "reply_type": "factual", + "created_at": "2026-04-19T15:50:19.730Z", + "trace_id": "address-GUrN4cdH9l", + "debug": { + "trace_id": "address-GUrN4cdH9l", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "none", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "grounded", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "high", + "query_shape": "DOCUMENT_LIST", + "query_shape_confidence": "medium", + "detected_intent": "list_documents_by_counterparty", + "detected_intent_confidence": "medium", + "extracted_filters": { + "sort": "period_desc", + "limit": 20, + "counterparty": "Чепурнов П.Д.", + "organization": "ООО Альтернатива Плюс" + }, + "missing_required_filters": [], + "selected_recipe": "address_documents_by_counterparty_v1", + "mcp_call_status_legacy": "matched_non_empty", + "account_scope_mode": "preferred", + "account_scope_fallback_applied": false, + "anchor_type": "counterparty", + "anchor_value_raw": "чепурнов", + "anchor_value_resolved": "Чепурнов П.Д.", + "resolver_confidence": "medium", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "matched_non_empty", + "rows_fetched": 1000, + "raw_rows_received": 1000, + "rows_after_account_scope": 124, + "rows_after_recipe_filter": 1, + "rows_materialized": 124, + "rows_matched": 1, + "raw_row_keys_sample": [ + "Период", + "Регистратор", + "СчетДт", + "СчетКт", + "Сумма", + "Контрагент", + "Договор", + "Period", + "Registrator", + "Amount" + ], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": null, + "response_type": "FACTUAL_LIST", + "as_of_date_basis": "implicit_current_snapshot", + "capability_id": "documents_drilldown", + "capability_layer": "navigation", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "drilldown_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_documents_by_counterparty_v1" + ], + "route_expectation_expected_requested_result_modes": [], + "route_expectation_expected_result_modes": [ + "heuristic_candidates", + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": false, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "UlXZTHISmL56Ec", + "llm_decomposition_effective_message": "покажи документы по чепурнову", + "llm_decomposition_reason": "normalized_fragment_rejected_intent_drop", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "покажи документы по чепурнову", + "canonical_message": "покажи документы по чепурнову", + "mode": "address_query", + "mode_confidence": "high", + "query_shape": "DOCUMENT_LIST", + "query_shape_confidence": "medium", + "intent": "list_documents_by_counterparty", + "intent_confidence": "medium", + "entities": { + "account": null, + "counterparty": "чепурнов", + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "explicit_anchor", + "anchor_kind": "counterparty", + "anchor_value": "чепурнов", + "date_scope_kind": "implicit_current", + "date_basis_hint": "implicit_current_snapshot", + "self_scope_detected": false, + "selected_object_scope_detected": false + }, + "aggregation_profile": "list_lookup" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "покажи документы по чепурнову", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "address_query", + "address_mode_confidence": "high", + "address_intent": "list_documents_by_counterparty", + "address_intent_confidence": "medium", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": true, + "semantic_reason_codes": [], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": false, + "exact_address_intent_protected_from_semantic_deep_hint": true, + "followup_semantic_override_to_deep_allowed": false + }, + "followup_context_detected": true, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_mode_classifier_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "покажи документы по чепурнову", + "effective_message": "покажи документы по чепурнову", + "decision": "continue_previous", + "decision_reasons": [ + "followup_context_detected", + "llm_contract_intent_available" + ], + "followup_context_applied": true, + "previous_intent": "inventory_on_hand_as_of_date", + "target_intent": "list_documents_by_counterparty", + "intent_selection_mode": "carry_previous_intent", + "anchor_type": "organization", + "anchor_value": "ООО \\Альтернатива Плюс\\", + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": false, + "reason": null, + "initial_limited_category": null, + "retry_message": null, + "retry_used_followup_context": false, + "retry_result_category": null + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "UlXZTHISmL56Ec", + "prompt_version": "normalizer_v2_0_2", + "applied": false, + "effective_message": "покажи документы по чепурнову" + }, + "address_followup_offer": { + "enabled": true, + "source_intent": "list_documents_by_counterparty", + "anchor_type": "counterparty", + "anchor_value": "Чепурнов П.Д.", + "suggested_intents": [ + "bank_operations_by_counterparty", + "list_contracts_by_counterparty" + ] + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_active_organization": "ООО Альтернатива Плюс", + "address_root_frame_context": { + "root_intent": "inventory_on_hand_as_of_date", + "current_frame_kind": "inventory_root", + "organization": "ООО Альтернатива Плюс", + "as_of_date": "2026-04-19", + "period_from": null, + "period_to": null + }, + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T2", + "transition_contract_title": "Root Follow-Up With Date Or Scope Change", + "transition_contract_reason": [ + "root_followup_continue_previous" + ], + "capability_contract_id": null, + "capability_contract_reason": [ + "debug_capability_id_has_no_contract" + ], + "truth_gate_contract_status": "full_confirmed", + "carryover_eligibility": "root_only" + }, + "transition_contract_id": "T2", + "capability_contract_id": null, + "truth_gate_contract_status": "full_confirmed", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": null, + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": null, + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + }, + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "answer_shape": "confirmed_factual", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "state_transition_id": "T2", + "state_transition_status": "applied", + "effective_carryover_depth": "root_only", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "documents_drilldown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": "T2", + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "counterparty", + "organization" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "documents_drilldown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": "T2", + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "counterparty", + "organization" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + }, + "capability_binding_status": "contract_missing", + "capability_binding_action": "observe_only", + "capability_binding_violations": [ + "capability_contract_missing" + ], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "observe_only", + "original_reply_type": "factual", + "guarded_reply_type": "factual", + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "address_action_detected", + "address_entity_detected", + "document_list_signal_detected", + "documents_by_counterparty_signal_detected", + "organization_from_followup_context", + "address_followup_context_applied" + ] + } + } + }, + { + "message_id": "msg-0eCFUR-qPh", + "session_id": "asst-HFD9N5qwZM", + "role": "user", + "text": "какой оборот был свк", + "reply_type": null, + "created_at": "2026-04-19T15:58:04.532Z", + "trace_id": null, + "debug": null + }, + { + "message_id": "msg-9Y0cF1OIYd", + "session_id": "asst-HFD9N5qwZM", + "role": "assistant", + "text": "Контрагент: Чепурнов П.Д. Д. Найдено документов: 1.\nКонтрагент: Чепурнов П.Д. Д.\n1. 2022-01-20T12:00:03Z | Поступление на расчетный счет 00000000001 от 20.01.2022 12:00:03 | 0 / 0 | 890660 | аналитика: Чепурнов П.Д.; Договор № 11/1 от 25.11.2020 г.", + "reply_type": "factual", + "created_at": "2026-04-19T15:58:20.316Z", + "trace_id": "address-Fq1cRhIMFu", + "debug": { + "trace_id": "address-Fq1cRhIMFu", + "prompt_version": "address_query_runtime_v1", + "schema_version": "address_query_runtime_v1", + "fallback_type": "none", + "route_summary": null, + "fragments": [], + "requirements_extracted": [], + "coverage_report": { + "requirements_total": 0, + "requirements_covered": 0, + "requirements_uncovered": [], + "requirements_partially_covered": [], + "clarification_needed_for": [], + "out_of_scope_requirements": [] + }, + "routes": [], + "retrieval_status": [], + "retrieval_results": [], + "answer_grounding_check": { + "status": "grounded", + "route_subject_match": true, + "missing_requirements": [], + "reasons": [ + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ], + "why_included_summary": [], + "selection_reason_summary": [] + }, + "dropped_intent_segments": [], + "detected_mode": "address_query", + "detected_mode_confidence": "medium", + "query_shape": "AGGREGATE_LOOKUP", + "query_shape_confidence": "high", + "detected_intent": "list_documents_by_counterparty", + "detected_intent_confidence": "low", + "extracted_filters": { + "sort": "period_desc", + "limit": 20, + "organization": "ООО Альтернатива Плюс", + "counterparty": "Чепурнов П.Д." + }, + "missing_required_filters": [], + "selected_recipe": "address_documents_by_counterparty_v1", + "mcp_call_status_legacy": "matched_non_empty", + "account_scope_mode": "preferred", + "account_scope_fallback_applied": false, + "anchor_type": "counterparty", + "anchor_value_raw": "Чепурнов П.Д.", + "anchor_value_resolved": "Чепурнов П.Д.", + "resolver_confidence": "high", + "ambiguity_count": 0, + "match_failure_stage": "none", + "match_failure_reason": null, + "mcp_call_status": "matched_non_empty", + "rows_fetched": 1000, + "raw_rows_received": 1000, + "rows_after_account_scope": 124, + "rows_after_recipe_filter": 1, + "rows_materialized": 124, + "rows_matched": 1, + "raw_row_keys_sample": [ + "Период", + "Регистратор", + "СчетДт", + "СчетКт", + "Сумма", + "Контрагент", + "Договор", + "Period", + "Registrator", + "Amount" + ], + "materialization_drop_reason": "none", + "account_token_raw": null, + "account_token_normalized": null, + "account_scope_fields_checked": [ + "account_dt", + "account_kt", + "registrator", + "analytics" + ], + "account_scope_match_strategy": "account_code_regex_plus_alias_map_v1", + "account_scope_drop_reason": "not_applicable", + "runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS", + "limited_reason_category": null, + "response_type": "FACTUAL_LIST", + "capability_id": "documents_drilldown", + "capability_layer": "navigation", + "capability_route_mode": "exact", + "capability_route_enabled": true, + "capability_route_reason": "drilldown_route_enabled", + "shadow_route_status": "skipped", + "route_expectation_status": "matched", + "route_expectation_reason": "route_expectation_matched", + "route_expectation_expected_selected_recipes": [ + "address_documents_by_counterparty_v1" + ], + "route_expectation_expected_requested_result_modes": [], + "route_expectation_expected_result_modes": [ + "heuristic_candidates", + "confirmed_balance" + ], + "execution_lane": "address_query", + "llm_decomposition_applied": false, + "llm_decomposition_attempted": true, + "llm_provider_used": "local", + "llm_decomposition_trace_id": "8TNaiB-JfhqB5s", + "llm_decomposition_effective_message": "какой оборот был свк", + "llm_decomposition_reason": "followup_raw_message_preferred_over_llm_rewrite", + "llm_canonical_candidate_detected": true, + "llm_predecompose_contract": { + "schema_version": "address_llm_predecompose_contract_v1", + "source_message": "какой оборот был свк", + "canonical_message": "какой оборот был свк", + "mode": "unsupported", + "mode_confidence": "low", + "query_shape": "AGGREGATE_LOOKUP", + "query_shape_confidence": "high", + "intent": "unknown", + "intent_confidence": "low", + "entities": { + "account": null, + "counterparty": null, + "contract": null, + "document_type": null, + "document_ref": null, + "organization": null + }, + "period": { + "scope": "unspecified", + "period_from": null, + "period_to": null, + "as_of_date": null, + "has_explicit_period": false + }, + "semantics": { + "scope_kind": "none", + "anchor_kind": "none", + "anchor_value": null, + "date_scope_kind": "none", + "date_basis_hint": null, + "self_scope_detected": false, + "selected_object_scope_detected": false + }, + "aggregation_profile": "management_profile" + }, + "fallback_rule_hit": null, + "sanitized_user_message": "какой оборот был свк", + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_signal_detected", + "orchestration_contract_v1": { + "schema_version": "assistant_orchestration_contract_v1", + "hard_meta_mode": null, + "provider_execution": { + "schema_version": "assistant_provider_execution_contract_v1", + "policy_owner": "assistantProviderExecutionPolicy", + "provider_mode": "unknown", + "normalized_provider": null, + "use_mock": false, + "base_url_configured": false, + "llm_runtime_unavailable_detected": false, + "living_mode_forced_deep": false, + "living_mode_forced_reason": null, + "reason_codes": [ + "provider_unknown" + ] + }, + "address_mode": "unsupported", + "address_mode_confidence": "low", + "address_intent": "unknown", + "address_intent_confidence": "low", + "strong_data_signal_detected": true, + "data_retrieval_signal_detected": true, + "semantic_contract_valid": true, + "semantic_apply_canonical_recommended": false, + "semantic_reason_codes": [ + "unsupported_low_confidence_contract" + ], + "semantic_route_arbitration": { + "supported_address_intent_detected": true, + "strict_deep_investigation_bypass_allowed": false, + "semantic_deep_investigation_hint_detected": false, + "semantic_aggregate_shape_detected": true, + "exact_address_intent_protected_from_semantic_deep_hint": false, + "followup_semantic_override_to_deep_allowed": true + }, + "followup_context_detected": true, + "unsupported_address_intent_fallback_to_deep": false, + "deep_analysis_signal_fallback_to_deep": false, + "aggregate_analytics_signal_fallback_to_deep": false, + "deep_session_continuation_fallback_to_deep": false, + "answer_inspection_followup_over_grounded_answer": false, + "final_decision": { + "run_address_lane": true, + "tool_gate_decision": "run_address_lane", + "tool_gate_reason": "address_signal_detected", + "living_mode": "address_data", + "living_reason": "address_lane_triggered" + } + }, + "dialog_continuation_contract_v2": { + "schema_version": "address_dialog_continuation_contract_v2", + "source_message": "какой оборот был свк", + "effective_message": "какой оборот был свк", + "decision": "continue_previous", + "decision_reasons": [ + "followup_context_detected" + ], + "followup_context_applied": true, + "previous_intent": "list_documents_by_counterparty", + "target_intent": "list_documents_by_counterparty", + "intent_selection_mode": "carry_previous_intent", + "anchor_type": "counterparty", + "anchor_value": "Чепурнов П.Д.", + "implicit_continuation_signal": false + }, + "address_retry_audit": { + "attempted": false, + "reason": null, + "initial_limited_category": null, + "retry_message": null, + "retry_used_followup_context": false, + "retry_result_category": null + }, + "answer_structure_v11": null, + "investigation_state_snapshot": null, + "normalized": null, + "normalizer_output": { + "trace_id": "8TNaiB-JfhqB5s", + "prompt_version": "normalizer_v2_0_2", + "applied": false, + "effective_message": "какой оборот был свк" + }, + "address_followup_offer": { + "enabled": true, + "source_intent": "list_documents_by_counterparty", + "anchor_type": "counterparty", + "anchor_value": "Чепурнов П.Д.", + "suggested_intents": [ + "bank_operations_by_counterparty", + "list_contracts_by_counterparty" + ] + }, + "assistant_known_organizations": [ + "ООО Альтернатива Плюс", + "ООО Лайсвуд", + "РАЙМ" + ], + "assistant_active_organization": "ООО Альтернатива Плюс", + "assistant_runtime_contract_v1": { + "schema_version": "assistant_runtime_contracts_v1", + "transition_contract_id": "T2", + "transition_contract_title": "Root Follow-Up With Date Or Scope Change", + "transition_contract_reason": [ + "root_followup_continue_previous" + ], + "capability_contract_id": null, + "capability_contract_reason": [ + "debug_capability_id_has_no_contract" + ], + "truth_gate_contract_status": "full_confirmed", + "carryover_eligibility": "root_only" + }, + "transition_contract_id": "T2", + "capability_contract_id": null, + "truth_gate_contract_status": "full_confirmed", + "assistant_truth_answer_policy_v1": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "truth_gate": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": null, + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + } + }, + "coverage_gate_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ], + "source_truth_gate_status": "full_confirmed", + "blocked_or_limited_explanation": null + }, + "answer_shape_contract": { + "schema_version": "assistant_truth_answer_policy_runtime_v1", + "policy_owner": "assistantTruthAnswerPolicyRuntimeAdapter", + "answer_shape": "confirmed_factual", + "reply_type": "factual", + "capability_contract_id": null, + "transition_contract_id": "T2", + "may_state_confirmed_facts": true, + "must_include_limitation": false, + "may_power_followup": true, + "required_sections": [ + "direct_answer", + "evidence_basis" + ], + "downgrade_only": true + }, + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "answer_shape": "confirmed_factual", + "assistant_state_transition_v1": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "state_transition_contract": { + "schema_version": "assistant_state_transition_runtime_v1", + "state_owner": "assistantStateTransitionRuntimeAdapter", + "transition_id": "T2", + "transition_title": "Root Follow-Up With Date Or Scope Change", + "application_status": "applied", + "declared_carryover_depth": "root_only", + "truth_gate_carryover_depth": "root_only", + "effective_carryover_depth": "root_only", + "required_prior_state": [ + "root_frame_state" + ], + "expected_answer_mode": "confirmed", + "state_mutations": [ + "update_root_frame_state", + "run_exact_route", + "refresh_coverage_gate_state" + ], + "forbidden_carryover": [ + "incompatible_selected_object_route" + ], + "state_actions": { + "living_mode_state": "update", + "root_frame_state": "update", + "selected_object_frame_state": "clear", + "meta_frame_state": "clear", + "clarification_state": "clear", + "coverage_gate_state": "create", + "answer_context_state": "create" + }, + "coverage_gate_state": { + "coverage_status": "full", + "evidence_grade": "strong", + "grounding_status": "grounded", + "truth_mode": "confirmed", + "carryover_eligibility": "root_only", + "reason_codes": [ + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "reason_codes": [ + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "state_transition_id": "T2", + "state_transition_status": "applied", + "effective_carryover_depth": "root_only", + "assistant_capability_binding_v1": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "documents_drilldown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": "T2", + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "organization", + "counterparty" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "capability_binding_contract": { + "schema_version": "assistant_capability_runtime_binding_v1", + "binding_owner": "assistantCapabilityRuntimeBindingAdapter", + "capability_id": "documents_drilldown", + "capability_contract_id": null, + "binding_status": "contract_missing", + "binding_action": "observe_only", + "runtime_lane_expected": null, + "runtime_lane_observed": "address_exact", + "execution_adapter": null, + "transition_id": "T2", + "transition_allowed": false, + "required_anchors": [], + "provided_anchors": [ + "sort", + "limit", + "organization", + "counterparty" + ], + "missing_anchors": [], + "requires_focus_object": false, + "focus_object_binding_status": "not_required", + "result_shape": null, + "answer_object_shape": null, + "truth_gate_behavior": null, + "truth_fallback_allowed": null, + "answer_shape_compatible": false, + "violations": [ + "capability_contract_missing" + ], + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + }, + "capability_binding_status": "contract_missing", + "capability_binding_action": "observe_only", + "capability_binding_violations": [ + "capability_contract_missing" + ], + "capability_binding_response_guard": { + "schema_version": "assistant_capability_binding_response_guard_v1", + "guard_owner": "assistantCapabilityBindingResponseGuard", + "applied": false, + "action": "observe_only", + "original_reply_type": "factual", + "guarded_reply_type": "factual", + "reason_codes": [ + "binding_status_contract_missing", + "binding_action_observe_only", + "capability_contract_missing", + "transition_status_applied", + "transition_T2", + "root_followup_continue_previous", + "debug_capability_id_has_no_contract", + "truth_gate_full_confirmed", + "truth_mode_confirmed", + "route_expectation_matched", + "no_address_or_deep_signal", + "address_mode_from_followup_context", + "aggregate_signal_detected", + "intent_not_supported_in_v1", + "intent_from_followup_context", + "organization_from_followup_context", + "counterparty_from_followup_context", + "address_followup_context_applied" + ] + } + } + } + ], + "investigation_state": { + "schema_version": "investigation_state_v1", + "session_id": "asst-HFD9N5qwZM", + "status": "idle", + "turn_index": 0, + "updated_at": "2026-04-19T15:42:13.731Z", + "question_id": null, + "question_scope_id": null, + "scope_origin": null, + "focus": { + "domain": null, + "period": null, + "primary_accounts": [], + "active_query_subject": null + }, + "narrowing_status": "unknown", + "evidence_refs": [], + "open_uncertainties": [], + "last_answer_mode": null, + "followup_context": null, + "query_mode_hint": "direct_answer" + }, + "address_navigation_state": { + "schema_version": "address_navigation_state_v1", + "session_id": "asst-HFD9N5qwZM", + "updated_at": "2026-04-19T15:58:20.316Z", + "session_context": { + "active_result_set_id": "rs-msg-9Y0cF1OIYd", + "active_focus_object": { + "object_type": "counterparty", + "object_id": "counterparty:чепурнов п.д.", + "label": "Чепурнов П.Д.", + "provenance_result_set_id": "rs-msg-9Y0cF1OIYd", + "selected_at": "2026-04-19T15:58:20.316Z" + }, + "last_confirmed_route": "address_documents_by_counterparty_v1", + "date_scope": { + "as_of_date": "2026-04-19", + "period_from": null, + "period_to": null + }, + "organization_scope": "ООО Альтернатива Плюс" + }, + "result_sets": [ + { + "result_set_id": "rs-msg-65k6tTD6OM", + "type": "balance_snapshot", + "intent": "receivables_confirmed_as_of_date", + "route_id": "address_receivables_confirmed_as_of_date_v1", + "filters": { + "sort": "period_desc", + "limit": 20, + "as_of_date": "2026-04-19" + }, + "source_refs": [ + "address_receivables_confirmed_as_of_date_v1" + ], + "entity_refs": [ + { + "index": 1, + "entity_type": "counterparty", + "value": "Департамент капитального ремонта города Москвы." + }, + { + "index": 2, + "entity_type": "counterparty", + "value": "Комитет государственных услуг г. Москвы" + }, + { + "index": 3, + "entity_type": "counterparty", + "value": "ГКУ" + }, + { + "index": 4, + "entity_type": "counterparty", + "value": "Финансовое обеспечение заявки" + }, + { + "index": 5, + "entity_type": "counterparty", + "value": "Савва Офис Сервис" + }, + { + "index": 6, + "entity_type": "counterparty", + "value": "Держава АКБ, ПАО" + } + ], + "created_from_turn": 7, + "created_at": "2026-04-19T15:45:14.679Z" + }, + { + "result_set_id": "rs-msg-LuqE-5rdpY", + "type": "balance_snapshot", + "intent": "payables_confirmed_as_of_date", + "route_id": "address_payables_confirmed_as_of_date_v1", + "filters": { + "sort": "period_desc", + "limit": 20, + "as_of_date": "2026-04-19" + }, + "source_refs": [ + "address_payables_confirmed_as_of_date_v1" + ], + "entity_refs": [], + "created_from_turn": 9, + "created_at": "2026-04-19T15:46:45.097Z" + }, + { + "result_set_id": "rs-msg-_4UcKjZLGt", + "type": "inventory_snapshot", + "intent": "inventory_on_hand_as_of_date", + "route_id": null, + "filters": { + "sort": "period_desc", + "as_of_date": "2026-04-19" + }, + "source_refs": [], + "entity_refs": [], + "created_from_turn": 11, + "created_at": "2026-04-19T15:48:08.327Z" + }, + { + "result_set_id": "rs-msg-8j-yLKFQxv", + "type": "inventory_snapshot", + "intent": "inventory_on_hand_as_of_date", + "route_id": "address_inventory_on_hand_as_of_date_v1", + "filters": { + "sort": "period_desc", + "as_of_date": "2026-04-19", + "organization": "ООО Альтернатива Плюс" + }, + "source_refs": [ + "address_inventory_on_hand_as_of_date_v1" + ], + "entity_refs": [ + { + "index": 1, + "entity_type": "item", + "value": "Модуль прямоугольый 1400*110*750" + }, + { + "index": 2, + "entity_type": "item", + "value": "Конструкция трансформер рабочей станции 1300*900*2000" + }, + { + "index": 3, + "entity_type": "item", + "value": "Диван трехместный" + }, + { + "index": 4, + "entity_type": "item", + "value": "Кресло орион" + }, + { + "index": 5, + "entity_type": "item", + "value": "Зеркало для инвалидов поворотное травмобезопасное" + }, + { + "index": 6, + "entity_type": "item", + "value": "Пуф арий" + }, + { + "index": 7, + "entity_type": "item", + "value": "Столешница 600*3050*26 дуб ниагара" + }, + { + "index": 8, + "entity_type": "item", + "value": "Столешница 600*3050*26 альмандин" + }, + { + "index": 9, + "entity_type": "item", + "value": "Четки Пост (84*117)" + }, + { + "index": 10, + "entity_type": "item", + "value": "Кромка с клеем 33 альмандин 137 м" + }, + { + "index": 11, + "entity_type": "item", + "value": "Кромка с клеем 33 дуб ниагара 137 м" + } + ], + "created_from_turn": 13, + "created_at": "2026-04-19T15:48:30.785Z" + }, + { + "result_set_id": "rs-msg-db4ft8FU6c", + "type": "document_list", + "intent": "list_documents_by_counterparty", + "route_id": "address_documents_by_counterparty_v1", + "filters": { + "sort": "period_desc", + "limit": 20, + "counterparty": "Чепурнов П.Д.", + "organization": "ООО Альтернатива Плюс" + }, + "source_refs": [ + "address_documents_by_counterparty_v1" + ], + "entity_refs": [ + { + "index": 1, + "entity_type": "document_ref", + "value": "2022-01-20T12:00:03Z" + } + ], + "created_from_turn": 15, + "created_at": "2026-04-19T15:50:19.730Z" + }, + { + "result_set_id": "rs-msg-9Y0cF1OIYd", + "type": "document_list", + "intent": "list_documents_by_counterparty", + "route_id": "address_documents_by_counterparty_v1", + "filters": { + "sort": "period_desc", + "limit": 20, + "organization": "ООО Альтернатива Плюс", + "counterparty": "Чепурнов П.Д." + }, + "source_refs": [ + "address_documents_by_counterparty_v1" + ], + "entity_refs": [ + { + "index": 1, + "entity_type": "document_ref", + "value": "2022-01-20T12:00:03Z" + } + ], + "created_from_turn": 17, + "created_at": "2026-04-19T15:58:20.316Z" + } + ], + "navigation_history": [ + { + "event_id": "nav-VtSvUcEvqs", + "action": "open", + "source_result_set_id": null, + "target_object_id": null, + "derived_result_set_id": "rs-msg-65k6tTD6OM", + "turn_index": 7, + "created_at": "2026-04-19T15:45:14.679Z" + }, + { + "event_id": "nav-spp_0H2s-I", + "action": "refine", + "source_result_set_id": "rs-msg-65k6tTD6OM", + "target_object_id": null, + "derived_result_set_id": "rs-msg-LuqE-5rdpY", + "turn_index": 9, + "created_at": "2026-04-19T15:46:45.097Z" + }, + { + "event_id": "nav-tgTq3aUzYK", + "action": "open", + "source_result_set_id": "rs-msg-LuqE-5rdpY", + "target_object_id": null, + "derived_result_set_id": "rs-msg-_4UcKjZLGt", + "turn_index": 11, + "created_at": "2026-04-19T15:48:08.327Z" + }, + { + "event_id": "nav-yO-yZqUrgk", + "action": "drilldown", + "source_result_set_id": "rs-msg-_4UcKjZLGt", + "target_object_id": "organization:ооо \\альтернатива плюс\\", + "derived_result_set_id": "rs-msg-8j-yLKFQxv", + "turn_index": 13, + "created_at": "2026-04-19T15:48:30.785Z" + }, + { + "event_id": "nav-WygbRXXepc", + "action": "drilldown", + "source_result_set_id": "rs-msg-8j-yLKFQxv", + "target_object_id": "counterparty:чепурнов п.д.", + "derived_result_set_id": "rs-msg-db4ft8FU6c", + "turn_index": 15, + "created_at": "2026-04-19T15:50:19.730Z" + }, + { + "event_id": "nav-2hAjDVvN-q", + "action": "drilldown", + "source_result_set_id": "rs-msg-db4ft8FU6c", + "target_object_id": "counterparty:чепурнов п.д.", + "derived_result_set_id": "rs-msg-9Y0cF1OIYd", + "turn_index": 17, + "created_at": "2026-04-19T15:58:20.316Z" + } + ] + } + } +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_qwen_seed_20260420054242_gen-mo6rqcw8-kuswg6b.json b/llm_normalizer/data/eval_cases/assistant_autogen_qwen_seed_20260420054242_gen-mo6rqcw8-kuswg6b.json new file mode 100644 index 0000000..c5101f1 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_qwen_seed_20260420054242_gen-mo6rqcw8-kuswg6b.json @@ -0,0 +1,254 @@ +{ + "suite_id": "assistant_autogen_gen-mo6rqcw8-kuswg6b", + "suite_version": "0.1.0", + "schema_version": "assistant_autogen_suite_v0_1", + "generated_at": "2026-04-20T05:42:42.633Z", + "generation_id": "gen-mo6rqcw8-kuswg6b", + "mode": "qwen_seed", + "domain": null, + "scenario_count": 15, + "case_ids": [ + "AUTO-001", + "AUTO-002", + "AUTO-003", + "AUTO-004", + "AUTO-005", + "AUTO-006", + "AUTO-007", + "AUTO-008", + "AUTO-009", + "AUTO-010", + "AUTO-011", + "AUTO-012", + "AUTO-013", + "AUTO-014", + "AUTO-015" + ], + "cases": [ + { + "case_id": "AUTO-001", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас висит сальдо, которое уже больше месяца не менялось и выглядит как застывший долг?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-002", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас поставщики, которые давно отгружали, но оплаты так и нет — можно ли их считать просроченными или это просто задержка в документах?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-003", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех клиентов, по которым есть отгрузки, но денег с них не поступало уже больше 60 дней — какие из них вообще активны?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-004", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас есть оплаты, но нет закрытия счетов, и это выглядит как архивный кэш?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-005", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Кто из заказчиков давно не платил, но при этом по ним висят открытые договора — можно ли считать их активными или уже нужно смотреть на отключение?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-006", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас авансы, которые уже прошли 3 месяца после получения, но не закрыты ни документами, ни сверками?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-007", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи все контрагенты, по которым в 1С указано «договор активен», а оплаты и отгрузки — ноль за последние полгода" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-008", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким поставщикам у нас есть счета-фактуры, но документы об оплате не приходили?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-009", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "А может быть, они вообще висят?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-010", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие клиенты уже давно получали товары, но по ним нет актов сверки и счёт-фактур — возможно, это ошибка или просто пропущенные действия?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-011", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас есть документы по отгрузке, но оплаты не видно — может, деньги пришли, но не привязались?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-012", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех контрагентов с незакрытыми договорами и остатками в долгах свыше 100 тыс. — кто из них реально проблемный?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-013", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие поставщики у нас на текущий момент имеют несогласованные остатки, и где это может повлиять на отчётность?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-014", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас зависшие взаиморасчёты, когда документы есть, но оплаты нет — можно ли считать это технической ошибкой или уже ручная проверка нужна?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + }, + { + "case_id": "AUTO-015", + "scenario_tag": "qwen_seed_general", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам в 1С отображается активность, но при этом у них ноль поставок и оплат за год?" + } + ], + "expected_hints": { + "expected_reply_type": null, + "expected_degraded_to": null + } + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-EYyK1lOCNB.json b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-EYyK1lOCNB.json new file mode 100644 index 0000000..064023c --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-EYyK1lOCNB.json @@ -0,0 +1,190 @@ +{ + "suite_id": "assistant_autogen_runtime_job-EYyK1lOCNB", + "suite_version": "0.1.0", + "schema_version": "assistant_autogen_runtime_v0_1", + "scenario_count": 15, + "case_ids": [ + "AUTO-001", + "AUTO-002", + "AUTO-003", + "AUTO-004", + "AUTO-005", + "AUTO-006", + "AUTO-007", + "AUTO-008", + "AUTO-009", + "AUTO-010", + "AUTO-011", + "AUTO-012", + "AUTO-013", + "AUTO-014", + "AUTO-015" + ], + "cases": [ + { + "case_id": "AUTO-001", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас висит сальдо, которое уже больше месяца не менялось и выглядит как застывший долг?" + } + ] + }, + { + "case_id": "AUTO-002", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас поставщики, которые давно отгружали, но оплаты так и нет — можно ли их считать просроченными или это просто задержка в документах?" + } + ] + }, + { + "case_id": "AUTO-003", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех клиентов, по которым есть отгрузки, но денег с них не поступало уже больше 60 дней — какие из них вообще активны?" + } + ] + }, + { + "case_id": "AUTO-004", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас есть оплаты, но нет закрытия счетов, и это выглядит как архивный кэш?" + } + ] + }, + { + "case_id": "AUTO-005", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Кто из заказчиков давно не платил, но при этом по ним висят открытые договора — можно ли считать их активными или уже нужно смотреть на отключение?" + } + ] + }, + { + "case_id": "AUTO-006", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас авансы, которые уже прошли 3 месяца после получения, но не закрыты ни документами, ни сверками?" + } + ] + }, + { + "case_id": "AUTO-007", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи все контрагенты, по которым в 1С указано «договор активен», а оплаты и отгрузки — ноль за последние полгода" + } + ] + }, + { + "case_id": "AUTO-008", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким поставщикам у нас есть счета-фактуры, но документы об оплате не приходили?" + } + ] + }, + { + "case_id": "AUTO-009", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "А может быть, они вообще висят?" + } + ] + }, + { + "case_id": "AUTO-010", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие клиенты уже давно получали товары, но по ним нет актов сверки и счёт-фактур — возможно, это ошибка или просто пропущенные действия?" + } + ] + }, + { + "case_id": "AUTO-011", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас есть документы по отгрузке, но оплаты не видно — может, деньги пришли, но не привязались?" + } + ] + }, + { + "case_id": "AUTO-012", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех контрагентов с незакрытыми договорами и остатками в долгах свыше 100 тыс. — кто из них реально проблемный?" + } + ] + }, + { + "case_id": "AUTO-013", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие поставщики у нас на текущий момент имеют несогласованные остатки, и где это может повлиять на отчётность?" + } + ] + }, + { + "case_id": "AUTO-014", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас зависшие взаиморасчёты, когда документы есть, но оплаты нет — можно ли считать это технической ошибкой или уже ручная проверка нужна?" + } + ] + }, + { + "case_id": "AUTO-015", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам в 1С отображается активность, но при этом у них ноль поставок и оплат за год?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-l0db74IDVl.json b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-l0db74IDVl.json new file mode 100644 index 0000000..13bf56d --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-l0db74IDVl.json @@ -0,0 +1,190 @@ +{ + "suite_id": "assistant_autogen_runtime_job-l0db74IDVl", + "suite_version": "0.1.0", + "schema_version": "assistant_autogen_runtime_v0_1", + "scenario_count": 15, + "case_ids": [ + "AUTO-001", + "AUTO-002", + "AUTO-003", + "AUTO-004", + "AUTO-005", + "AUTO-006", + "AUTO-007", + "AUTO-008", + "AUTO-009", + "AUTO-010", + "AUTO-011", + "AUTO-012", + "AUTO-013", + "AUTO-014", + "AUTO-015" + ], + "cases": [ + { + "case_id": "AUTO-001", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас висит сальдо, которое уже больше месяца не менялось и выглядит как застывший долг?" + } + ] + }, + { + "case_id": "AUTO-002", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас поставщики, которые давно отгружали, но оплаты так и нет — можно ли их считать просроченными или это просто задержка в документах?" + } + ] + }, + { + "case_id": "AUTO-003", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех клиентов, по которым есть отгрузки, но денег с них не поступало уже больше 60 дней — какие из них вообще активны?" + } + ] + }, + { + "case_id": "AUTO-004", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас есть оплаты, но нет закрытия счетов, и это выглядит как архивный кэш?" + } + ] + }, + { + "case_id": "AUTO-005", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Кто из заказчиков давно не платил, но при этом по ним висят открытые договора — можно ли считать их активными или уже нужно смотреть на отключение?" + } + ] + }, + { + "case_id": "AUTO-006", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас авансы, которые уже прошли 3 месяца после получения, но не закрыты ни документами, ни сверками?" + } + ] + }, + { + "case_id": "AUTO-007", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи все контрагенты, по которым в 1С указано «договор активен», а оплаты и отгрузки — ноль за последние полгода" + } + ] + }, + { + "case_id": "AUTO-008", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким поставщикам у нас есть счета-фактуры, но документы об оплате не приходили?" + } + ] + }, + { + "case_id": "AUTO-009", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "А может быть, они вообще висят?" + } + ] + }, + { + "case_id": "AUTO-010", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие клиенты уже давно получали товары, но по ним нет актов сверки и счёт-фактур — возможно, это ошибка или просто пропущенные действия?" + } + ] + }, + { + "case_id": "AUTO-011", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас есть документы по отгрузке, но оплаты не видно — может, деньги пришли, но не привязались?" + } + ] + }, + { + "case_id": "AUTO-012", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех контрагентов с незакрытыми договорами и остатками в долгах свыше 100 тыс. — кто из них реально проблемный?" + } + ] + }, + { + "case_id": "AUTO-013", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие поставщики у нас на текущий момент имеют несогласованные остатки, и где это может повлиять на отчётность?" + } + ] + }, + { + "case_id": "AUTO-014", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас зависшие взаиморасчёты, когда документы есть, но оплаты нет — можно ли считать это технической ошибкой или уже ручная проверка нужна?" + } + ] + }, + { + "case_id": "AUTO-015", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам в 1С отображается активность, но при этом у них ноль поставок и оплат за год?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-vLP4TFSoym.json b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-vLP4TFSoym.json new file mode 100644 index 0000000..7a43754 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_runtime_job-vLP4TFSoym.json @@ -0,0 +1,190 @@ +{ + "suite_id": "assistant_autogen_runtime_job-vLP4TFSoym", + "suite_version": "0.1.0", + "schema_version": "assistant_autogen_runtime_v0_1", + "scenario_count": 15, + "case_ids": [ + "AUTO-001", + "AUTO-002", + "AUTO-003", + "AUTO-004", + "AUTO-005", + "AUTO-006", + "AUTO-007", + "AUTO-008", + "AUTO-009", + "AUTO-010", + "AUTO-011", + "AUTO-012", + "AUTO-013", + "AUTO-014", + "AUTO-015" + ], + "cases": [ + { + "case_id": "AUTO-001", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас висит сальдо, которое уже больше месяца не менялось и выглядит как застывший долг?" + } + ] + }, + { + "case_id": "AUTO-002", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас поставщики, которые давно отгружали, но оплаты так и нет — можно ли их считать просроченными или это просто задержка в документах?" + } + ] + }, + { + "case_id": "AUTO-003", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех клиентов, по которым есть отгрузки, но денег с них не поступало уже больше 60 дней — какие из них вообще активны?" + } + ] + }, + { + "case_id": "AUTO-004", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам у нас есть оплаты, но нет закрытия счетов, и это выглядит как архивный кэш?" + } + ] + }, + { + "case_id": "AUTO-005", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Кто из заказчиков давно не платил, но при этом по ним висят открытые договора — можно ли считать их активными или уже нужно смотреть на отключение?" + } + ] + }, + { + "case_id": "AUTO-006", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас авансы, которые уже прошли 3 месяца после получения, но не закрыты ни документами, ни сверками?" + } + ] + }, + { + "case_id": "AUTO-007", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи все контрагенты, по которым в 1С указано «договор активен», а оплаты и отгрузки — ноль за последние полгода" + } + ] + }, + { + "case_id": "AUTO-008", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким поставщикам у нас есть счета-фактуры, но документы об оплате не приходили?" + } + ] + }, + { + "case_id": "AUTO-009", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "А может быть, они вообще висят?" + } + ] + }, + { + "case_id": "AUTO-010", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие клиенты уже давно получали товары, но по ним нет актов сверки и счёт-фактур — возможно, это ошибка или просто пропущенные действия?" + } + ] + }, + { + "case_id": "AUTO-011", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас есть документы по отгрузке, но оплаты не видно — может, деньги пришли, но не привязались?" + } + ] + }, + { + "case_id": "AUTO-012", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Покажи всех контрагентов с незакрытыми договорами и остатками в долгах свыше 100 тыс. — кто из них реально проблемный?" + } + ] + }, + { + "case_id": "AUTO-013", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Какие поставщики у нас на текущий момент имеют несогласованные остатки, и где это может повлиять на отчётность?" + } + ] + }, + { + "case_id": "AUTO-014", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Где у нас зависшие взаиморасчёты, когда документы есть, но оплаты нет — можно ли считать это технической ошибкой или уже ручная проверка нужна?" + } + ] + }, + { + "case_id": "AUTO-015", + "scenario_tag": "autogen_runtime", + "question_type": "direct", + "broadness_level": "medium", + "turns": [ + { + "user_message": "По каким контрагентам в 1С отображается активность, но при этом у них ноль поставок и оплат за год?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260419164457_gen-mo5zy5vo-z9klj34.json b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260419164457_gen-mo5zy5vo-z9klj34.json new file mode 100644 index 0000000..cf1b32f --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260419164457_gen-mo5zy5vo-z9klj34.json @@ -0,0 +1,51 @@ +{ + "suite_id": "assistant_saved_session_gen-mo5zy5vo-z9klj34", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_suite_v0_1", + "generated_at": "2026-04-19T16:44:57.540Z", + "generation_id": "gen-mo5zy5vo-z9klj34", + "mode": "saved_user_sessions", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет как дела" + }, + { + "user_message": "кто намс должен денег на сегодня" + }, + { + "user_message": "что ты можешь" + }, + { + "user_message": "кто нам должен денег на сегодня" + }, + { + "user_message": "а мы кому" + }, + { + "user_message": "какиек остатки на складе на сегодня" + }, + { + "user_message": "альтернатива" + }, + { + "user_message": "покажи документы по чепурнову" + }, + { + "user_message": "какой оборот был свк" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-2uOHnkz2a2.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-2uOHnkz2a2.json new file mode 100644 index 0000000..00567aa --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-2uOHnkz2a2.json @@ -0,0 +1,42 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-2uOHnkz2a2", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "AGENT | Phase 18 semantic dialog authority replay", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "AGENT | Phase 18 semantic dialog authority replay", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "по какой компании мы сейчас работаем?" + }, + { + "user_message": "Альтернатива Плюс" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "какой оборот был свк" + }, + { + "user_message": "а чем капибара отличается от утки?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-KK_Wm-w0cW.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-KK_Wm-w0cW.json new file mode 100644 index 0000000..8d5d88a --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-KK_Wm-w0cW.json @@ -0,0 +1,120 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-KK_Wm-w0cW", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "кайф - что там на складе по остаткам?" + }, + { + "user_message": "АЛЬТЕРНАТИВА" + }, + { + "user_message": "а исторические остатки на другие даты умеешь?" + }, + { + "user_message": "давай на июль 2017" + }, + { + "user_message": "март 2016" + }, + { + "user_message": "По выбранному объекту \"Рабочая станция универсального специалиста (индивидуальное изготовление)\": где взяли это?" + }, + { + "user_message": "а кому продали?" + }, + { + "user_message": "у тебя написано кто контрагент: рабочая станция - это ошибка?" + }, + { + "user_message": "ндс можешь прикинуть на дату покупки рабочей станции?" + }, + { + "user_message": "а какой ндс мы должны сгрузить на март 2020?" + }, + { + "user_message": "прикинь какой ндс нам надо заплатить на февраль 2017" + }, + { + "user_message": "кто у нас самый доходный клиент за все время" + }, + { + "user_message": "кто нам должен денег на май 2017" + }, + { + "user_message": "а какой ндс мы должны примерно заплатить за этот период?" + }, + { + "user_message": "мы должны комуто денег на сегодня?" + }, + { + "user_message": "а нам?" + }, + { + "user_message": "какой у нас самый доходный год" + }, + { + "user_message": "а за 2017 мы скок заработали?" + }, + { + "user_message": "сколько вообще денег мы заработали за все время?" + }, + { + "user_message": "ты умеешь считать дельту по договорам?" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "а по свк" + }, + { + "user_message": "а сейчас у нас есть что на складе?" + }, + { + "user_message": "что нам отгружал чепурнов? какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на сегодня" + }, + { + "user_message": "остатки на март 2016" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + }, + { + "user_message": "Есть ли остатки товара, которые закупались очень давно" + }, + { + "user_message": "Какие конкретно номенклатуры формируют остаток по складу на май 2020" + }, + { + "user_message": "а по Альтернативе Плюс сколько лет активности в базе 1С?" + }, + { + "user_message": "Как ты оценишь деятельность компании?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-U2K9_kawA3.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-U2K9_kawA3.json new file mode 100644 index 0000000..fbda1a7 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-U2K9_kawA3.json @@ -0,0 +1,120 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-U2K9_kawA3", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "кайф - что там на складе по остаткам?" + }, + { + "user_message": "АЛЬТЕРНАТИВА" + }, + { + "user_message": "а исторические остатки на другие даты умеешь?" + }, + { + "user_message": "давай на июль 2017" + }, + { + "user_message": "март 2016" + }, + { + "user_message": "По выбранному объекту \"Рабочая станция универсального специалиста (индивидуальное изготовление)\": где взяли это?" + }, + { + "user_message": "а кому продали?" + }, + { + "user_message": "у тебя написано кто контрагент: рабочая станция - это ошибка?" + }, + { + "user_message": "ндс можешь прикинуть на дату покупки рабочей станции?" + }, + { + "user_message": "а какой ндс мы должны сгрузить на март 2020?" + }, + { + "user_message": "прикинь какой ндс нам надо заплатить на февраль 2017" + }, + { + "user_message": "кто у нас самый доходный клиент за все время" + }, + { + "user_message": "кто нам должен денег на май 2017" + }, + { + "user_message": "а какой ндс мы должны примерно заплатить за этот период?" + }, + { + "user_message": "мы должны комуто денег на сегодня?" + }, + { + "user_message": "а нам?" + }, + { + "user_message": "какой у нас самый доходный год" + }, + { + "user_message": "а за 2017 мы скок заработали?" + }, + { + "user_message": "сколько вообще денег мы заработали за все время?" + }, + { + "user_message": "ты умеешь считать дельту по договорам?" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "а по свк" + }, + { + "user_message": "а сейчас у нас есть что на складе?" + }, + { + "user_message": "что нам отгружал чепурнов? какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на сегодня" + }, + { + "user_message": "остатки на март 2016" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + }, + { + "user_message": "Есть ли остатки товара, которые закупались очень давно" + }, + { + "user_message": "Какие конкретно номенклатуры формируют остаток по складу на май 2020" + }, + { + "user_message": "а по Альтернативе Плюс сколько лет активности в базе 1С?" + }, + { + "user_message": "Как ты оценишь деятельность компании?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-UerO64gB9r.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-UerO64gB9r.json new file mode 100644 index 0000000..a487a1b --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-UerO64gB9r.json @@ -0,0 +1,48 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-UerO64gB9r", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет как дела" + }, + { + "user_message": "кто намс должен денег на сегодня" + }, + { + "user_message": "что ты можешь" + }, + { + "user_message": "кто нам должен денег на сегодня" + }, + { + "user_message": "а мы кому" + }, + { + "user_message": "какиек остатки на складе на сегодня" + }, + { + "user_message": "альтернатива" + }, + { + "user_message": "покажи документы по чепурнову" + }, + { + "user_message": "какой оборот был свк" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-Z2Yw7g_j-N.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-Z2Yw7g_j-N.json new file mode 100644 index 0000000..d5efab5 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-Z2Yw7g_j-N.json @@ -0,0 +1,120 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-Z2Yw7g_j-N", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "кайф - что там на складе по остаткам?" + }, + { + "user_message": "АЛЬТЕРНАТИВА" + }, + { + "user_message": "а исторические остатки на другие даты умеешь?" + }, + { + "user_message": "давай на июль 2017" + }, + { + "user_message": "март 2016" + }, + { + "user_message": "По выбранному объекту \"Рабочая станция универсального специалиста (индивидуальное изготовление)\": где взяли это?" + }, + { + "user_message": "а кому продали?" + }, + { + "user_message": "у тебя написано кто контрагент: рабочая станция - это ошибка?" + }, + { + "user_message": "ндс можешь прикинуть на дату покупки рабочей станции?" + }, + { + "user_message": "а какой ндс мы должны сгрузить на март 2020?" + }, + { + "user_message": "прикинь какой ндс нам надо заплатить на февраль 2017" + }, + { + "user_message": "кто у нас самый доходный клиент за все время" + }, + { + "user_message": "кто нам должен денег на май 2017" + }, + { + "user_message": "а какой ндс мы должны примерно заплатить за этот период?" + }, + { + "user_message": "мы должны комуто денег на сегодня?" + }, + { + "user_message": "а нам?" + }, + { + "user_message": "какой у нас самый доходный год" + }, + { + "user_message": "а за 2017 мы скок заработали?" + }, + { + "user_message": "сколько вообще денег мы заработали за все время?" + }, + { + "user_message": "ты умеешь считать дельту по договорам?" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "а по свк" + }, + { + "user_message": "а сейчас у нас есть что на складе?" + }, + { + "user_message": "что нам отгружал чепурнов? какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на сегодня" + }, + { + "user_message": "остатки на март 2016" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + }, + { + "user_message": "Есть ли остатки товара, которые закупались очень давно" + }, + { + "user_message": "Какие конкретно номенклатуры формируют остаток по складу на май 2020" + }, + { + "user_message": "а по Альтернативе Плюс сколько лет активности в базе 1С?" + }, + { + "user_message": "Как ты оценишь деятельность компании?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-_OYN2F_Y52.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-_OYN2F_Y52.json new file mode 100644 index 0000000..eae338a --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-_OYN2F_Y52.json @@ -0,0 +1,42 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-_OYN2F_Y52", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "AGENT | Phase 18 semantic dialog authority replay", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "AGENT | Phase 18 semantic dialog authority replay", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "по какой компании мы сейчас работаем?" + }, + { + "user_message": "Альтернатива Плюс" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "какой оборот был свк" + }, + { + "user_message": "а чем капибара отличается от утки?" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-pP3lffpL3V.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-pP3lffpL3V.json new file mode 100644 index 0000000..d31db3c --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-pP3lffpL3V.json @@ -0,0 +1,48 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-pP3lffpL3V", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет как дела" + }, + { + "user_message": "кто намс должен денег на сегодня" + }, + { + "user_message": "что ты можешь" + }, + { + "user_message": "кто нам должен денег на сегодня" + }, + { + "user_message": "а мы кому" + }, + { + "user_message": "какиек остатки на складе на сегодня" + }, + { + "user_message": "альтернатива" + }, + { + "user_message": "покажи документы по чепурнову" + }, + { + "user_message": "какой оборот был свк" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-q4K6EkY6xR.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-q4K6EkY6xR.json new file mode 100644 index 0000000..0876599 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-q4K6EkY6xR.json @@ -0,0 +1,48 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-q4K6EkY6xR", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "Ручная сессия 19.04.2026, 18:58:20", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет как дела" + }, + { + "user_message": "кто намс должен денег на сегодня" + }, + { + "user_message": "что ты можешь" + }, + { + "user_message": "кто нам должен денег на сегодня" + }, + { + "user_message": "а мы кому" + }, + { + "user_message": "какиек остатки на складе на сегодня" + }, + { + "user_message": "альтернатива" + }, + { + "user_message": "покажи документы по чепурнову" + }, + { + "user_message": "какой оборот был свк" + } + ] + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-vkFyPa1gBh.json b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-vkFyPa1gBh.json new file mode 100644 index 0000000..f1e8baa --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_saved_session_runtime_job-vkFyPa1gBh.json @@ -0,0 +1,120 @@ +{ + "suite_id": "assistant_saved_session_runtime_job-vkFyPa1gBh", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_runtime_v0_1", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "saved_user_sessions_runtime", + "title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "приветик - че как там дела" + }, + { + "user_message": "расскажи что можешь интересного" + }, + { + "user_message": "кайф - что там на складе по остаткам?" + }, + { + "user_message": "АЛЬТЕРНАТИВА" + }, + { + "user_message": "а исторические остатки на другие даты умеешь?" + }, + { + "user_message": "давай на июль 2017" + }, + { + "user_message": "март 2016" + }, + { + "user_message": "По выбранному объекту \"Рабочая станция универсального специалиста (индивидуальное изготовление)\": где взяли это?" + }, + { + "user_message": "а кому продали?" + }, + { + "user_message": "у тебя написано кто контрагент: рабочая станция - это ошибка?" + }, + { + "user_message": "ндс можешь прикинуть на дату покупки рабочей станции?" + }, + { + "user_message": "а какой ндс мы должны сгрузить на март 2020?" + }, + { + "user_message": "прикинь какой ндс нам надо заплатить на февраль 2017" + }, + { + "user_message": "кто у нас самый доходный клиент за все время" + }, + { + "user_message": "кто нам должен денег на май 2017" + }, + { + "user_message": "а какой ндс мы должны примерно заплатить за этот период?" + }, + { + "user_message": "мы должны комуто денег на сегодня?" + }, + { + "user_message": "а нам?" + }, + { + "user_message": "какой у нас самый доходный год" + }, + { + "user_message": "а за 2017 мы скок заработали?" + }, + { + "user_message": "сколько вообще денег мы заработали за все время?" + }, + { + "user_message": "ты умеешь считать дельту по договорам?" + }, + { + "user_message": "по чепурнову покажи все доки" + }, + { + "user_message": "а по свк" + }, + { + "user_message": "а сейчас у нас есть что на складе?" + }, + { + "user_message": "что нам отгружал чепурнов? какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на сегодня" + }, + { + "user_message": "остатки на март 2016" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + }, + { + "user_message": "Есть ли остатки товара, которые закупались очень давно" + }, + { + "user_message": "Какие конкретно номенклатуры формируют остаток по складу на май 2020" + }, + { + "user_message": "а по Альтернативе Плюс сколько лет активности в базе 1С?" + }, + { + "user_message": "Как ты оценишь деятельность компании?" + } + ] + } + ] +} \ No newline at end of file