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:
@@ -0,0 +1,151 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import express from 'express';
|
||||
import { once } from 'node:events';
|
||||
import { createAdminApi } from './admin-routes.mjs';
|
||||
|
||||
async function startTestServer(router) {
|
||||
const app = express();
|
||||
app.use('/admin-api', router);
|
||||
const server = app.listen(0, '127.0.0.1');
|
||||
await once(server, 'listening');
|
||||
const address = server.address();
|
||||
return {
|
||||
server,
|
||||
baseUrl: `http://127.0.0.1:${address.port}`,
|
||||
close: async () => {
|
||||
server.close();
|
||||
await once(server, 'close');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('admin memory-v2 config routes expose config and runtime state', async () => {
|
||||
const updates = [];
|
||||
const router = createAdminApi({
|
||||
jsonBody: express.json(),
|
||||
getToken() {
|
||||
return 'token-admin';
|
||||
},
|
||||
userAuth: {
|
||||
async getMe(token) {
|
||||
if (token !== 'token-admin') return null;
|
||||
return { id: 'admin-1', role: 'admin' };
|
||||
},
|
||||
},
|
||||
llmProviderService: null,
|
||||
memoryV2ConfigService: {
|
||||
async getAdminConfig() {
|
||||
return { config: { chatIntentRouter: { enabled: true } }, updatedAt: 123 };
|
||||
},
|
||||
async updateAdminConfig(patch, { updatedBy }) {
|
||||
updates.push({ patch, updatedBy });
|
||||
return { config: patch, updatedAt: 456, updatedBy };
|
||||
},
|
||||
async getRuntimeState() {
|
||||
return { source: 'admin-db', overrides: { MEMIND_CHAT_LLM_ROUTER_ENABLED: '1' } };
|
||||
},
|
||||
},
|
||||
plazaPosts: null,
|
||||
plazaOps: null,
|
||||
wechatAdmin: null,
|
||||
subscriptionService: null,
|
||||
});
|
||||
|
||||
const server = await startTestServer(router);
|
||||
try {
|
||||
const configRes = await fetch(`${server.baseUrl}/admin-api/memory-v2/config`, {
|
||||
headers: { cookie: 'h5_user_session=token-admin' },
|
||||
});
|
||||
assert.equal(configRes.status, 200);
|
||||
assert.deepEqual(await configRes.json(), {
|
||||
config: { chatIntentRouter: { enabled: true } },
|
||||
updatedAt: 123,
|
||||
});
|
||||
|
||||
const updateRes = await fetch(`${server.baseUrl}/admin-api/memory-v2/config`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
cookie: 'h5_user_session=token-admin',
|
||||
},
|
||||
body: JSON.stringify({ chatIntentRouter: { enabled: false } }),
|
||||
});
|
||||
assert.equal(updateRes.status, 200);
|
||||
assert.deepEqual(updates, [{
|
||||
patch: { chatIntentRouter: { enabled: false } },
|
||||
updatedBy: 'admin-1',
|
||||
}]);
|
||||
|
||||
const runtimeRes = await fetch(`${server.baseUrl}/admin-api/memory-v2/runtime`, {
|
||||
headers: { cookie: 'h5_user_session=token-admin' },
|
||||
});
|
||||
assert.equal(runtimeRes.status, 200);
|
||||
assert.deepEqual(await runtimeRes.json(), {
|
||||
source: 'admin-db',
|
||||
overrides: { MEMIND_CHAT_LLM_ROUTER_ENABLED: '1' },
|
||||
});
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
});
|
||||
|
||||
test('admin system test route executes shared validation service', async () => {
|
||||
const calls = [];
|
||||
const router = createAdminApi({
|
||||
jsonBody: express.json(),
|
||||
getToken() {
|
||||
return 'token-admin';
|
||||
},
|
||||
userAuth: {
|
||||
async getMe(token) {
|
||||
if (token !== 'token-admin') return null;
|
||||
return { id: 'admin-1', role: 'admin' };
|
||||
},
|
||||
},
|
||||
llmProviderService: null,
|
||||
memoryV2ConfigService: null,
|
||||
adminSystemTestService: {
|
||||
async runSkillValidation(input) {
|
||||
calls.push(input);
|
||||
return {
|
||||
ok: true,
|
||||
selectedSkill: input.skillName,
|
||||
account: { username: input.username },
|
||||
summary: { passed: 1, warnings: 0, failed: 0 },
|
||||
steps: [],
|
||||
issues: [],
|
||||
};
|
||||
},
|
||||
},
|
||||
plazaPosts: null,
|
||||
plazaOps: null,
|
||||
wechatAdmin: null,
|
||||
subscriptionService: null,
|
||||
});
|
||||
|
||||
const server = await startTestServer(router);
|
||||
try {
|
||||
const response = await fetch(`${server.baseUrl}/admin-api/system-tests/skill-validation`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
cookie: 'h5_user_session=token-admin',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: 'john',
|
||||
password: 'secret',
|
||||
skillName: 'service-integration-smoke',
|
||||
}),
|
||||
});
|
||||
assert.equal(response.status, 200);
|
||||
assert.deepEqual(calls, [{
|
||||
username: 'john',
|
||||
password: 'secret',
|
||||
skillName: 'service-integration-smoke',
|
||||
}]);
|
||||
assert.equal((await response.json()).ok, true);
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user