Add per-feature Cursor channel toggles for admin and runtime.
Memind CI / Test, build, and release guards (push) Has been cancelled

Expose page/data/scheduled-task/chat-bridge switches in the智趣体验通道 config so Tang can roll out Cursor paths independently with DeepSeek fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-31 09:40:52 +08:00
parent ac2c87be43
commit 617ff0d1dd
21 changed files with 915 additions and 127 deletions
+33 -9
View File
@@ -58,6 +58,7 @@ import {
shouldPersistSessionStreamEvent,
shouldSkipUpstreamAfterSessionReplay,
} from './session-stream.mjs';
import { resolveCursorChatBridgeEligible } from './wechat-cursor-executor-policy.mjs';
const insecureDispatcher = new Agent({
connect: { rejectUnauthorized: false },
@@ -1172,6 +1173,7 @@ export function createTkmindProxy({
sessionAccess = null,
sessionStreamStore = null,
llmProviderService,
cursorExecutorPolicyService = null,
localFetchAsset,
subscriptionService,
billingConfigService = null,
@@ -1570,7 +1572,7 @@ export function createTkmindProxy({
: null,
},
);
await applySessionLlmProvider(session.id);
await applySessionLlmProvider(session.id, { userId });
return session;
}
@@ -1600,14 +1602,36 @@ export function createTkmindProxy({
}
}
async function applySessionLlmProvider(sessionId) {
async function applySessionLlmProvider(sessionId, { userId = null } = {}) {
if (!llmProviderService || !sessionId) return null;
try {
const target = await resolveTarget(sessionId);
return await llmProviderService.applyBestProviderForSession(
sessionId,
(url, init) => apiFetch(target, apiSecret, `${url.pathname}${url.search}`, init),
);
const fetchImpl = (url, init) =>
apiFetch(target, apiSecret, `${url.pathname}${url.search}`, init);
if (userId && cursorExecutorPolicyService?.getEffectivePolicy) {
try {
const cursorPolicy = await cursorExecutorPolicyService.getEffectivePolicy(userId, {
userId,
});
if (
resolveCursorChatBridgeEligible({
user: { userId },
policy: cursorPolicy,
})
&& typeof llmProviderService.applyCursorChatBridgeForSession === 'function'
) {
return await llmProviderService.applyCursorChatBridgeForSession(sessionId, fetchImpl);
}
} catch (policyErr) {
console.warn(
'Cursor chat bridge policy lookup skipped:',
policyErr instanceof Error ? policyErr.message : policyErr,
);
}
}
return await llmProviderService.applyBestProviderForSession(sessionId, fetchImpl);
} catch (err) {
console.warn(
'LLM provider apply skipped:',
@@ -2027,7 +2051,7 @@ export function createTkmindProxy({
forceDeepReasoning,
disableImageReading: disableImageReading || visionHandlesThisTurn,
});
await applySessionLlmProvider(sessionId);
await applySessionLlmProvider(sessionId, { userId });
await repairSessionToolHistory(sessionId);
const user = await userAuth.getUserById(userId);
@@ -2406,7 +2430,7 @@ export function createTkmindProxy({
});
return;
}
await applySessionLlmProvider(session.id);
await applySessionLlmProvider(session.id, { userId: req.currentUser.id });
}
res.status(upstream.status).json(session);
} catch (err) {
@@ -2491,7 +2515,7 @@ export function createTkmindProxy({
}
}
await applySessionLlmProvider(sessionId);
await applySessionLlmProvider(sessionId, { userId: req.currentUser.id });
res.status(upstream.status).json(payload);
} catch (err) {