Files
memind/chat-intent-observation.test.mjs
T
John a30b62b987
Memind CI / Test, build, and release guards (push) Has been cancelled
feat(chat-intent): observe routing, keep discuss-first on chat, and escalate short follow-ups
Close the chat-session dead zone without flipping production flags: record 0.72 fallbacks, stop C-2 from treating「先聊聊」as execute, and promote「不对你去执行」after a completed direct turn on both h5direct and date sessions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 13:13:17 +08:00

125 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
aggregateChatIntentObservations,
isRuleFallbackClassification,
observationFromIntentRoutedData,
RULE_FALLBACK_CONFIDENCE,
RULE_FALLBACK_REASON,
summarizeChatIntentObservation,
} from './chat-intent-observation.mjs';
import { CHAT_INTENT_ROUTE, classifyWithRules } from './chat-intent-router.mjs';
test('isRuleFallbackClassification accepts explicit flag or legacy 0.72 reason', () => {
assert.equal(isRuleFallbackClassification({ ruleFallback: true }), true);
assert.equal(isRuleFallbackClassification({
source: 'rule',
confidence: RULE_FALLBACK_CONFIDENCE,
reason: RULE_FALLBACK_REASON,
}), true);
assert.equal(isRuleFallbackClassification({
source: 'llm',
confidence: RULE_FALLBACK_CONFIDENCE,
reason: RULE_FALLBACK_REASON,
}), false);
});
test('summarizeChatIntentObservation tags short text and shadow flips', () => {
const observation = summarizeChatIntentObservation({
route: CHAT_INTENT_ROUTE.DIRECT_CHAT,
source: 'rule',
confidence: 0.72,
reason: RULE_FALLBACK_REASON,
ruleFallback: true,
llmShadow: { route: CHAT_INTENT_ROUTE.AGENT, wouldChangeRoute: true },
}, {
text: '帮我做',
memoryRecall: false,
});
assert.equal(observation.ruleFallback, true);
assert.equal(observation.textLengthBucket, 'short_le6');
assert.equal(observation.wouldChangeRoute, true);
assert.equal(observation.llmShadowRoute, CHAT_INTENT_ROUTE.AGENT);
});
test('observationFromIntentRoutedData prefers stored observation', () => {
const stored = { route: 'direct_chat', ruleFallback: true, textLengthBucket: 'long_gt12' };
assert.deepEqual(observationFromIntentRoutedData({
route: 'agent_orchestration',
observation: stored,
}), stored);
const inferred = observationFromIntentRoutedData({
route: 'direct_chat',
source: 'rule',
confidence: 0.72,
reason: RULE_FALLBACK_REASON,
});
assert.equal(inferred.ruleFallback, true);
});
test('aggregateChatIntentObservations computes stage A ratios', () => {
const summary = aggregateChatIntentObservations({
routed: [
{
route: 'direct_chat',
source: 'rule',
ruleFallback: true,
textLengthBucket: 'long_gt12',
memoryRecall: false,
wouldChangeRoute: true,
llmShadowRoute: 'agent_orchestration',
},
{
route: 'direct_chat',
source: 'rule',
ruleFallback: false,
textLengthBucket: 'short_le6',
memoryRecall: true,
wouldChangeRoute: false,
llmShadowRoute: null,
},
{
route: 'agent_orchestration',
source: 'llm',
ruleFallback: false,
textLengthBucket: 'long_gt12',
memoryRecall: false,
wouldChangeRoute: false,
llmShadowRoute: null,
},
],
escalatedCount: 1,
contextInjectedCount: 1,
});
assert.equal(summary.total, 3);
assert.equal(summary.ruleFallbackRatio, 0.3333);
assert.equal(summary.escalatedCount, 1);
assert.equal(summary.memoryRecallDirectRatio, 1);
assert.equal(summary.wouldChangeRouteRatio, 1);
});
test('classifyWithRules attaches stage A observation on 0.72 fallback', () => {
const result = classifyWithRules({
text: '帮我比较一下英得尔和美的车载冰箱',
sessionId: 'h5direct_abc',
sessionMessageCount: 3,
});
assert.equal(result.route, CHAT_INTENT_ROUTE.DIRECT_CHAT);
assert.equal(result.source, 'rule');
assert.equal(result.ruleFallback, true);
assert.equal(result.observation.ruleFallback, true);
assert.equal(result.observation.textLengthBucket, 'long_gt12');
assert.equal(result.observation.memoryRecall, false);
});
test('classifyWithRules marks memory recall without treating it as 0.72 fallback', () => {
const result = classifyWithRules({
text: '你记得我说想去哪儿吗',
sessionId: 'h5direct_abc',
sessionMessageCount: 3,
});
assert.equal(result.route, CHAT_INTENT_ROUTE.DIRECT_CHAT);
assert.equal(result.observation.memoryRecall, true);
assert.equal(result.observation.ruleFallback, false);
});