feat: add ofcx-go provider profile for OpenCode Zen Go DeepSeek V4 Flash

- Add ofcx-go to BackendProfile type union
- Add ofcx-go backend profile spec (Codex app-server stdio)
- Add defaultConfig for ofcx-go (deepseek-v4-flash via Moon Bridge)
- Add Secret mount in deploy.json for runner projection
- Add RBAC access for ofcx-go provider secret
- Update self-test to cover 4 profiles
This commit is contained in:
Codex
2026-06-07 20:14:52 +08:00
parent 0ff445e182
commit 3afb2bf8ec
6 changed files with 37 additions and 6 deletions
+9
View File
@@ -56,6 +56,15 @@
"profile": "minimax-m3", "profile": "minimax-m3",
"readOnly": true, "readOnly": true,
"writableCopy": true "writableCopy": true
},
{
"name": "ofcx-go-secret-projection",
"secretRef": { "name": "agentrun-v01-provider-ofcx-go", "keys": ["auth.json", "config.toml"] },
"projectionPath": "/var/run/agentrun/secrets/ofcx-go-0",
"runtimeCopyPath": "/home/agentrun/.codex-ofcx-go",
"profile": "ofcx-go",
"readOnly": true,
"writableCopy": true
} }
], ],
"env": [ "env": [
+2 -2
View File
@@ -367,7 +367,7 @@ metadata:
rules: rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["secrets"] resources: ["secrets"]
resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3"] resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-ofcx-go"]
verbs: ["get", "patch", "update"] verbs: ["get", "patch", "update"]
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
@@ -400,7 +400,7 @@ metadata:
rules: rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["secrets"] resources: ["secrets"]
resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3"] resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-ofcx-go"]
verbs: ["get"] verbs: ["get"]
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
+12
View File
@@ -50,6 +50,18 @@ export const backendProfileSpecs: readonly BackendProfileSpec[] = [
profileIsolation: "profile-scoped-codex-home", profileIsolation: "profile-scoped-codex-home",
description: "MiniMax M3 OpenAI-compatible profile through Codex app-server stdio", description: "MiniMax M3 OpenAI-compatible profile through Codex app-server stdio",
}, },
{
profile: "ofcx-go",
backendKind: "codex-app-server-stdio",
protocol: "codex-app-server-jsonrpc-stdio",
transport: "stdio",
command: "codex app-server --listen stdio://",
status: "registered",
requiredSecretKeys: ["auth.json", "config.toml"],
defaultSecretName: "agentrun-v01-provider-ofcx-go",
profileIsolation: "profile-scoped-codex-home",
description: "OpenCode Zen Go DeepSeek V4 Flash profile through Moon Bridge",
},
]; ];
export const backendProfiles = backendProfileSpecs.map((item) => item.profile) as readonly BackendProfile[]; export const backendProfiles = backendProfileSpecs.map((item) => item.profile) as readonly BackendProfile[];
+1 -1
View File
@@ -28,7 +28,7 @@ export type FailureKind =
export type RunStatus = "pending" | "claimed" | "running" | "completed" | "failed" | "blocked" | "cancelled"; export type RunStatus = "pending" | "claimed" | "running" | "completed" | "failed" | "blocked" | "cancelled";
export type CommandState = "pending" | "acknowledged" | "completed" | "failed" | "cancelled"; export type CommandState = "pending" | "acknowledged" | "completed" | "failed" | "cancelled";
export type TerminalStatus = "completed" | "failed" | "blocked" | "cancelled"; export type TerminalStatus = "completed" | "failed" | "blocked" | "cancelled";
export type BackendProfile = "codex" | "deepseek" | "minimax-m3"; export type BackendProfile = "codex" | "deepseek" | "minimax-m3" | "ofcx-go";
export type QueueTaskState = "pending" | "running" | "completed" | "failed" | "blocked" | "cancelled"; export type QueueTaskState = "pending" | "running" | "completed" | "failed" | "blocked" | "cancelled";
export type SessionExecutionState = "idle" | "running" | "terminal"; export type SessionExecutionState = "idle" | "running" | "terminal";
export type SessionAttentionState = "active" | "unread" | "read"; export type SessionAttentionState = "active" | "unread" | "read";
+10
View File
@@ -414,6 +414,16 @@ function defaultConfig(profile: BackendProfile): ProfileConfig {
displayName: "OpenAI", displayName: "OpenAI",
}; };
} }
if (profile === "ofcx-go") {
return {
model: "deepseek-v4-flash",
providerName: "opencode",
baseUrl: "http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1",
envKey: "OPENAI_API_KEY",
wireApi: "responses",
displayName: "OpenCode",
};
}
if (profile === "minimax-m3") { if (profile === "minimax-m3") {
return { return {
model: "MiniMax-M3", model: "MiniMax-M3",
@@ -13,8 +13,8 @@ const selfTest: SelfTestCase = async (context) => {
const gitopsRenderer = await readFile(path.join(context.root, "scripts/src/gitops-render.ts"), "utf8"); const gitopsRenderer = await readFile(path.join(context.root, "scripts/src/gitops-render.ts"), "utf8");
assert.equal(gitopsRenderer.includes("agentrun-v01-mgr-provider-secret-manager"), true); assert.equal(gitopsRenderer.includes("agentrun-v01-mgr-provider-secret-manager"), true);
assert.equal(gitopsRenderer.includes('verbs: ["get", "patch", "update"]'), true); assert.equal(gitopsRenderer.includes('verbs: ["get", "patch", "update"]'), true);
assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3"]'), true); assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-ofcx-go"]'), true);
for (const profile of ["codex", "deepseek", "minimax-m3"]) { for (const profile of ["codex", "deepseek", "minimax-m3", "ofcx-go"]) {
assert.equal(gitopsRenderer.includes(`agentrun-v01-provider-${profile}`), true); assert.equal(gitopsRenderer.includes(`agentrun-v01-provider-${profile}`), true);
} }
@@ -88,7 +88,7 @@ process.exit(1);
try { try {
const client = new ManagerClient(server.baseUrl); const client = new ManagerClient(server.baseUrl);
const list = await client.get("/api/v1/provider-profiles") as JsonRecord; const list = await client.get("/api/v1/provider-profiles") as JsonRecord;
assert.equal(list.count, 3); assert.equal(list.count, 4);
assert.equal(JSON.stringify(list).includes("auth.json"), true); assert.equal(JSON.stringify(list).includes("auth.json"), true);
assert.equal(JSON.stringify(list).includes("redacted-fixture"), false); assert.equal(JSON.stringify(list).includes("redacted-fixture"), false);