Isolate Cursor executor to admin-configured whitelist channel for H5 and WeChat.
Memind CI / Test, build, and release guards (push) Failing after 4m22s

Non-allowlisted users stay on the existing Goose/DeepSeek path; only memindadm whitelist users enter the TKMind Cursor channel on selected intents and channels.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-28 15:27:10 +08:00
parent 02fdcdedc5
commit 416bf7a29a
13 changed files with 339 additions and 42 deletions
+51 -21
View File
@@ -25,6 +25,10 @@ import { wrapRunStreamPayload, writeSseErrorAndEnd } from './sse-event-taxonomy.
import { resolveGoalBindingForAgentRun } from './goal-run-resolve.mjs';
import { enforcePageGenerationCursorRuntime } from './cursor-page-routing.mjs';
import { resolvePreferredCodeExecutor } from './cursor-agent-launch.mjs';
import {
CURSOR_EXECUTOR_CHANNEL,
resolveCursorChannelEligible,
} from './wechat-cursor-executor-policy.mjs';
function envFlag(value) {
return ['1', 'true', 'yes', 'on'].includes(String(value ?? '').trim().toLowerCase());
@@ -188,6 +192,7 @@ export function createPostAgentRunsHandler({
agentRunGateway,
mindSpaceAssetAgent = null,
codeRunPolicyService = null,
cursorExecutorPolicyService = null,
goalRunService = null,
chatIntentRouter = null,
templateCatalogService = null,
@@ -259,12 +264,30 @@ export function createPostAgentRunsHandler({
let requiredExecutor = selectedSkillRuntime.requiredExecutor ?? null;
let requiredReviewExecutor = selectedSkillRuntime.requiredReviewExecutor ?? null;
let cursorChannelEligible = false;
if (cursorExecutorPolicyService?.getEffectivePolicy) {
try {
const cursorPolicy = await cursorExecutorPolicyService.getEffectivePolicy(
request.currentUser.id,
request.currentUser,
);
cursorChannelEligible = resolveCursorChannelEligible({
user: request.currentUser,
channel: CURSOR_EXECUTOR_CHANNEL.H5,
policy: cursorPolicy,
});
} catch {
cursorChannelEligible = false;
}
}
if (!requiredExecutor && !requiredReviewExecutor) {
const pageCursorRuntime = enforcePageGenerationCursorRuntime(userMessage, {
rawToolMode,
taskType,
forceDeepReasoning,
env: process.env,
channelEligible: cursorChannelEligible,
});
userMessage = pageCursorRuntime.userMessage;
rawToolMode = pageCursorRuntime.rawToolMode;
@@ -307,29 +330,36 @@ export function createPostAgentRunsHandler({
const policyTaskType = requiredReviewExecutor
? 'h5_chat_code_task'
: taskType;
if (!codeRunPolicy.enabled) {
response.status(403).json({ message: '代码任务灰度未开启' });
return;
}
if (!codeRunPolicy.userAllowed) {
response.status(403).json({ message: '当前用户未开启代码任务灰度' });
return;
}
const taskTypeAllowlist = codeRunPolicy.taskTypeAllowlist ?? [];
if (
taskTypeAllowlist.length > 0 &&
(
!policyTaskType ||
!taskTypeAllowlist
.map((item) => String(item).toLowerCase())
.includes(policyTaskType.toLowerCase())
)
) {
response.status(403).json({ message: '当前代码任务类型未开启灰度' });
return;
const isCursorChannelRun = cursorChannelEligible && (
requiredExecutor === 'cursor'
|| userMessage?.metadata?.memindRun?.pageCursorDefault === true
);
if (!isCursorChannelRun) {
if (!codeRunPolicy.enabled) {
response.status(403).json({ message: '代码任务灰度未开启' });
return;
}
if (!codeRunPolicy.userAllowed) {
response.status(403).json({ message: '当前用户未开启代码任务灰度' });
return;
}
const taskTypeAllowlist = codeRunPolicy.taskTypeAllowlist ?? [];
if (
taskTypeAllowlist.length > 0 &&
(
!policyTaskType ||
!taskTypeAllowlist
.map((item) => String(item).toLowerCase())
.includes(policyTaskType.toLowerCase())
)
) {
response.status(403).json({ message: '当前代码任务类型未开启灰度' });
return;
}
}
if (
codeRunPolicy.requireValidation
!isCursorChannelRun
&& codeRunPolicy.requireValidation
&& !hasExpectedFileValidation(userMessage)
&& !userMessage?.metadata?.memindRun?.pageCursorDefault
&& !userMessage?.metadata?.memindRun?.cursorAgentDefault