82 lines
3.0 KiB
TypeScript
82 lines
3.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { createAssistantLivingModePolicy } from "../src/services/assistantLivingModePolicy";
|
|
|
|
function buildPolicy() {
|
|
return createAssistantLivingModePolicy({
|
|
featureAssistantLivingChatRouterV1: true,
|
|
compactWhitespace: (text: string) => text.replace(/\s+/g, " ").trim(),
|
|
repairAddressMojibake: (text: string) => text,
|
|
toNonEmptyString: (value: unknown) => {
|
|
if (value === null || value === undefined) {
|
|
return null;
|
|
}
|
|
const text = String(value).trim();
|
|
return text.length > 0 ? text : null;
|
|
},
|
|
normalizeOrganizationScopeValue: (value: unknown) => {
|
|
if (value === null || value === undefined) {
|
|
return null;
|
|
}
|
|
const text = String(value).trim().replace(/^"+|"+$/g, "").replace(/^'+|'+$/g, "");
|
|
return text.length > 0 ? text : null;
|
|
},
|
|
hasReferentialPointer: (text: string) => /(same thing|that one|this one)/i.test(text.toLowerCase()),
|
|
hasSmallTalkSignal: (text: string) => /(thanks|thank you|hello|hi)\b/i.test(text.toLowerCase()),
|
|
hasAssistantCapabilityQuestionSignal: (text: string) =>
|
|
/(?:what can you do|capabilities|features)/i.test(text),
|
|
hasOperationalAdminActionRequestSignal: (text: string) =>
|
|
/(?:install|update|delete\s+database|drop\s+database)/i.test(text),
|
|
resolveProviderExecutionState: (input: { useMock?: unknown }) => ({
|
|
living_mode_forced_deep: Boolean(input?.useMock),
|
|
living_mode_forced_reason: Boolean(input?.useMock) ? "mock_mode_keeps_deep_pipeline" : null
|
|
})
|
|
});
|
|
}
|
|
|
|
describe("assistantLivingModePolicy", () => {
|
|
it("routes casual small-talk to chat mode", () => {
|
|
const policy = buildPolicy();
|
|
|
|
const decision = policy.resolveLivingAssistantModeDecision({
|
|
userMessage: "hello",
|
|
addressLaneTriggered: false,
|
|
useMock: false,
|
|
predecomposeMode: "unsupported",
|
|
predecomposeModeConfidence: "low"
|
|
});
|
|
|
|
expect(decision.mode).toBe("chat");
|
|
expect(decision.reason).toBe("living_chat_signal_detected");
|
|
});
|
|
|
|
it("keeps explicit inventory question in deep mode", () => {
|
|
const policy = buildPolicy();
|
|
|
|
const decision = policy.resolveLivingAssistantModeDecision({
|
|
userMessage: "show warehouse inventory for 2020",
|
|
addressLaneTriggered: false,
|
|
useMock: false,
|
|
predecomposeMode: "unsupported",
|
|
predecomposeModeConfidence: "low"
|
|
});
|
|
|
|
expect(decision.mode).toBe("deep_analysis");
|
|
expect(decision.reason).toBe("strong_data_signal_detected");
|
|
});
|
|
|
|
it("keeps deep pipeline in mock mode via provider execution policy", () => {
|
|
const policy = buildPolicy();
|
|
|
|
const decision = policy.resolveLivingAssistantModeDecision({
|
|
userMessage: "hello",
|
|
addressLaneTriggered: false,
|
|
useMock: true,
|
|
predecomposeMode: "unsupported",
|
|
predecomposeModeConfidence: "low"
|
|
});
|
|
|
|
expect(decision.mode).toBe("deep_analysis");
|
|
expect(decision.reason).toBe("mock_mode_keeps_deep_pipeline");
|
|
});
|
|
});
|