feat: add memindadm runtime policy for agent code runs (Phase 1.5)

Persist code-run gates in admin DB and expose them via /auth/status so H5 can honor runtime policy without VITE rebuilds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-23 21:33:27 +08:00
parent 13f5c740a1
commit 239c41f935
12 changed files with 639 additions and 43 deletions
+32 -5
View File
@@ -1,4 +1,4 @@
import type { MindSpaceChatContext } from '../types';
import type { MindSpaceChatContext, AgentCodeRunClientPolicy } from '../types';
export type AgentRunCreateOptions = {
toolMode?: 'chat' | 'code';
@@ -32,6 +32,33 @@ export const agentPageDataDevAutodetectEnabled = envFlag(
import.meta.env.VITE_AGENT_PAGE_DATA_DEV_AUTODETECT,
);
let runtimeAgentCodeRunPolicy: AgentCodeRunClientPolicy | null = null;
export function applyAgentCodeRunClientPolicy(policy: AgentCodeRunClientPolicy | null) {
runtimeAgentCodeRunPolicy = policy;
}
function clientCodeRunsEnabled(): boolean {
if (runtimeAgentCodeRunPolicy?.codeRun?.enabled != null) {
return runtimeAgentCodeRunPolicy.codeRun.enabled;
}
return agentCodeRunsEnabled;
}
function clientCodeRunsAutodetectEnabled(): boolean {
if (runtimeAgentCodeRunPolicy?.codeRun?.generalAutodetect != null) {
return runtimeAgentCodeRunPolicy.codeRun.generalAutodetect;
}
return agentCodeRunsAutodetectEnabled;
}
function clientPageDataDevAutodetectEnabled(): boolean {
if (runtimeAgentCodeRunPolicy?.codeRun?.pageDataDevAutodetect != null) {
return runtimeAgentCodeRunPolicy.codeRun.pageDataDevAutodetect;
}
return agentPageDataDevAutodetectEnabled;
}
export const PAGE_DATA_DEV_TASK_TYPE = 'page_data_dev';
function parseUserIdSet(value: unknown): Set<string> {
@@ -46,7 +73,7 @@ function parseUserIdSet(value: unknown): Set<string> {
const agentCodeRunUserIds = parseUserIdSet(import.meta.env.VITE_AGENT_CODE_RUNS_USER_IDS);
export function agentCodeRunsEnabledForUser(userId?: string | null): boolean {
if (!agentCodeRunsEnabled) return false;
if (!clientCodeRunsEnabled()) return false;
if (agentCodeRunUserIds.size === 0) return true;
return Boolean(userId && agentCodeRunUserIds.has(userId));
}
@@ -68,7 +95,7 @@ export function isPageDataDevTaskText(text: string): boolean {
}
export function resolvePageDataDevTaskType(text: string): string | null {
if (!agentPageDataDevAutodetectEnabled) return null;
if (!clientPageDataDevAutodetectEnabled()) return null;
return isPageDataDevTaskText(text) ? PAGE_DATA_DEV_TASK_TYPE : null;
}
@@ -263,8 +290,8 @@ export function resolveAgentRunOptions(
{
taskType = 'code_task',
forceCode = false,
allowAutodetect = agentCodeRunsAutodetectEnabled,
allowPageDataDevAutodetect = agentPageDataDevAutodetectEnabled,
allowAutodetect = clientCodeRunsAutodetectEnabled(),
allowPageDataDevAutodetect = clientPageDataDevAutodetectEnabled(),
userId = null,
requestId = null,
mindspaceContext = null,