From 7262603a26e35cac6f60e1bf9fe9a6f85054fbd3 Mon Sep 17 00:00:00 2001 From: dctouch Date: Fri, 24 Apr 2026 19:11:46 +0300 Subject: [PATCH] =?UTF-8?q?Post-F:=20=D0=B7=D0=B0=D0=BA=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20metadata=20scope=20=D0=B8=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B8=D1=82=D1=8C=20live7=20canary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...semantic_integrity_hardening_2026-04-23.md | 3 +- .../11 - architecture_turnaround/README.md | 4 +- .../assistantMcpDiscoveryTurnInputAdapter.js | 70 ++-- .../assistantMcpDiscoveryTurnInputAdapter.ts | 77 ++-- ...istantMcpDiscoveryTurnInputAdapter.test.ts | 44 +++ .../data/autorun_generators/history.json | 92 +++++ ..._20260424161022_gen-ag04241610-84c8bb.json | 353 ++++++++++++++++++ ..._20260424161022_gen-ag04241610-84c8bb.json | 97 +++++ 8 files changed, 687 insertions(+), 53 deletions(-) create mode 100644 llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260424161022_gen-ag04241610-84c8bb.json create mode 100644 llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260424161022_gen-ag04241610-84c8bb.json diff --git a/docs/ARCH/11 - architecture_turnaround/17 - post_f_semantic_integrity_hardening_2026-04-23.md b/docs/ARCH/11 - architecture_turnaround/17 - post_f_semantic_integrity_hardening_2026-04-23.md index 6120ecb..44311be 100644 --- a/docs/ARCH/11 - architecture_turnaround/17 - post_f_semantic_integrity_hardening_2026-04-23.md +++ b/docs/ARCH/11 - architecture_turnaround/17 - post_f_semantic_integrity_hardening_2026-04-23.md @@ -168,6 +168,7 @@ Materially hardened in this pass: - explicit raw entity search after a ranking/value-flow dialogue now resets stale assistant/followup scope: `Найди в 1С Группу СВК` becomes `source_signal=raw_text` with `explicit_entity_candidates=["Группа СВК"]`, no stale organization/date/ranking scope in the discovery turn input, and downstream follow-ups then carry the grounded SVK object intentionally; - open-organization ranked value-flow questions now stay subjectless by design: predicate-shaped entity pollution such as `принёс наибольшую выручку организации в` is discarded, referential organization placeholders such as `эта организация` are resolved through the active organization scope, and the MCP ranking answer overrides exact-lane year-summary replies when the user asked `кто`; - ranked value-flow answer drafts no longer leak raw English/internal evidence lines into the user-facing response; +- metadata-scoped movement/document chains now keep organization scope and metadata subject separate: stale follow-up `counterparty` values that are really the active organization, or action-verb pollution such as `Провести`, no longer become `explicit_entity_candidates` during year switches and document pivots; - VAT exact materialization now survives period-window filtering instead of collapsing into `recipe_visibility_gap`; - confirmed VAT tax-period turns now keep raw month extraction separate from runtime tax-quarter execution, so exact VAT routes do not lose the intended tax period; - post-pivot receivables recovery now preserves the selected open-items recipe without weakening strict account-scope guards for risk replies; @@ -188,7 +189,7 @@ Replay-backed anchors for the current layer include: - `address_truth_harness_phase80_payments_to_contracts_to_documents_all_time_live_rerun1` - `address_truth_harness_phase82_human_mixed_integrity_status_dialog_post_m23_rerun_documents_scope_bidirectional` - `address_truth_harness_phase82_human_mixed_integrity_status_dialog_post_f_account_injection_guard_clean_scope` -- `address_truth_harness_post_f_cross_stage_canary_agent_20260424_live5`, accepted `24/24`, and saved into autoruns as `AGENT | Post-F cross-stage semantic integrity canary` (`gen-ag04241406-abe4d8`) +- `address_truth_harness_post_f_cross_stage_canary_agent_20260424_live7`, accepted `24/24`, and saved into autoruns as `AGENT | Post-F cross-stage semantic integrity canary` (`gen-ag04241406-abe4d8`) ## Honest Remaining Risk diff --git a/docs/ARCH/11 - architecture_turnaround/README.md b/docs/ARCH/11 - architecture_turnaround/README.md index 83b2927..715b1f2 100644 --- a/docs/ARCH/11 - architecture_turnaround/README.md +++ b/docs/ARCH/11 - architecture_turnaround/README.md @@ -65,7 +65,7 @@ Current honest status: - pre-multidomain readiness: `~88%` - bounded-autonomy foundation readiness: `~86%` - open-world bounded-autonomy readiness: `~71%` -- graph snapshot after latest rebuild: `5891 nodes`, `12769 edges`, `135 communities` +- graph snapshot after latest rebuild: `5892 nodes`, `12772 edges`, `137 communities` - current breakpoint: - the validated hot paths are no longer structurally broken; - flagship continuity collapse is no longer the primary risk; @@ -92,7 +92,7 @@ Latest live proof now includes: - `address_truth_harness_phase80_payments_to_contracts_to_documents_all_time_live_rerun1` accepted - `address_truth_harness_phase82_human_mixed_integrity_status_dialog_post_m23_rerun_documents_scope_bidirectional` accepted `19/19` - `address_truth_harness_phase82_human_mixed_integrity_status_dialog_post_f_account_injection_guard_clean_scope` accepted `19/19`, with the `Жуковке 51` numeric counterparty suffix kept as counterparty scope instead of leaking as account `51` -- `address_truth_harness_post_f_cross_stage_canary_agent_20260424_live5` accepted `24/24`, proving a saved cross-stage AGENT canary across VAT metadata, numeric counterparty suffixes, open-organization value-flow clarification, ranked value-flow year switches, and SVK grounded reset; the saved autorun is `AGENT | Post-F cross-stage semantic integrity canary` (`gen-ag04241406-abe4d8`) +- `address_truth_harness_post_f_cross_stage_canary_agent_20260424_live7` accepted `24/24`, proving a saved cross-stage AGENT canary across VAT metadata, metadata-scoped organization/document pivots, numeric counterparty suffixes, open-organization value-flow clarification, ranked value-flow year switches, and SVK grounded reset; the saved autorun is `AGENT | Post-F cross-stage semantic integrity canary` (`gen-ag04241406-abe4d8`) - `address_truth_harness_phase11_manual_followup_meta_quality_live_rerun_vatfix` accepted `10/10` - `address_truth_harness_phase20_continuity_stabilization_live_rerun_vatfix` accepted `6/6` - `addressQueryRuntimeM23.test.ts` full semantic/runtime slice accepted `403/403` after Post-F VAT/date-basis, scope-recovery, open value-flow organization clarification, document-vs-bank arbitration, and reply-shape hardening diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js index 8581fdb..bb37e99 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnInputAdapter.js @@ -89,8 +89,17 @@ function isValueFlowPredicateEntityCandidate(value) { } return !/(? 0) && + (isInvalidEntityCandidate(followupSeed.counterparty) || + sameScopedName(followupSeed.counterparty, followupSeed.organization) || + sameScopedName(followupSeed.counterparty, currentTurnOrganizationScope))); + const effectiveFollowupCounterparty = followupCounterpartyIsMetadataOrganizationScope + ? null + : followupSeed.counterparty; const explicitOrganizationScopeSignal = Boolean(rawOrganizationMentionSignal && currentTurnOrganizationScope); const organizationClarificationFollowupApplicable = Boolean(followupSeed.domain === "counterparty_value" && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && currentTurnOrganizationScope && !rawLifecycleSignal && !rawValueFlowSignal && @@ -912,7 +932,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { !rawLifecycleSignal && !rawValueFlowSignal && hasMetadataObjectHint(rawText)); - const metadataLaneCarryoverAvailable = Boolean(followupSeed.counterparty || + const metadataLaneCarryoverAvailable = Boolean(effectiveFollowupCounterparty || followupSeed.discoveryEntity || followupSeed.metadataScopeHint || followupSeed.metadataSelectedEntitySet || @@ -946,7 +966,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { !rawLifecycleSignal && metadataMovementHintSignal); const entityResolutionGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -959,7 +979,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { !rawMetadataSignal && metadataDocumentHintSignal); const entityResolutionGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -974,14 +994,14 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const groundedValueFlowFollowupApplicable = Boolean(rawValueFlowSignal && !rawLifecycleSignal && !rawMetadataSignal && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && (followupSeed.pilotScope === "entity_resolution_search_v1" || followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" || followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" || followupSeed.pilotScope === "counterparty_value_flow_query_movements_v1" || followupSeed.pilotScope === "counterparty_supplier_payout_query_movements_v1" || followupSeed.pilotScope === "counterparty_bidirectional_value_flow_query_movements_v1")); - const groundedValueFlowEvidenceSourceApplicable = Boolean((followupSeed.counterparty || followupSeed.discoveryEntity) && + const groundedValueFlowEvidenceSourceApplicable = Boolean((effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -995,27 +1015,27 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const valueFlowGroundedDocumentFollowupApplicable = Boolean(groundedValueFlowEvidenceSourceApplicable && metadataDocumentHintSignal); const valueFlowGroundedMovementFollowupApplicable = Boolean(groundedValueFlowEvidenceSourceApplicable && metadataMovementHintSignal); const documentEvidenceGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && metadataMovementHintSignal); const movementEvidenceGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && metadataDocumentHintSignal); const metadataScopedMovementEvidenceToDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" && followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && metadataDocumentHintSignal); const metadataScopedDocumentEvidenceToMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" && followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1074,7 +1094,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable || metadataAmbiguityResolvedDocumentFollowupApplicable || (followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1092,7 +1112,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { const metadataGroundedMovementLaneApplicable = metadataGroundedMovementFollowupApplicable || metadataAmbiguityResolvedMovementFollowupApplicable || (followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1171,8 +1191,8 @@ function buildAssistantMcpDiscoveryTurnInput(input) { ? normalizedPredecomposeCounterparty : null; const explicitCurrentCounterpartyOverridesFollowupEntity = Boolean(explicitCurrentCounterpartyCandidate && - (followupSeed.counterparty || followupSeed.discoveryEntity) && - !sameScopedName(explicitCurrentCounterpartyCandidate, followupSeed.counterparty ?? followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && + !sameScopedName(explicitCurrentCounterpartyCandidate, effectiveFollowupCounterparty ?? followupSeed.discoveryEntity) && (valueFlowSignal || lifecycleSignal || metadataGroundedDocumentLaneApplicable || @@ -1187,7 +1207,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { followupSeed.metadataSelectedEntitySet ?? null; const metadataScopedLaneWithoutSubject = Boolean((metadataGroundedMovementLaneApplicable || metadataGroundedDocumentLaneApplicable) && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable); const groundedFollowupEntity = metadataScopedLaneWithoutSubject ? null @@ -1195,7 +1215,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { ? null : explicitCurrentCounterpartyOverridesFollowupEntity ? null - : followupSeed.counterparty ?? followupSeed.discoveryEntity; + : effectiveFollowupCounterparty ?? followupSeed.discoveryEntity; const entityCandidates = entityResolutionSignal ? [] : []; if (entityResolutionSignal) { pushNormalizedEntityResolutionCandidate(entityCandidates, entityResolutionClarificationCandidate); @@ -1209,7 +1229,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { pushNormalizedEntityResolutionCandidate(entityCandidates, normalizedPredecomposeCounterparty); } if (!rawEntitySearchOverridesStaleScope) { - pushNormalizedEntityResolutionCandidate(entityCandidates, followupSeed.counterparty); + pushNormalizedEntityResolutionCandidate(entityCandidates, effectiveFollowupCounterparty); } } else { @@ -1221,7 +1241,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { } pushScopedEntityCandidate(entityCandidates, normalizedPredecomposeCounterparty, groundedFollowupEntity); if (!groundedFollowupEntity) { - pushScopedEntityCandidate(entityCandidates, followupSeed.counterparty, null); + pushScopedEntityCandidate(entityCandidates, effectiveFollowupCounterparty, null); if (!metadataScopedLaneWithoutSubject) { pushScopedEntityCandidate(entityCandidates, followupSeed.discoveryEntity, null); } @@ -1234,7 +1254,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { pushUnique(entityCandidates, followupSeed.discoveryEntity); pushUnique(entityCandidates, rawMetadataScopeHint); } - const openScopeValueFlowWithoutCounterparty = valueFlowSignal && !normalizedPredecomposeCounterparty && !followupSeed.counterparty; + const openScopeValueFlowWithoutCounterparty = valueFlowSignal && !normalizedPredecomposeCounterparty && !effectiveFollowupCounterparty; const valueFlowOrganizationStaysScope = openScopeValueFlowWithoutCounterparty && Boolean(bidirectionalValueFlowSignal || hasValueRankingSignal(rawText) || @@ -1242,7 +1262,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { explicitOrganizationScopeSignal || organizationClarificationFollowupApplicable || followupSeed.organization); - const openScopeValueFlowWithoutResolvedCounterparty = Boolean(valueFlowSignal && !normalizedPredecomposeCounterparty && !followupSeed.counterparty); + const openScopeValueFlowWithoutResolvedCounterparty = Boolean(valueFlowSignal && !normalizedPredecomposeCounterparty && !effectiveFollowupCounterparty); if (openScopeValueFlowWithoutCounterparty && !valueFlowOrganizationStaysScope) { pushUnique(entityCandidates, predecomposeEntities.organization); pushUnique(entityCandidates, followupSeed.organization); @@ -1263,9 +1283,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) { if ((metadataLaneScopeHint && sameScopedName(candidate, metadataLaneScopeHint)) || (explicitOrganizationScope && sameScopedName(candidate, explicitOrganizationScope)) || (followupSeed.organization && sameScopedName(candidate, followupSeed.organization)) || - (followupSeed.counterparty && - !sameScopedName(followupSeed.counterparty, explicitCurrentCounterpartyCandidate) && - sameScopedName(candidate, followupSeed.counterparty))) { + (effectiveFollowupCounterparty && + !sameScopedName(effectiveFollowupCounterparty, explicitCurrentCounterpartyCandidate) && + sameScopedName(candidate, effectiveFollowupCounterparty))) { entityCandidates.splice(index, 1); } } @@ -1590,7 +1610,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) { normalizedPredecomposeCounterparty) { pushReason(reasonCodes, "mcp_discovery_counterparty_from_predecompose"); } - if (followupSeed.counterparty && !rawEntitySearchOverridesStaleScope) { + if (effectiveFollowupCounterparty && !rawEntitySearchOverridesStaleScope) { pushReason(reasonCodes, "mcp_discovery_counterparty_from_followup_context"); } if (followupDateScopeApplied) { diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts index ab358ae..b9b3213 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts @@ -135,8 +135,22 @@ function isValueFlowPredicateEntityCandidate(value: string | null): boolean { return !/(? 0) && + (isInvalidEntityCandidate(followupSeed.counterparty) || + sameScopedName(followupSeed.counterparty, followupSeed.organization) || + sameScopedName(followupSeed.counterparty, currentTurnOrganizationScope)) + ); + const effectiveFollowupCounterparty = followupCounterpartyIsMetadataOrganizationScope + ? null + : followupSeed.counterparty; const explicitOrganizationScopeSignal = Boolean(rawOrganizationMentionSignal && currentTurnOrganizationScope); const organizationClarificationFollowupApplicable = Boolean( followupSeed.domain === "counterparty_value" && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && currentTurnOrganizationScope && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1225,7 +1252,7 @@ export function buildAssistantMcpDiscoveryTurnInput( hasMetadataObjectHint(rawText) ); const metadataLaneCarryoverAvailable = Boolean( - followupSeed.counterparty || + effectiveFollowupCounterparty || followupSeed.discoveryEntity || followupSeed.metadataScopeHint || followupSeed.metadataSelectedEntitySet || @@ -1269,7 +1296,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ); const entityResolutionGroundedDocumentFollowupApplicable = Boolean( followupSeed.pilotScope === "entity_resolution_search_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -1286,7 +1313,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ); const entityResolutionGroundedMovementFollowupApplicable = Boolean( followupSeed.pilotScope === "entity_resolution_search_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -1305,7 +1332,7 @@ export function buildAssistantMcpDiscoveryTurnInput( rawValueFlowSignal && !rawLifecycleSignal && !rawMetadataSignal && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && (followupSeed.pilotScope === "entity_resolution_search_v1" || followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" || followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" || @@ -1314,7 +1341,7 @@ export function buildAssistantMcpDiscoveryTurnInput( followupSeed.pilotScope === "counterparty_bidirectional_value_flow_query_movements_v1") ); const groundedValueFlowEvidenceSourceApplicable = Boolean( - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -1334,7 +1361,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ); const documentEvidenceGroundedMovementFollowupApplicable = Boolean( followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -1342,7 +1369,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ); const movementEvidenceGroundedDocumentFollowupApplicable = Boolean( followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" && - (followupSeed.counterparty || followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && @@ -1351,7 +1378,7 @@ export function buildAssistantMcpDiscoveryTurnInput( const metadataScopedMovementEvidenceToDocumentFollowupApplicable = Boolean( followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" && followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1360,7 +1387,7 @@ export function buildAssistantMcpDiscoveryTurnInput( const metadataScopedDocumentEvidenceToMovementFollowupApplicable = Boolean( followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" && followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1431,7 +1458,7 @@ export function buildAssistantMcpDiscoveryTurnInput( metadataGroundedDocumentFollowupApplicable || metadataAmbiguityResolvedDocumentFollowupApplicable || (followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1450,7 +1477,7 @@ export function buildAssistantMcpDiscoveryTurnInput( metadataGroundedMovementFollowupApplicable || metadataAmbiguityResolvedMovementFollowupApplicable || (followupSeed.subjectResolutionOptional && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable && !rawLifecycleSignal && !rawValueFlowSignal && @@ -1537,8 +1564,8 @@ export function buildAssistantMcpDiscoveryTurnInput( : null; const explicitCurrentCounterpartyOverridesFollowupEntity = Boolean( explicitCurrentCounterpartyCandidate && - (followupSeed.counterparty || followupSeed.discoveryEntity) && - !sameScopedName(explicitCurrentCounterpartyCandidate, followupSeed.counterparty ?? followupSeed.discoveryEntity) && + (effectiveFollowupCounterparty || followupSeed.discoveryEntity) && + !sameScopedName(explicitCurrentCounterpartyCandidate, effectiveFollowupCounterparty ?? followupSeed.discoveryEntity) && (valueFlowSignal || lifecycleSignal || metadataGroundedDocumentLaneApplicable || @@ -1556,7 +1583,7 @@ export function buildAssistantMcpDiscoveryTurnInput( null; const metadataScopedLaneWithoutSubject = Boolean( (metadataGroundedMovementLaneApplicable || metadataGroundedDocumentLaneApplicable) && - !followupSeed.counterparty && + !effectiveFollowupCounterparty && metadataLaneCarryoverAvailable ); const groundedFollowupEntity = metadataScopedLaneWithoutSubject @@ -1565,7 +1592,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ? null : explicitCurrentCounterpartyOverridesFollowupEntity ? null - : followupSeed.counterparty ?? followupSeed.discoveryEntity; + : effectiveFollowupCounterparty ?? followupSeed.discoveryEntity; const entityCandidates = entityResolutionSignal ? [] : []; if (entityResolutionSignal) { pushNormalizedEntityResolutionCandidate(entityCandidates, entityResolutionClarificationCandidate); @@ -1579,7 +1606,7 @@ export function buildAssistantMcpDiscoveryTurnInput( pushNormalizedEntityResolutionCandidate(entityCandidates, normalizedPredecomposeCounterparty); } if (!rawEntitySearchOverridesStaleScope) { - pushNormalizedEntityResolutionCandidate(entityCandidates, followupSeed.counterparty); + pushNormalizedEntityResolutionCandidate(entityCandidates, effectiveFollowupCounterparty); } } else { if (groundedFollowupEntity) { @@ -1590,7 +1617,7 @@ export function buildAssistantMcpDiscoveryTurnInput( } pushScopedEntityCandidate(entityCandidates, normalizedPredecomposeCounterparty, groundedFollowupEntity); if (!groundedFollowupEntity) { - pushScopedEntityCandidate(entityCandidates, followupSeed.counterparty, null); + pushScopedEntityCandidate(entityCandidates, effectiveFollowupCounterparty, null); if (!metadataScopedLaneWithoutSubject) { pushScopedEntityCandidate(entityCandidates, followupSeed.discoveryEntity, null); } @@ -1606,7 +1633,7 @@ export function buildAssistantMcpDiscoveryTurnInput( pushUnique(entityCandidates, rawMetadataScopeHint); } const openScopeValueFlowWithoutCounterparty = - valueFlowSignal && !normalizedPredecomposeCounterparty && !followupSeed.counterparty; + valueFlowSignal && !normalizedPredecomposeCounterparty && !effectiveFollowupCounterparty; const valueFlowOrganizationStaysScope = openScopeValueFlowWithoutCounterparty && Boolean( @@ -1618,7 +1645,7 @@ export function buildAssistantMcpDiscoveryTurnInput( followupSeed.organization ); const openScopeValueFlowWithoutResolvedCounterparty = Boolean( - valueFlowSignal && !normalizedPredecomposeCounterparty && !followupSeed.counterparty + valueFlowSignal && !normalizedPredecomposeCounterparty && !effectiveFollowupCounterparty ); if (openScopeValueFlowWithoutCounterparty && !valueFlowOrganizationStaysScope) { pushUnique(entityCandidates, predecomposeEntities.organization); @@ -1644,9 +1671,9 @@ export function buildAssistantMcpDiscoveryTurnInput( (metadataLaneScopeHint && sameScopedName(candidate, metadataLaneScopeHint)) || (explicitOrganizationScope && sameScopedName(candidate, explicitOrganizationScope)) || (followupSeed.organization && sameScopedName(candidate, followupSeed.organization)) || - (followupSeed.counterparty && - !sameScopedName(followupSeed.counterparty, explicitCurrentCounterpartyCandidate) && - sameScopedName(candidate, followupSeed.counterparty)) + (effectiveFollowupCounterparty && + !sameScopedName(effectiveFollowupCounterparty, explicitCurrentCounterpartyCandidate) && + sameScopedName(candidate, effectiveFollowupCounterparty)) ) { entityCandidates.splice(index, 1); } @@ -2000,7 +2027,7 @@ export function buildAssistantMcpDiscoveryTurnInput( ) { pushReason(reasonCodes, "mcp_discovery_counterparty_from_predecompose"); } - if (followupSeed.counterparty && !rawEntitySearchOverridesStaleScope) { + if (effectiveFollowupCounterparty && !rawEntitySearchOverridesStaleScope) { pushReason(reasonCodes, "mcp_discovery_counterparty_from_followup_context"); } if (followupDateScopeApplied) { diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts index 90bf191..1f6c863 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryTurnInputAdapter.test.ts @@ -2007,6 +2007,7 @@ describe("assistant MCP discovery turn input adapter", () => { previous_discovery_ranking_need: "top_desc", previous_filters: { organization: orgName, + counterparty: "\u041f\u0440\u043e\u0432\u0435\u0441\u0442\u0438", period_from: "2020-01-01", period_to: "2020-12-31" } @@ -2290,4 +2291,47 @@ describe("assistant MCP discovery turn input adapter", () => { }); expect(result.turn_meaning_ref?.explicit_entity_candidates).toBeUndefined(); }); + + it("does not promote organization scope into counterparty subject after a metadata-scoped movement year switch", () => { + const orgName = + "\u041e\u041e\u041e \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u041f\u043b\u044e\u0441"; + const result = buildAssistantMcpDiscoveryTurnInput({ + userMessage: "\u0417\u0430 2020 \u0433\u043e\u0434.", + followupContext: { + previous_discovery_pilot_scope: "counterparty_movement_evidence_query_movements_v1", + previous_discovery_loop_status: "ready_for_next_hop", + previous_discovery_loop_selected_chain_id: "movement_evidence", + previous_discovery_loop_pending_axes: [], + previous_discovery_loop_asked_domain_family: "movements", + previous_discovery_loop_asked_action_family: "list_movements", + previous_discovery_loop_unsupported_family: "movement_evidence", + previous_discovery_loop_metadata_scope_hint: "\u041d\u0414\u0421", + previous_discovery_loop_subject_resolution_optional: true, + previous_discovery_entity_candidates: ["\u041d\u0414\u0421"], + previous_filters: { + organization: orgName, + counterparty: orgName, + period_to: "2026-04-24" + } + } + }); + + expect(result.adapter_status).toBe("ready"); + expect(result.should_run_discovery).toBe(true); + expect(result.semantic_data_need).toBe("movement evidence"); + expect(result.turn_meaning_ref).toMatchObject({ + asked_domain_family: "movements", + asked_action_family: "list_movements", + metadata_scope_hint: "\u041d\u0414\u0421", + subject_resolution_optional: true, + explicit_organization_scope: orgName, + explicit_date_scope: "2020", + unsupported_but_understood_family: "movement_evidence", + stale_replay_forbidden: true + }); + expect(result.turn_meaning_ref?.explicit_entity_candidates).toBeUndefined(); + expect(result.data_need_graph?.subject_candidates).toEqual([]); + expect(result.reason_codes).toContain("mcp_discovery_metadata_scoped_lane_without_subject"); + expect(result.reason_codes).not.toContain("mcp_discovery_counterparty_from_followup_context"); + }); }); diff --git a/llm_normalizer/data/autorun_generators/history.json b/llm_normalizer/data/autorun_generators/history.json index 1f0fe38..da9f95f 100644 --- a/llm_normalizer/data/autorun_generators/history.json +++ b/llm_normalizer/data/autorun_generators/history.json @@ -1,4 +1,96 @@ [ + { + "generation_id": "gen-ag04241610-84c8bb", + "created_at": "2026-04-24T16:10:22+00:00", + "mode": "saved_user_sessions", + "title": "AGENT | Post-F cross-stage semantic integrity canary live7", + "count": 24, + "domain": "address_post_f_cross_stage_canary_agent", + "questions": [ + "Мне нужно понять, где в 1С по НДС вообще лежат данные. Какие объекты стоит смотреть по НДС?", + "Хорошо, тогда покажи движения по ООО Альтернатива Плюс.", + "За 2020 год.", + "А теперь по документам?", + "А теперь за 2021 год?", + "А теперь за все время?", + "С НДС закончили. Новая тема: покажи документы по Жуковке 51.", + "Хорошо, а теперь платежи по нему тоже покажи.", + "А по нему договоры?", + "А по нему документы?", + "А за 2021?", + "С Жуковкой закончили. Теперь другая задача: быстрый денежный срез по одной организации. Если для ответа нужна организация, просто уточни ее. Сколько вообще входящих денег было за 2020 год?", + "По ООО Альтернатива Плюс.", + "Понял, тогда за все время.", + "Хорошо. А что по ООО Альтернатива Плюс больше в 2020 году: входящие или исходящие деньги?", + "И кто больше всего принес денег этой организации в 2020 году?", + "А в 2021 году?", + "Теперь отдельная тема по конкретному контрагенту. Найди в 1С Группу СВК.", + "Сколько получили по нему за 2020 год?", + "А теперь сколько заплатили?", + "А какое нетто?", + "А по документам?", + "А по движениям?", + "А теперь тот же смысл за 2021 год." + ], + "generated_by": "codex_agent", + "saved_case_set_file": "assistant_autogen_saved_user_sessions_20260424161022_gen-ag04241610-84c8bb.json", + "context": { + "llm_provider": null, + "model": null, + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "autogen_personality_id": null, + "autogen_personality_prompt": null, + "source_session_id": null, + "saved_session_file": "assistant_saved_session_20260424161022_gen-ag04241610-84c8bb.json", + "saved_case_set_kind": "agent_semantic_scenario", + "agent_run": true, + "agent_focus": "live7: VAT metadata scoped org/document pivots, ranking year switches, fresh SVK reset", + "architecture_phase": "Post-F Semantic Integrity Hardening", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_post_f_cross_stage_canary_agent_20260424.json", + "scenario_id": "address_truth_harness_post_f_cross_stage_canary_agent_20260424", + "semantic_tags": [ + "account_injection_guard", + "all_time_followup", + "bidirectional_value_flow", + "clarification_resume", + "contracts_followup", + "counterparty_pronoun_resolution", + "cross_stage_canary", + "document_lane_continuity", + "document_pivot_after_movement", + "documents_followup", + "documents_pivot", + "grounded_counterparty", + "incoming_value_flow", + "legacy_phase39", + "legacy_phase64", + "legacy_phase67", + "metadata_surface", + "movement_execution", + "movement_lane_after_metadata", + "movements_pivot", + "net_value_flow", + "numeric_counterparty_suffix", + "open_scope_total", + "organization_clarification", + "organization_scope", + "payments_followup", + "payout_value_flow", + "period_clarification_resume", + "post_f", + "repeated_pivot", + "scope_reuse", + "topic_reset", + "value_flow_ranking", + "vat_orientation", + "year_switch", + "year_switch_after_document_pivot", + "year_switch_after_repeated_pivot" + ] + } + }, { "generation_id": "gen-ag04241406-abe4d8", "created_at": "2026-04-24T14:06:30+00:00", diff --git a/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260424161022_gen-ag04241610-84c8bb.json b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260424161022_gen-ag04241610-84c8bb.json new file mode 100644 index 0000000..91a1b03 --- /dev/null +++ b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260424161022_gen-ag04241610-84c8bb.json @@ -0,0 +1,353 @@ +{ + "saved_at": "2026-04-24T16:10:22+00:00", + "generation_id": "gen-ag04241610-84c8bb", + "mode": "saved_user_sessions", + "title": "AGENT | Post-F cross-stage semantic integrity canary live7", + "agent_run": true, + "questions": [ + "Мне нужно понять, где в 1С по НДС вообще лежат данные. Какие объекты стоит смотреть по НДС?", + "Хорошо, тогда покажи движения по ООО Альтернатива Плюс.", + "За 2020 год.", + "А теперь по документам?", + "А теперь за 2021 год?", + "А теперь за все время?", + "С НДС закончили. Новая тема: покажи документы по Жуковке 51.", + "Хорошо, а теперь платежи по нему тоже покажи.", + "А по нему договоры?", + "А по нему документы?", + "А за 2021?", + "С Жуковкой закончили. Теперь другая задача: быстрый денежный срез по одной организации. Если для ответа нужна организация, просто уточни ее. Сколько вообще входящих денег было за 2020 год?", + "По ООО Альтернатива Плюс.", + "Понял, тогда за все время.", + "Хорошо. А что по ООО Альтернатива Плюс больше в 2020 году: входящие или исходящие деньги?", + "И кто больше всего принес денег этой организации в 2020 году?", + "А в 2021 году?", + "Теперь отдельная тема по конкретному контрагенту. Найди в 1С Группу СВК.", + "Сколько получили по нему за 2020 год?", + "А теперь сколько заплатили?", + "А какое нетто?", + "А по документам?", + "А по движениям?", + "А теперь тот же смысл за 2021 год." + ], + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "live7: VAT metadata scoped org/document pivots, ranking year switches, fresh SVK reset", + "architecture_phase": "Post-F Semantic Integrity Hardening", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_post_f_cross_stage_canary_agent_20260424.json", + "scenario_id": "address_truth_harness_post_f_cross_stage_canary_agent_20260424", + "semantic_tags": [ + "account_injection_guard", + "all_time_followup", + "bidirectional_value_flow", + "clarification_resume", + "contracts_followup", + "counterparty_pronoun_resolution", + "cross_stage_canary", + "document_lane_continuity", + "document_pivot_after_movement", + "documents_followup", + "documents_pivot", + "grounded_counterparty", + "incoming_value_flow", + "legacy_phase39", + "legacy_phase64", + "legacy_phase67", + "metadata_surface", + "movement_execution", + "movement_lane_after_metadata", + "movements_pivot", + "net_value_flow", + "numeric_counterparty_suffix", + "open_scope_total", + "organization_clarification", + "organization_scope", + "payments_followup", + "payout_value_flow", + "period_clarification_resume", + "post_f", + "repeated_pivot", + "scope_reuse", + "topic_reset", + "value_flow_ranking", + "vat_orientation", + "year_switch", + "year_switch_after_document_pivot", + "year_switch_after_repeated_pivot" + ] + }, + "source_session_id": null, + "session": { + "session_id": null, + "mode": "agent_semantic_run", + "items": [ + { + "message_id": "agent-user-001", + "role": "user", + "text": "Мне нужно понять, где в 1С по НДС вообще лежат данные. Какие объекты стоит смотреть по НДС?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-002", + "role": "user", + "text": "Хорошо, тогда покажи движения по ООО Альтернатива Плюс.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-003", + "role": "user", + "text": "За 2020 год.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-004", + "role": "user", + "text": "А теперь по документам?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-005", + "role": "user", + "text": "А теперь за 2021 год?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-006", + "role": "user", + "text": "А теперь за все время?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-007", + "role": "user", + "text": "С НДС закончили. Новая тема: покажи документы по Жуковке 51.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-008", + "role": "user", + "text": "Хорошо, а теперь платежи по нему тоже покажи.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-009", + "role": "user", + "text": "А по нему договоры?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-010", + "role": "user", + "text": "А по нему документы?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-011", + "role": "user", + "text": "А за 2021?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-012", + "role": "user", + "text": "С Жуковкой закончили. Теперь другая задача: быстрый денежный срез по одной организации. Если для ответа нужна организация, просто уточни ее. Сколько вообще входящих денег было за 2020 год?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-013", + "role": "user", + "text": "По ООО Альтернатива Плюс.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-014", + "role": "user", + "text": "Понял, тогда за все время.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-015", + "role": "user", + "text": "Хорошо. А что по ООО Альтернатива Плюс больше в 2020 году: входящие или исходящие деньги?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-016", + "role": "user", + "text": "И кто больше всего принес денег этой организации в 2020 году?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-017", + "role": "user", + "text": "А в 2021 году?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-018", + "role": "user", + "text": "Теперь отдельная тема по конкретному контрагенту. Найди в 1С Группу СВК.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-019", + "role": "user", + "text": "Сколько получили по нему за 2020 год?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-020", + "role": "user", + "text": "А теперь сколько заплатили?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-021", + "role": "user", + "text": "А какое нетто?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-022", + "role": "user", + "text": "А по документам?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-023", + "role": "user", + "text": "А по движениям?", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-024", + "role": "user", + "text": "А теперь тот же смысл за 2021 год.", + "created_at": "2026-04-24T16:10:22+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + } + ], + "agent_run": true, + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "live7: VAT metadata scoped org/document pivots, ranking year switches, fresh SVK reset", + "architecture_phase": "Post-F Semantic Integrity Hardening", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_post_f_cross_stage_canary_agent_20260424.json", + "scenario_id": "address_truth_harness_post_f_cross_stage_canary_agent_20260424", + "semantic_tags": [ + "account_injection_guard", + "all_time_followup", + "bidirectional_value_flow", + "clarification_resume", + "contracts_followup", + "counterparty_pronoun_resolution", + "cross_stage_canary", + "document_lane_continuity", + "document_pivot_after_movement", + "documents_followup", + "documents_pivot", + "grounded_counterparty", + "incoming_value_flow", + "legacy_phase39", + "legacy_phase64", + "legacy_phase67", + "metadata_surface", + "movement_execution", + "movement_lane_after_metadata", + "movements_pivot", + "net_value_flow", + "numeric_counterparty_suffix", + "open_scope_total", + "organization_clarification", + "organization_scope", + "payments_followup", + "payout_value_flow", + "period_clarification_resume", + "post_f", + "repeated_pivot", + "scope_reuse", + "topic_reset", + "value_flow_ranking", + "vat_orientation", + "year_switch", + "year_switch_after_document_pivot", + "year_switch_after_repeated_pivot" + ] + } + } +} diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260424161022_gen-ag04241610-84c8bb.json b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260424161022_gen-ag04241610-84c8bb.json new file mode 100644 index 0000000..f632574 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260424161022_gen-ag04241610-84c8bb.json @@ -0,0 +1,97 @@ +{ + "suite_id": "assistant_saved_session_gen-ag04241610-84c8bb", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_suite_v0_1", + "generated_at": "2026-04-24T16:10:22+00:00", + "generation_id": "gen-ag04241610-84c8bb", + "mode": "saved_user_sessions", + "title": "AGENT | Post-F cross-stage semantic integrity canary live7", + "domain": "address_post_f_cross_stage_canary_agent", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "agent_saved_user_sessions", + "title": "AGENT | Post-F cross-stage semantic integrity canary live7", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "Мне нужно понять, где в 1С по НДС вообще лежат данные. Какие объекты стоит смотреть по НДС?" + }, + { + "user_message": "Хорошо, тогда покажи движения по ООО Альтернатива Плюс." + }, + { + "user_message": "За 2020 год." + }, + { + "user_message": "А теперь по документам?" + }, + { + "user_message": "А теперь за 2021 год?" + }, + { + "user_message": "А теперь за все время?" + }, + { + "user_message": "С НДС закончили. Новая тема: покажи документы по Жуковке 51." + }, + { + "user_message": "Хорошо, а теперь платежи по нему тоже покажи." + }, + { + "user_message": "А по нему договоры?" + }, + { + "user_message": "А по нему документы?" + }, + { + "user_message": "А за 2021?" + }, + { + "user_message": "С Жуковкой закончили. Теперь другая задача: быстрый денежный срез по одной организации. Если для ответа нужна организация, просто уточни ее. Сколько вообще входящих денег было за 2020 год?" + }, + { + "user_message": "По ООО Альтернатива Плюс." + }, + { + "user_message": "Понял, тогда за все время." + }, + { + "user_message": "Хорошо. А что по ООО Альтернатива Плюс больше в 2020 году: входящие или исходящие деньги?" + }, + { + "user_message": "И кто больше всего принес денег этой организации в 2020 году?" + }, + { + "user_message": "А в 2021 году?" + }, + { + "user_message": "Теперь отдельная тема по конкретному контрагенту. Найди в 1С Группу СВК." + }, + { + "user_message": "Сколько получили по нему за 2020 год?" + }, + { + "user_message": "А теперь сколько заплатили?" + }, + { + "user_message": "А какое нетто?" + }, + { + "user_message": "А по документам?" + }, + { + "user_message": "А по движениям?" + }, + { + "user_message": "А теперь тот же смысл за 2021 год." + } + ] + } + ] +}