249 lines
7.7 KiB
TypeScript
249 lines
7.7 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { runAssistantDeepTurnResponseRuntime } from "../src/services/assistantDeepTurnResponseRuntimeAdapter";
|
|
|
|
function buildBaseInput(overrides: Record<string, unknown> = {}) {
|
|
return {
|
|
featureInvestigationStateV1: true,
|
|
featureContractsV11: true,
|
|
featureAnswerPolicyV11: true,
|
|
sessionId: "asst-1",
|
|
questionId: "msg-q1",
|
|
userMessage: "question",
|
|
normalized: {
|
|
trace_id: "trace-1",
|
|
prompt_version: "normalizer_v2_0_2",
|
|
schema_version: "normalized_query_v2_0_2",
|
|
normalized: { schema_version: "normalized_query_v2_0_2" }
|
|
},
|
|
normalizedQuestion: "normalized-question",
|
|
routeSummary: { mode: "deterministic_v2", decisions: [] as any[] },
|
|
executionPlan: [],
|
|
requirementExtractionRequirements: [],
|
|
coverageEvaluationRequirements: [],
|
|
coverageReport: {},
|
|
groundingCheck: { status: "no_grounded_answer", reasons: [] },
|
|
retrievalCalls: [],
|
|
retrievalResultsRaw: [],
|
|
retrievalResults: [],
|
|
questionTypeClass: "single_fact_lookup",
|
|
companyAnchors: {},
|
|
runtimeAnalysisContext: {},
|
|
businessScopeResolution: {},
|
|
temporalGuard: {},
|
|
polarityAudit: {},
|
|
claimAnchorAudit: {},
|
|
targetedEvidenceAudit: {},
|
|
evidenceAdmissibilityGateAudit: {},
|
|
rbpLiveRouteAudit: {},
|
|
faLiveRouteAudit: {},
|
|
groundedAnswerEligibilityGuard: {},
|
|
followupStateUsage: null,
|
|
followupApplied: false,
|
|
composition: {
|
|
reply_type: "factual",
|
|
assistant_reply: "assistant answer"
|
|
},
|
|
previousInvestigationState: null,
|
|
addressRuntimeMetaForDeep: null,
|
|
extractDroppedIntentSegments: () => [],
|
|
buildDebugRoutes: () => [],
|
|
extractExecutionState: () => [],
|
|
sanitizeReply: (value: string) => value,
|
|
persistInvestigationState: () => {},
|
|
messageIdFactory: () => "msg-a1",
|
|
appendItem: () => {},
|
|
getSession: () => ({ session_id: "asst-1", items: [] }),
|
|
persistSession: () => {},
|
|
cloneConversation: () => [],
|
|
logEvent: () => {},
|
|
...overrides
|
|
} as any;
|
|
}
|
|
|
|
describe("assistant deep turn response runtime adapter", () => {
|
|
it("wires packaging output into deep finalization", () => {
|
|
const runPackagingRuntime = vi.fn(() => ({
|
|
messageId: "msg-a1",
|
|
investigationStateSnapshot: null,
|
|
droppedIntentSegments: [],
|
|
analysisContextForContract: null,
|
|
routesForDebug: [],
|
|
resolvedExecutionState: [],
|
|
safeAssistantReplyBase: "base",
|
|
safeAssistantReply: "safe-reply",
|
|
debug: { trace_id: "trace-1" },
|
|
assistantItem: {
|
|
message_id: "msg-a1",
|
|
session_id: "asst-1",
|
|
role: "assistant",
|
|
text: "safe-reply",
|
|
reply_type: "factual",
|
|
created_at: "2026-04-10T00:00:00.000Z",
|
|
trace_id: "trace-1",
|
|
debug: null
|
|
},
|
|
deepAnalysisLogDetails: { info: "ok" }
|
|
}));
|
|
const responsePayload = {
|
|
ok: true,
|
|
session_id: "asst-1",
|
|
conversation: [],
|
|
debug: { trace_id: "trace-1" }
|
|
};
|
|
const runFinalizeDeepTurn = vi.fn(() => ({
|
|
response: responsePayload
|
|
}));
|
|
|
|
const runtime = runAssistantDeepTurnResponseRuntime(
|
|
buildBaseInput({
|
|
runPackagingRuntime,
|
|
runFinalizeDeepTurn
|
|
})
|
|
);
|
|
|
|
expect(runPackagingRuntime).toHaveBeenCalledTimes(1);
|
|
expect(runFinalizeDeepTurn).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
sessionId: "asst-1",
|
|
assistantReply: "safe-reply",
|
|
replyType: "factual"
|
|
})
|
|
);
|
|
expect(runtime.response).toEqual(responsePayload);
|
|
expect(runtime.debug).toMatchObject({
|
|
trace_id: "trace-1",
|
|
mcp_discovery_response_applied: false
|
|
});
|
|
});
|
|
|
|
it("passes feature flags and followup flags into packaging stage", () => {
|
|
const runPackagingRuntime = vi.fn(() => ({
|
|
messageId: "msg-a1",
|
|
investigationStateSnapshot: null,
|
|
droppedIntentSegments: [],
|
|
analysisContextForContract: null,
|
|
routesForDebug: [],
|
|
resolvedExecutionState: [],
|
|
safeAssistantReplyBase: "base",
|
|
safeAssistantReply: "safe-reply",
|
|
debug: {},
|
|
assistantItem: {
|
|
message_id: "msg-a1",
|
|
session_id: "asst-1",
|
|
role: "assistant",
|
|
text: "safe-reply",
|
|
reply_type: "factual",
|
|
created_at: "2026-04-10T00:00:00.000Z",
|
|
trace_id: "trace-1",
|
|
debug: null
|
|
},
|
|
deepAnalysisLogDetails: {}
|
|
}));
|
|
|
|
runAssistantDeepTurnResponseRuntime(
|
|
buildBaseInput({
|
|
featureInvestigationStateV1: false,
|
|
followupApplied: true,
|
|
runPackagingRuntime,
|
|
runFinalizeDeepTurn: () => ({
|
|
response: {
|
|
ok: true,
|
|
session_id: "asst-1",
|
|
conversation: [],
|
|
debug: null
|
|
}
|
|
})
|
|
})
|
|
);
|
|
|
|
expect(runPackagingRuntime).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
featureInvestigationStateV1: false,
|
|
followupApplied: true
|
|
})
|
|
);
|
|
});
|
|
|
|
it("can replace a bad deep partial answer with a guarded MCP discovery candidate", () => {
|
|
const runPackagingRuntime = vi.fn(() => ({
|
|
messageId: "msg-a1",
|
|
investigationStateSnapshot: null,
|
|
droppedIntentSegments: [],
|
|
analysisContextForContract: null,
|
|
routesForDebug: [],
|
|
resolvedExecutionState: [],
|
|
safeAssistantReplyBase: "bad-base",
|
|
safeAssistantReply: "bad deep partial answer",
|
|
debug: { trace_id: "trace-1" },
|
|
assistantItem: {
|
|
message_id: "msg-a1",
|
|
session_id: "asst-1",
|
|
role: "assistant",
|
|
text: "bad deep partial answer",
|
|
reply_type: "partial_coverage",
|
|
created_at: "2026-04-10T00:00:00.000Z",
|
|
trace_id: "trace-1",
|
|
debug: null
|
|
},
|
|
deepAnalysisLogDetails: {}
|
|
}));
|
|
const runFinalizeDeepTurn = vi.fn((input) => ({
|
|
response: {
|
|
ok: true,
|
|
session_id: "asst-1",
|
|
assistant_reply: input.assistantReply,
|
|
reply_type: input.replyType,
|
|
conversation_item: input.assistantItem,
|
|
conversation: [],
|
|
debug: input.debug
|
|
}
|
|
}));
|
|
|
|
const runtime = runAssistantDeepTurnResponseRuntime(
|
|
buildBaseInput({
|
|
composition: { reply_type: "partial_coverage" },
|
|
addressRuntimeMetaForDeep: {
|
|
mcpDiscoveryRuntimeEntryPoint: {
|
|
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
|
|
policy_owner: "assistantMcpDiscoveryRuntimeEntryPoint",
|
|
entry_status: "bridge_executed",
|
|
hot_runtime_wired: false,
|
|
discovery_attempted: true,
|
|
turn_input: { should_run_discovery: true },
|
|
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: "Discovery answer",
|
|
confirmed_lines: ["Confirmed fact"],
|
|
inference_lines: [],
|
|
unknown_lines: [],
|
|
limitation_lines: [],
|
|
next_step_line: null
|
|
}
|
|
},
|
|
reason_codes: []
|
|
}
|
|
},
|
|
runPackagingRuntime,
|
|
runFinalizeDeepTurn
|
|
})
|
|
);
|
|
|
|
expect(runtime.response.assistant_reply).toContain("Discovery answer");
|
|
expect(runtime.debug?.mcp_discovery_response_applied).toBe(true);
|
|
expect(runFinalizeDeepTurn).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
assistantReply: expect.stringContaining("Discovery answer"),
|
|
replyType: "partial_coverage",
|
|
assistantItem: expect.objectContaining({
|
|
text: expect.stringContaining("Discovery answer")
|
|
})
|
|
})
|
|
);
|
|
});
|
|
});
|