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:
+27
-3
@@ -164,7 +164,8 @@ import { createScheduleService } from './schedule-service.mjs';
|
||||
import { createFeedbackService } from './user-feedback.mjs';
|
||||
import { startScheduleReminderWorker } from './schedule-reminder-worker.mjs';
|
||||
import { createLlmProviderService, RELAY_BOOTSTRAP } from './llm-providers.mjs';
|
||||
import { createDirectChatService, isDirectChatSessionId, sendDirectChatSessionEvents } from './direct-chat-service.mjs';
|
||||
import { createDirectChatService, isDirectChatSessionId, isPortalDirectChatSnapshot, sendDirectChatSessionEvents } from './direct-chat-service.mjs';
|
||||
import { createManagedChatIntentRouter } from './chat-intent-router.mjs';
|
||||
import { createSessionSnapshotService } from './session-snapshot.mjs';
|
||||
import { createConversationMemoryService } from './conversation-memory.mjs';
|
||||
import { createManagedMemoryV2Runtime } from './memory-v2-runtime.mjs';
|
||||
@@ -285,6 +286,7 @@ if (ACCESS_PASSWORD && !isDatabaseConfigured()) {
|
||||
let userAuth = null;
|
||||
let tkmindProxy = null;
|
||||
let agentRunGateway = null;
|
||||
let chatIntentRouter = null;
|
||||
let toolGateway = null;
|
||||
let directChatService = null;
|
||||
let sessionSnapshotService = null;
|
||||
@@ -523,14 +525,22 @@ async function bootstrapUserAuth() {
|
||||
void llmProviderService.syncSelectedToGoosed().catch((err) => {
|
||||
console.warn('LLM provider boot sync skipped:', err instanceof Error ? err.message : err);
|
||||
});
|
||||
conversationMemoryService = createConversationMemoryService(pool);
|
||||
memoryV2ConfigService = createMemoryV2AdminConfigService(pool);
|
||||
conversationMemoryService = createConversationMemoryService(pool, {
|
||||
llmProviderService,
|
||||
getEffectiveEnv: async () => {
|
||||
const state = await memoryV2ConfigService.getRuntimeState().catch(() => null);
|
||||
return { ...process.env, ...(state?.overrides ?? {}) };
|
||||
},
|
||||
});
|
||||
memoryV2 = await createManagedMemoryV2Runtime({
|
||||
legacyMemoryService: conversationMemoryService,
|
||||
configService: memoryV2ConfigService,
|
||||
mysqlPool: pool,
|
||||
});
|
||||
sessionSnapshotService = createSessionSnapshotService(pool, {
|
||||
conversationMemoryService,
|
||||
memoryV2,
|
||||
});
|
||||
directChatService = createDirectChatService({
|
||||
userAuth,
|
||||
@@ -539,6 +549,11 @@ async function bootstrapUserAuth() {
|
||||
memoryV2,
|
||||
conversationMemoryService,
|
||||
});
|
||||
chatIntentRouter = createManagedChatIntentRouter({
|
||||
llmProviderService,
|
||||
memoryV2,
|
||||
configService: memoryV2ConfigService,
|
||||
});
|
||||
tkmindProxy = createTkmindProxy({
|
||||
apiTarget: API_TARGET,
|
||||
apiTargets: API_TARGETS,
|
||||
@@ -564,6 +579,7 @@ async function bootstrapUserAuth() {
|
||||
tkmindProxy,
|
||||
toolGateway,
|
||||
directChatService,
|
||||
chatIntentRouter,
|
||||
autoDispatch: ['1', 'true', 'yes', 'on'].includes(
|
||||
String(process.env.MEMIND_AGENT_RUN_AUTODISPATCH ?? '1').trim().toLowerCase(),
|
||||
),
|
||||
@@ -4460,7 +4476,11 @@ api.get('/sessions/:sessionId', async (req, res, next) => {
|
||||
const canUseSnapshotCache = hintMc != null && hintUa != null;
|
||||
const mcMatch = snapshot.meta.synced_msg_count === hintMc;
|
||||
const uaMatch = snapshot.meta.source_updated_at === hintUa;
|
||||
if (isDirectChatSessionId(sessionId) || (canUseSnapshotCache && mcMatch && uaMatch)) {
|
||||
if (
|
||||
isDirectChatSessionId(sessionId) ||
|
||||
isPortalDirectChatSnapshot(snapshot) ||
|
||||
(canUseSnapshotCache && mcMatch && uaMatch)
|
||||
) {
|
||||
const sanitizedMessages = sanitizeSessionConversationPublicHtmlLinks(
|
||||
snapshot.messages,
|
||||
req.currentUser,
|
||||
@@ -4560,6 +4580,10 @@ api.get('/sessions/:sessionId/events', async (req, res, next) => {
|
||||
}
|
||||
return sendDirectChatSessionEvents(req, res, snapshot);
|
||||
}
|
||||
const portalDirectSnapshot = await sessionSnapshotService?.get(sessionId).catch(() => null);
|
||||
if (isPortalDirectChatSnapshot(portalDirectSnapshot)) {
|
||||
return sendDirectChatSessionEvents(req, res, portalDirectSnapshot);
|
||||
}
|
||||
const publishDir = resolveMindSpaceUserPublishDir(__dirname, { id: req.currentUser.id });
|
||||
const syncPublicHtmlDuringStream = (event) => {
|
||||
materializePublicHtmlWritesFromSessionEvent(event, { publishDir });
|
||||
|
||||
Reference in New Issue
Block a user