fix(agent): restore active-task routing and active-mode validation observation
Memind CI / Test, build, and release guards (push) Successful in 5m23s

Keep correction follow-ups on Agent using session transcript and active task
context, and let Page Data validation reach Orchestrator when mode is active
instead of requiring shadowEngine.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-27 12:15:15 +08:00
parent f95d766f69
commit aecde46ff6
6 changed files with 662 additions and 20 deletions
+138
View File
@@ -11,6 +11,9 @@ import {
coercePageGenerationSkill,
createChatIntentRouter,
createManagedChatIntentRouter,
formatRouterTranscript,
shouldDeferActiveTaskRoutingToLlm,
shouldForceActiveAgentTaskContinuation,
isNormalizedRouterDecisionEnabled,
isNormalizedRouterDecisionShadow,
resolveGatewayAgentSessionId,
@@ -469,6 +472,141 @@ test('classifyWithRules keeps agent session confirmation on agent path', () => {
assert.match(fresh.reason, /记忆/);
});
test('classifyWithRules continues agent task after failed run in same session', () => {
const activeTaskContext = {
hasRecentAgentTask: true,
lastRunFailed: true,
lastSuggestedSkill: 'page-data-collect',
lastRunStatus: 'failed',
lastRoute: 'agent_orchestration',
};
const result = classifyWithRules({
text: '还是没有按照我的逻辑更正',
sessionId: '20260827_3',
sessionMessageCount: 50,
activeTaskContext,
grantedSkills: ['page-data-collect'],
});
assert.equal(result.route, CHAT_INTENT_ROUTE.AGENT);
assert.equal(result.suggestedSkill, 'page-data-collect');
assert.match(result.reason, /上一轮任务未完成/);
});
test('classifyWithRules routes correction follow-up to agent when recent agent task exists', () => {
const activeTaskContext = {
hasRecentAgentTask: true,
lastRunFailed: false,
lastSuggestedSkill: 'page-data-collect',
lastRunStatus: 'succeeded',
lastRoute: 'agent_orchestration',
};
const result = classifyWithRules({
text: '不听指令了吗',
sessionId: '20260827_3',
sessionMessageCount: 51,
activeTaskContext,
grantedSkills: ['page-data-collect'],
});
assert.equal(result.route, CHAT_INTENT_ROUTE.AGENT);
assert.equal(result.suggestedSkill, 'page-data-collect');
assert.match(result.reason, /纠正或补充/);
});
test('classifyWithRules defers ambiguous active-task follow-up to LLM router', () => {
const activeTaskContext = {
hasRecentAgentTask: true,
lastRunFailed: false,
lastSuggestedSkill: 'page-data-collect',
lastRunStatus: 'succeeded',
lastRoute: 'agent_orchestration',
};
const result = classifyWithRules({
text: '招商管理端可以展开招商漏斗,明确准入门槛',
sessionId: '20260827_3',
sessionMessageCount: 52,
activeTaskContext,
grantedSkills: ['page-data-collect'],
});
assert.equal(result, null);
});
test('formatRouterTranscript keeps recent turns and strips skill prefixes from user text', () => {
const transcript = formatRouterTranscript([
{
role: 'user',
metadata: { displayText: '帮我做商户沟通台账' },
content: [{ type: 'text', text: '请使用 page-data-collect 技能:帮我做商户沟通台账' }],
},
{
role: 'assistant',
content: [{ type: 'text', text: '好的,我先创建问卷页面。' }],
},
], {
excludeLatestUserText: '招商管理端展开漏斗',
});
assert.match(transcript, /用户:帮我做商户沟通台账/);
assert.match(transcript, /助手:好的,我先创建问卷页面/);
assert.doesNotMatch(transcript, /page-data-collect 技能/);
});
test('createChatIntentRouter uses active-task fallback when LLM router is unavailable', async () => {
const router = createChatIntentRouter({
llmProviderService: {
async createChatCompletion() {
return null;
},
},
env: {
...process.env,
MEMIND_CHAT_LLM_ROUTER_ENABLED: '1',
MEMIND_CHAT_LLM_ROUTER_SHADOW: '0',
MEMIND_CHAT_ROUTER_CANARY_USER_IDS: '',
},
});
const result = await router.classify({
userId: 'user-1',
sessionId: '20260827_3',
sessionMessageCount: 40,
grantedSkills: ['page-data-collect'],
activeTaskContext: {
hasRecentAgentTask: true,
lastRunFailed: true,
lastSuggestedSkill: 'page-data-collect',
lastRunStatus: 'failed',
lastRoute: 'agent_orchestration',
},
userMessage: {
role: 'user',
content: [{ type: 'text', text: '还是没有按照我的逻辑更正' }],
metadata: { displayText: '还是没有按照我的逻辑更正' },
},
});
assert.equal(result.route, CHAT_INTENT_ROUTE.AGENT);
assert.equal(result.suggestedSkill, 'page-data-collect');
});
test('classifyWithRules keeps memory recall on direct chat even with failed agent task context', () => {
const activeTaskContext = {
hasRecentAgentTask: true,
lastRunFailed: true,
lastSuggestedSkill: 'page-data-collect',
lastRunStatus: 'failed',
};
const result = classifyWithRules({
text: '你记得我说想去哪儿吗',
sessionId: '20260827_3',
sessionMessageCount: 50,
activeTaskContext,
userMessage: {
role: 'user',
content: [{ type: 'text', text: '你记得我说想去哪儿吗' }],
metadata: { displayText: '你记得我说想去哪儿吗' },
},
});
assert.equal(result.route, CHAT_INTENT_ROUTE.DIRECT_CHAT);
assert.match(result.reason, /记忆|历史对话/);
});
test('classifyWithRules keeps memory recall on direct chat even when session already active', () => {
const result = classifyWithRules({
text: '你记得我说想去哪儿吗',