АДРЕСНЫЙ РЕЖИМ - L0-стабилизация address: LLM-first + deterministic fallback + tool-gate + trace
This commit is contained in:
@@ -152,5 +152,67 @@ describe("assistant address llm pre-decompose candidate preference", () => {
|
||||
expect(response.debug?.llm_decomposition_attempted).toBe(true);
|
||||
expect(response.debug?.llm_decomposition_applied).toBe(true);
|
||||
expect(response.debug?.llm_decomposition_effective_message).toBe("svk doki za 20 god pokezh");
|
||||
expect(response.debug?.fallback_rule_hit).toBeNull();
|
||||
expect(response.debug?.sanitized_user_message).toBeTypeOf("string");
|
||||
expect(response.debug?.tool_gate_decision).toBe("run_address_lane");
|
||||
});
|
||||
|
||||
it("applies deterministic fallback rule when llm fragment is unusable", async () => {
|
||||
const calls: Array<{ message: string }> = [];
|
||||
const addressQueryService = {
|
||||
tryHandle: vi.fn(async (message: string) => {
|
||||
calls.push({ message });
|
||||
return buildAddressLaneResult(message);
|
||||
})
|
||||
} as any;
|
||||
|
||||
const normalizerService = {
|
||||
normalize: vi.fn(async () => ({
|
||||
trace_id: "norm-predecompose-2",
|
||||
ok: true,
|
||||
normalized: {
|
||||
schema_version: "normalized_query_v2_0_2",
|
||||
user_message_raw: "свк доки за 20год покеж плс",
|
||||
message_in_scope: true,
|
||||
scope_confidence: "medium",
|
||||
contains_multiple_tasks: false,
|
||||
fragments: []
|
||||
},
|
||||
raw_model_output: null,
|
||||
validation: { passed: true, errors: [] },
|
||||
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
|
||||
latency_ms: 10,
|
||||
prompt_version: "normalizer_v2_0_2",
|
||||
schema_version: "v2_0_2",
|
||||
request_count_for_case: 1
|
||||
}))
|
||||
} as any;
|
||||
|
||||
const sessions = new AssistantSessionStore();
|
||||
const service = new AssistantService(
|
||||
normalizerService,
|
||||
sessions as any,
|
||||
{} as any,
|
||||
{ persistSession: vi.fn() } as any,
|
||||
addressQueryService
|
||||
);
|
||||
|
||||
const response = await service.handleMessage({
|
||||
session_id: `asst-predecompose-fallback-${Date.now()}`,
|
||||
user_message: "свк доки за 20год покеж плс",
|
||||
llmProvider: "local",
|
||||
useMock: false
|
||||
} as any);
|
||||
|
||||
expect(response.ok).toBe(true);
|
||||
expect(response.reply_type).toBe("factual");
|
||||
expect(calls).toHaveLength(1);
|
||||
expect(calls[0].message).toBe("документы по контрагенту свк за 2020 год");
|
||||
expect(response.debug?.llm_decomposition_attempted).toBe(true);
|
||||
expect(response.debug?.llm_decomposition_applied).toBe(true);
|
||||
expect(response.debug?.llm_decomposition_reason).toBe("fallback_rule_applied_after_llm");
|
||||
expect(response.debug?.fallback_rule_hit).toBe("documents_counterparty_year_rewrite");
|
||||
expect(response.debug?.sanitized_user_message).toContain("свк");
|
||||
expect(response.debug?.tool_gate_decision).toBe("run_address_lane");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user