Remove AI config approval flow

This commit is contained in:
npc0-hue
2026-09-22 15:33:32 +08:00
parent 20008b4043
commit a8b5d483a3
54 changed files with 364 additions and 875 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ A game management plugin defines how the platform creates and manages one type o
- Optional remote access methods and remote run capabilities.
- Optional runtime profiles for discovery, lifecycle modes, dependency probes, install plans, log sources, transports, and plugin-owned component declarations.
- Optional plugin pages hosted by platform_web.
- AI/file/log permissions declared for platform authorization, including `ai.mediation=platform` and `ai.configWritePolicy=review-required`.
- AI/file/log permissions declared for platform authorization, including `ai.mediation=platform`. AI configuration requests are dispatched through the platform's typed config-write job path.
- Production lifecycle operations, dependency policy, and disruptive approval requirements.
## Required Directory Plan
@@ -159,7 +159,6 @@
"config.suggest",
"logs.diagnose"
],
"mediation": "platform",
"configWritePolicy": "review-required"
"mediation": "platform"
}
}
@@ -22,7 +22,7 @@ function renderConfigPage(e: ReactLike["createElement"], input: any) {
return renderPanel(e, "配置工作台", "配置入口由插件页面声明,平台只提供运行上下文。", input, [
["文件权限", (input.context?.permissions ?? []).filter((value: string) => value.includes("files")).join(" / ") || "未声明"],
["AI 能力", (input.context?.permissions ?? []).includes("ai.invoke") ? "可请求平台 AI" : "未声明"],
["写入策略", "平台审查后派发"]
["写入策略", "平台校验后直接派发"]
]);
}
@@ -55,6 +55,7 @@
"files.list",
"files.read",
"files.write",
"config.write",
"files.patch",
"logs.read",
"remote.run.files.read",
@@ -294,8 +295,7 @@
"config.suggest",
"logs.diagnose"
],
"mediation": "platform",
"configWritePolicy": "review-required"
"mediation": "platform"
},
"runtimeProfiles": {
"discovery": [
@@ -323,6 +323,7 @@
"process.stop",
"process.restart",
"process.status",
"config.write",
"remote.run.process.start",
"remote.run.process.stop"
],
@@ -62,6 +62,7 @@
"process.status",
"files.list",
"files.read",
"config.write",
"files.patch",
"logs.read",
"remote.ftp.read",
@@ -1071,8 +1072,7 @@
"purposes": [
"config.suggest"
],
"mediation": "platform",
"configWritePolicy": "review-required"
"mediation": "platform"
},
"runtimeProfiles": {
"discovery": [
@@ -1102,6 +1102,7 @@
"process.stop",
"process.restart",
"process.status",
"config.write",
"remote.run.process.start",
"remote.run.process.stop",
"remote.run.rcon.command"
@@ -187,12 +187,11 @@
"fileWorkspace": { "type": "object", "required": ["defaultDirectoryKey", "directories", "files", "configFields"], "additionalProperties": false, "properties": { "defaultDirectoryKey": { "$ref": "#/$defs/logicalKey" }, "directories": { "type": "array", "items": { "$ref": "#/$defs/pluginLogicalDirectory" } }, "files": { "type": "array", "items": { "$ref": "#/$defs/pluginLogicalFile" } }, "configFields": { "type": "array", "items": { "$ref": "#/$defs/pluginConfigField" } } } },
"ai": {
"type": "object",
"required": ["mediation", "configWritePolicy"],
"required": ["mediation"],
"additionalProperties": false,
"properties": {
"purposes": { "type": "array", "items": { "$ref": "#/$defs/aiPurpose" }, "uniqueItems": true },
"mediation": { "const": "platform" },
"configWritePolicy": { "const": "review-required" }
"mediation": { "const": "platform" }
}
}
},
+1 -1
View File
@@ -24,7 +24,7 @@ Plugin pages build execution requests with `createBridgeExecutionRequest` and ha
Execution responses use `requestId`, plugin/page/server scope, action, status, optional result refs, and optional safe errors. Use `parseBridgeExecutionResponse` before reading results so plugin code handles denied, deferred, and failed states uniformly.
AI requests use `createAIInvocationRequest` with an explicit manifest-declared purpose, prompt, and scoped context refs. Use `parseAIInvocationResponse` to consume recommendations, reviewable `diffId` metadata, and safe errors. Plugin code must not choose or receive provider API keys, provider base URLs, bearer tokens, or direct transport details. Config writes require a separate Platform operator approval.
AI requests use `createAIInvocationRequest` with an explicit manifest-declared purpose, prompt, and scoped context refs. Use `parseAIInvocationResponse` to consume recommendations, optional `configExecution` job metadata, and safe errors. For config purposes Platform validates the current config and dispatches the bounded `config.write` job immediately; plugin code must not choose or receive provider API keys, provider base URLs, bearer tokens, or direct transport details.
Artifact open requests use `createArtifactOpenRequest` with an artifact ID that belongs to the current server/job scope. Use `parseArtifactReference` to consume the bridge result. Parsed references contain platform-owned download URLs, filename, content type, size, checksum, expiry, range support, and chunk size; they do not contain bytes or raw storage adapter locations.
+3 -2
View File
@@ -122,7 +122,8 @@ export interface PluginAIInvocationResponse {
purpose: AIPurpose;
status: "ok" | "denied" | "error" | string;
recommendation?: string;
configRecommendation?: { diffId: string; key: string; suggestedConfig: string; diffSummary: string; expiresAt: string };
configRecommendation?: { key: string; suggestedConfig: string; diffSummary: string };
configExecution?: { status: string; jobId: string; capability: string; targetKey?: string; inputRef?: string };
usage?: { model?: string; mocked?: boolean; inputTokens?: number; outputTokens?: number };
error?: PluginBridgeError;
}
@@ -574,7 +575,6 @@ export interface GamePluginManifest {
ai?: {
purposes?: AIPurpose[];
mediation: "platform";
configWritePolicy: "review-required";
};
}
@@ -866,6 +866,7 @@ export function parseAIInvocationResponse(response: PluginAIInvocationResponse):
status: response.status,
recommendation: response.recommendation,
configRecommendation: response.configRecommendation ? { ...response.configRecommendation } : undefined,
configExecution: response.configExecution ? { ...response.configExecution } : undefined,
usage: response.usage ? { ...response.usage } : undefined,
error: response.error ? bridgeError(response.error.code, response.error.message, response.error.details ?? []) : undefined
};