feat: LLM intent router, direct chat execution, and Memory V2 light intervention

Wire chat intent routing with direct_chat on regular sessions, skill-selected
short-circuit to Agent, memory light/heavy intervention tiers, and fix direct
chat UI stuck streaming after completion.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-04 22:32:57 +08:00
parent bfb6356f7d
commit e45c9300bf
33 changed files with 3412 additions and 105 deletions
+90 -6
View File
@@ -6,16 +6,17 @@ import {
sendDirectChatSessionEvents,
} from './direct-chat-service.mjs';
test('direct chat is disabled by default', () => {
test('direct chat is enabled by default', () => {
const service = createDirectChatService({
userAuth: {},
llmProviderService: {},
sessionSnapshotService: {},
});
assert.equal(service.getStatus().enabled, false);
assert.equal(service.getStatus().enabled, true);
assert.equal(service.canHandle({
userMessage: { role: 'user', content: [{ type: 'text', text: 'hi' }] },
}), false);
routingDecision: 'direct_chat',
}), true);
});
test('direct chat creates a direct session, saves snapshot, and bills returned usage', async () => {
@@ -80,9 +81,9 @@ test('direct chat creates a direct session, saves snapshot, and bills returned u
assert.deepEqual(registered, [
{ userId: 'user-1', sessionId: result.sessionId, target: 'h5-direct' },
]);
assert.equal(saved.length, 1);
assert.equal(saved[0].messages.length, 2);
assert.equal(saved[0].messages[1].content[0].text, '你好,已收到。');
assert.equal(saved.length, 2);
assert.equal(saved[1].messages.length, 2);
assert.equal(saved[1].messages[1].content[0].text, '你好,已收到。');
assert.match(llmMessages[0][0].content, /喜欢简洁回答/);
assert.deepEqual(billed, [{
userId: 'user-1',
@@ -201,3 +202,86 @@ test('direct chat rejects page generation tasks so the execution backend can han
},
}), false);
});
test('direct chat allows llm-routed replies on regular agent sessions', () => {
const service = createDirectChatService({
enabled: true,
userAuth: {},
llmProviderService: {},
sessionSnapshotService: {},
});
const userMessage = {
role: 'user',
content: [{ type: 'text', text: '我想对太湖有更多的了解' }],
metadata: { displayText: '我想对太湖有更多的了解' },
};
assert.equal(service.canHandle({
sessionId: '20260704_11',
routingDecision: 'direct_chat',
userMessage,
}), true);
assert.equal(service.explainCanHandle({
sessionId: '20260704_11',
routingDecision: 'direct_chat',
userMessage,
}).reason, null);
});
test('direct chat run saves portal reply into an existing agent session', async () => {
const saved = [];
const service = createDirectChatService({
enabled: true,
userAuth: {
async getBillingState() {
return null;
},
async billSessionUsage() {
return null;
},
},
llmProviderService: {
async createChatCompletion() {
return {
ok: true,
model: 'deepseek-chat',
reply: '太湖是中国第三大淡水湖。',
usage: null,
};
},
},
sessionSnapshotService: {
async get(sessionId) {
return {
session: { id: sessionId, name: 'New Chat', updated_at: '2026-07-04T00:00:00.000Z' },
messages: [{
id: 'user-1',
role: 'user',
content: [{ type: 'text', text: 'hi' }],
metadata: { userVisible: true },
}],
};
},
async save(sessionId, userId, session, messages) {
saved.push({ sessionId, userId, session, messages });
},
},
});
const result = await service.run({
userId: 'user-1',
sessionId: '20260704_11',
requestId: 'req-taihu',
routingDecision: 'direct_chat',
userMessage: {
id: 'user-taihu',
role: 'user',
content: [{ type: 'text', text: '我想对太湖有更多的了解' }],
metadata: { displayText: '我想对太湖有更多的了解', userVisible: true },
},
});
assert.equal(result.sessionId, '20260704_11');
assert.equal(saved.length, 2);
assert.equal(saved[1].messages.at(-1)?.metadata?.source, 'portal-direct-chat');
assert.match(saved[1].messages.at(-1)?.content?.[0]?.text ?? '', /太湖/);
});