338 lines
14 KiB
TypeScript
338 lines
14 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
runAssistantDeepTurnAnalysisAttemptRuntime,
|
|
type RunAssistantDeepTurnAnalysisAttemptRuntimeInput
|
|
} from "../src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter";
|
|
|
|
function buildInput(
|
|
overrides: Partial<RunAssistantDeepTurnAnalysisAttemptRuntimeInput> = {}
|
|
): RunAssistantDeepTurnAnalysisAttemptRuntimeInput {
|
|
return {
|
|
userMessage: "почему долг не закрылся",
|
|
normalizedPayload: { fragments: [] } as any,
|
|
routeSummary: { mode: "deterministic_v2", decisions: [] } as any,
|
|
runtimeAnalysisContext: {
|
|
active: true,
|
|
as_of_date: "2020-07-31",
|
|
period_from: null,
|
|
period_to: null,
|
|
source: "analysis_context"
|
|
},
|
|
followupUsage: { applied: true },
|
|
investigationState: { session_id: "asst-1", followup_context: { active_domain: "settlements_60_62" } } as any,
|
|
featureAnswerPolicyV11: true,
|
|
featureProblemCentricAnswerV1: true,
|
|
featureLifecycleAnswerV1: true,
|
|
resolveBusinessScopeAlignment: () => ({ route_summary_resolved: { mode: "deterministic_v2", decisions: [] } }),
|
|
inferP0DomainFromMessage: () => "settlements_60_62",
|
|
resolveBusinessScopeFromLiveContext: ({ current }) => current,
|
|
extractRequirements: () => ({
|
|
requirements: [{ id: "R1" }],
|
|
byFragment: new Map<string, string[]>([["F1", ["R1"]]])
|
|
}),
|
|
toExecutionPlan: () =>
|
|
[
|
|
{
|
|
fragment_id: "F1",
|
|
requirement_ids: ["R1"],
|
|
route: "store_canonical",
|
|
should_execute: true,
|
|
fragment_text: "fragment",
|
|
no_route_reason: null
|
|
}
|
|
] as any,
|
|
enforceRbpLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: { rbp: true } }),
|
|
enforceFaLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: { fa: true } }),
|
|
executeRouteRuntime: async () => ({
|
|
status: "ok",
|
|
result_type: "summary",
|
|
items: [],
|
|
summary: {},
|
|
evidence: [],
|
|
limitations: []
|
|
}),
|
|
mapNoRouteReason: () => "skipped",
|
|
buildSkippedResult: (item) =>
|
|
({
|
|
fragment_id: item.fragment_id,
|
|
requirement_ids: item.requirement_ids ?? [],
|
|
route: item.route,
|
|
status: "skipped"
|
|
}) as any,
|
|
evaluateCoverage: () => ({
|
|
requirements: [{ id: "R1" }],
|
|
coverage: { requirements_total: 1, requirements_covered: 1 }
|
|
}),
|
|
checkGrounding: () => ({
|
|
status: "grounded",
|
|
reasons: []
|
|
}),
|
|
collectRbpLiveRouteAudit: () => ({ routed: 1 }),
|
|
collectFaLiveRouteAudit: () => ({ routed: 1 }),
|
|
hasExplicitPeriodAnchor: () => false,
|
|
...overrides
|
|
} as RunAssistantDeepTurnAnalysisAttemptRuntimeInput;
|
|
}
|
|
|
|
describe("assistant deep turn analysis attempt runtime adapter", () => {
|
|
it("wires deep-analysis callbacks through delegated runtime", async () => {
|
|
const runDeepTurnContextRuntime = vi.fn(() => ({
|
|
companyAnchors: { accounts: ["60.01"] },
|
|
initialBusinessScopeResolution: { route_summary_resolved: { mode: "deterministic_v2", decisions: [] } },
|
|
inferredDomainByMessage: "settlements_60_62",
|
|
focusDomainForGuards: "settlements_60_62",
|
|
temporalGuard: { primary_period_window: { from: "2020-07-01", to: "2020-07-31" } },
|
|
domainPolarityGuardInitial: { polarity: "supplier_payable" },
|
|
claimAnchorAudit: { claim_type: "prove_settlement_closure_state" },
|
|
businessScopeResolution: {
|
|
route_summary_resolved: { mode: "deterministic_v2", decisions: [] },
|
|
business_scope_resolved: ["company_specific_accounting"]
|
|
},
|
|
resolvedRouteSummary: { mode: "deterministic_v2", decisions: [] },
|
|
liveTemporalHint: {
|
|
as_of_date: "2020-07-31",
|
|
period_from: null,
|
|
period_to: null,
|
|
source: "analysis_context"
|
|
}
|
|
}));
|
|
const runDeepTurnPlanRuntime = vi.fn(() => ({
|
|
requirementExtraction: {
|
|
requirements: [{ id: "R1" }],
|
|
byFragment: new Map<string, string[]>([["F1", ["R1"]]])
|
|
},
|
|
executionPlan: [
|
|
{
|
|
fragment_id: "F1",
|
|
requirement_ids: ["R1"],
|
|
route: "store_canonical",
|
|
should_execute: true,
|
|
fragment_text: "fragment",
|
|
no_route_reason: null
|
|
}
|
|
],
|
|
rbpRoutePlanEnforcement: { executionPlan: [], audit: { rbp: true } },
|
|
faRoutePlanEnforcement: { executionPlan: [], audit: { fa: true } }
|
|
}));
|
|
const executeRouteRuntime = vi.fn(async () => ({
|
|
status: "ok",
|
|
result_type: "summary",
|
|
items: [],
|
|
summary: {},
|
|
evidence: [],
|
|
limitations: []
|
|
}));
|
|
const runDeepTurnRetrievalRuntime = vi.fn(async (input) => {
|
|
expect(input.executeRouteRuntime).toBe(executeRouteRuntime);
|
|
return {
|
|
retrievalCalls: [{ fragment_id: "F1", route: "store_canonical" }],
|
|
retrievalResultsRaw: [{ fragment_id: "F1", route: "store_canonical", raw_result: {} }],
|
|
retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"], route: "store_canonical" }]
|
|
} as any;
|
|
});
|
|
const runDeepTurnGuardRuntime = vi.fn(() => ({
|
|
retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"], route: "store_canonical" }],
|
|
polarityGuardResult: { audit: { polarity: "supplier_payable" } },
|
|
targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: 1 } },
|
|
evidenceGateResult: { audit: { admissible_evidence_count: 1 } }
|
|
}));
|
|
const runDeepTurnGroundingRuntime = vi.fn(() => ({
|
|
rbpLiveRouteAudit: { routed: 1 },
|
|
faLiveRouteAudit: { routed: 1 },
|
|
coverageEvaluation: {
|
|
requirements: [{ id: "R1" }],
|
|
coverage: { requirements_total: 1, requirements_covered: 1 }
|
|
},
|
|
groundedAnswerEligibilityGuard: { eligible: true },
|
|
groundingCheck: { status: "grounded", reasons: [] }
|
|
}));
|
|
const runDeepTurnCompositionRuntime = vi.fn(() => ({
|
|
questionTypeClass: "causal_trace",
|
|
composition: { reply_type: "factual_with_explanation" }
|
|
}));
|
|
const runDeepTurnAnalysisRuntime = vi.fn(async (input) => {
|
|
const contextRuntime = input.runContextRuntime();
|
|
const executionPlanRuntime = input.runExecutionPlanRuntime({
|
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
|
temporalGuard: contextRuntime.temporalGuard,
|
|
domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial
|
|
});
|
|
const retrievalRuntime = await input.runRetrievalRuntime({
|
|
executionPlan: executionPlanRuntime.executionPlan,
|
|
liveTemporalHint: contextRuntime.liveTemporalHint
|
|
});
|
|
const guardRuntime = input.runGuardRuntime({
|
|
retrievalResults: retrievalRuntime.retrievalResults as any,
|
|
domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial,
|
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
|
temporalGuard: contextRuntime.temporalGuard,
|
|
focusDomainForGuards: contextRuntime.focusDomainForGuards,
|
|
companyAnchors: contextRuntime.companyAnchors,
|
|
userMessage: "runtime-user-message"
|
|
});
|
|
const groundingRuntime = input.runGroundingRuntime({
|
|
claimType: contextRuntime.claimAnchorAudit.claim_type,
|
|
retrievalResults: guardRuntime.retrievalResults as any,
|
|
rbpPlanAudit: executionPlanRuntime.rbpRoutePlanEnforcement.audit,
|
|
faPlanAudit: executionPlanRuntime.faRoutePlanEnforcement.audit,
|
|
routeSummary: contextRuntime.resolvedRouteSummary,
|
|
requirementExtraction: executionPlanRuntime.requirementExtraction,
|
|
temporalGuard: contextRuntime.temporalGuard,
|
|
polarityAudit: guardRuntime.polarityGuardResult.audit,
|
|
evidenceAudit: guardRuntime.evidenceGateResult.audit,
|
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
|
targetedEvidenceHitRate: guardRuntime.targetedEvidenceResult.audit.targeted_evidence_hit_rate,
|
|
businessScopeResolved: contextRuntime.businessScopeResolution.business_scope_resolved
|
|
});
|
|
const compositionRuntime = input.runCompositionRuntime({
|
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
|
retrievalResults: guardRuntime.retrievalResults as any,
|
|
requirements: groundingRuntime.coverageEvaluation.requirements as any,
|
|
coverageReport: groundingRuntime.coverageEvaluation.coverage as any,
|
|
groundingCheck: groundingRuntime.groundingCheck as any,
|
|
companyAnchors: contextRuntime.companyAnchors
|
|
});
|
|
|
|
return {
|
|
companyAnchors: contextRuntime.companyAnchors,
|
|
temporalGuard: contextRuntime.temporalGuard,
|
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
|
businessScopeResolution: contextRuntime.businessScopeResolution,
|
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
|
requirementExtraction: executionPlanRuntime.requirementExtraction as any,
|
|
executionPlan: executionPlanRuntime.executionPlan as any,
|
|
retrievalCalls: retrievalRuntime.retrievalCalls as any,
|
|
retrievalResultsRaw: retrievalRuntime.retrievalResultsRaw as any,
|
|
retrievalResults: guardRuntime.retrievalResults as any,
|
|
polarityGuardResult: guardRuntime.polarityGuardResult as any,
|
|
targetedEvidenceResult: guardRuntime.targetedEvidenceResult as any,
|
|
evidenceGateResult: guardRuntime.evidenceGateResult as any,
|
|
rbpLiveRouteAudit: groundingRuntime.rbpLiveRouteAudit as any,
|
|
faLiveRouteAudit: groundingRuntime.faLiveRouteAudit as any,
|
|
coverageEvaluation: groundingRuntime.coverageEvaluation as any,
|
|
groundedAnswerEligibilityGuard: groundingRuntime.groundedAnswerEligibilityGuard as any,
|
|
groundingCheck: groundingRuntime.groundingCheck as any,
|
|
questionTypeClass: compositionRuntime.questionTypeClass as any,
|
|
composition: compositionRuntime.composition as any
|
|
};
|
|
});
|
|
|
|
const runtime = await runAssistantDeepTurnAnalysisAttemptRuntime(
|
|
buildInput({
|
|
executeRouteRuntime,
|
|
runDeepTurnAnalysisRuntime,
|
|
runDeepTurnContextRuntime,
|
|
runDeepTurnPlanRuntime,
|
|
runDeepTurnRetrievalRuntime,
|
|
runDeepTurnGuardRuntime,
|
|
runDeepTurnGroundingRuntime,
|
|
runDeepTurnCompositionRuntime
|
|
})
|
|
);
|
|
|
|
expect(runDeepTurnAnalysisRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnContextRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnPlanRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnRetrievalRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnGuardRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnGroundingRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runDeepTurnCompositionRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runtime.questionTypeClass).toBe("causal_trace");
|
|
});
|
|
|
|
it("forwards composition feature flags and investigation state", async () => {
|
|
const runDeepTurnCompositionRuntime = vi.fn(() => ({
|
|
questionTypeClass: "single_fact_lookup",
|
|
composition: { reply_type: "partial_coverage" }
|
|
}));
|
|
const runDeepTurnAnalysisRuntime = vi.fn(async (input) => {
|
|
input.runContextRuntime();
|
|
input.runExecutionPlanRuntime({
|
|
resolvedRouteSummary: null,
|
|
claimAnchorAudit: { claim_type: "unknown" },
|
|
temporalGuard: {},
|
|
domainPolarityGuardInitial: {}
|
|
});
|
|
await input.runRetrievalRuntime({
|
|
executionPlan: [],
|
|
liveTemporalHint: null
|
|
});
|
|
input.runGuardRuntime({
|
|
retrievalResults: [],
|
|
domainPolarityGuardInitial: {},
|
|
claimAnchorAudit: { claim_type: "unknown" },
|
|
temporalGuard: {},
|
|
focusDomainForGuards: null,
|
|
companyAnchors: {},
|
|
userMessage: "message"
|
|
});
|
|
input.runGroundingRuntime({
|
|
claimType: "unknown",
|
|
retrievalResults: [],
|
|
rbpPlanAudit: {},
|
|
faPlanAudit: {},
|
|
routeSummary: null,
|
|
requirementExtraction: { requirements: [], byFragment: new Map() } as any,
|
|
temporalGuard: {},
|
|
polarityAudit: {},
|
|
evidenceAudit: {},
|
|
claimAnchorAudit: { claim_type: "unknown" },
|
|
targetedEvidenceHitRate: null,
|
|
businessScopeResolved: null
|
|
});
|
|
input.runCompositionRuntime({
|
|
resolvedRouteSummary: null,
|
|
retrievalResults: [],
|
|
requirements: [],
|
|
coverageReport: {},
|
|
groundingCheck: { status: "grounded", reasons: [] },
|
|
companyAnchors: {}
|
|
});
|
|
return {
|
|
companyAnchors: {},
|
|
temporalGuard: {},
|
|
claimAnchorAudit: { claim_type: "unknown" },
|
|
businessScopeResolution: {},
|
|
resolvedRouteSummary: null,
|
|
requirementExtraction: { requirements: [], byFragment: new Map() } as any,
|
|
executionPlan: [],
|
|
retrievalCalls: [],
|
|
retrievalResultsRaw: [],
|
|
retrievalResults: [],
|
|
polarityGuardResult: { audit: {} } as any,
|
|
targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: null } } as any,
|
|
evidenceGateResult: { audit: {} } as any,
|
|
rbpLiveRouteAudit: {},
|
|
faLiveRouteAudit: {},
|
|
coverageEvaluation: { requirements: [], coverage: {} } as any,
|
|
groundedAnswerEligibilityGuard: {},
|
|
groundingCheck: { status: "grounded", reasons: [] } as any,
|
|
questionTypeClass: "single_fact_lookup" as any,
|
|
composition: { reply_type: "partial_coverage" } as any
|
|
};
|
|
});
|
|
|
|
const investigationState = { session_id: "asst-2" } as any;
|
|
await runAssistantDeepTurnAnalysisAttemptRuntime(
|
|
buildInput({
|
|
investigationState,
|
|
featureAnswerPolicyV11: false,
|
|
featureProblemCentricAnswerV1: false,
|
|
featureLifecycleAnswerV1: false,
|
|
runDeepTurnCompositionRuntime,
|
|
runDeepTurnAnalysisRuntime
|
|
})
|
|
);
|
|
|
|
expect(runDeepTurnCompositionRuntime).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
investigationState,
|
|
featureAnswerPolicyV11: false,
|
|
featureProblemCentricAnswerV1: false,
|
|
featureLifecycleAnswerV1: false
|
|
})
|
|
);
|
|
});
|
|
});
|