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
+41 -9
View File
@@ -67,8 +67,35 @@ function resolveDisplayTitle(session, messages) {
return deriveTitleFromMessages(messages);
}
async function syncConversationMemory({
memoryV2 = null,
conversationMemoryService = null,
sessionId,
userId,
messages,
logger = console,
} = {}) {
if (memoryV2?.write) {
const result = await memoryV2.write({ userId, sessionId, messages });
if (result?.skipped && result?.reason === 'disabled') return result;
if (!result?.ok && !result?.skipped) {
logger?.warn?.(
'[snapshot] memory v2 write degraded:',
result?.reason ?? 'unknown',
);
}
return result;
}
if (conversationMemoryService?.isEnabled?.()) {
return conversationMemoryService.saveAndAnalyze(sessionId, userId, messages);
}
return null;
}
export function createSessionSnapshotService(pool, options = {}) {
const conversationMemoryService = options.conversationMemoryService ?? null;
const memoryV2 = options.memoryV2 ?? null;
const logger = options.logger ?? console;
function isEnabled() {
return process.env.SESSION_SNAPSHOT_CACHE_ENABLED !== '0';
@@ -145,15 +172,20 @@ export function createSessionSnapshotService(pool, options = {}) {
now,
],
);
if (conversationMemoryService?.isEnabled?.()) {
void conversationMemoryService
.saveAndAnalyze(sessionId, userId, messages)
.catch((err) => {
console.warn(
'[snapshot] conversation memory sync failed:',
err instanceof Error ? err.message : err,
);
});
if (memoryV2?.write || conversationMemoryService?.isEnabled?.()) {
void syncConversationMemory({
memoryV2,
conversationMemoryService,
sessionId,
userId,
messages,
logger,
}).catch((err) => {
logger?.warn?.(
'[snapshot] conversation memory sync failed:',
err instanceof Error ? err.message : err,
);
});
}
} catch (err) {
// Non-fatal: log and continue; caller falls back to Goose.