diff --git a/deploy/deploy.json b/deploy/deploy.json index 4367cb5..0d5dfa2 100644 --- a/deploy/deploy.json +++ b/deploy/deploy.json @@ -56,6 +56,15 @@ "profile": "minimax-m3", "readOnly": 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": [ diff --git a/scripts/src/gitops-render.ts b/scripts/src/gitops-render.ts index 10b2c37..0b4e6d6 100644 --- a/scripts/src/gitops-render.ts +++ b/scripts/src/gitops-render.ts @@ -367,7 +367,7 @@ metadata: rules: - apiGroups: [""] 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"] --- apiVersion: rbac.authorization.k8s.io/v1 @@ -400,7 +400,7 @@ metadata: rules: - apiGroups: [""] 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"] --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/src/common/backend-profiles.ts b/src/common/backend-profiles.ts index 26e0e0b..ab177b0 100644 --- a/src/common/backend-profiles.ts +++ b/src/common/backend-profiles.ts @@ -50,6 +50,18 @@ export const backendProfileSpecs: readonly BackendProfileSpec[] = [ profileIsolation: "profile-scoped-codex-home", 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[]; diff --git a/src/common/types.ts b/src/common/types.ts index 58ffc41..96cac4d 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -28,7 +28,7 @@ export type FailureKind = export type RunStatus = "pending" | "claimed" | "running" | "completed" | "failed" | "blocked" | "cancelled"; export type CommandState = "pending" | "acknowledged" | "completed" | "failed" | "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 SessionExecutionState = "idle" | "running" | "terminal"; export type SessionAttentionState = "active" | "unread" | "read"; diff --git a/src/mgr/provider-profiles.ts b/src/mgr/provider-profiles.ts index 896ddba..56126da 100644 --- a/src/mgr/provider-profiles.ts +++ b/src/mgr/provider-profiles.ts @@ -414,6 +414,16 @@ function defaultConfig(profile: BackendProfile): ProfileConfig { 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") { return { model: "MiniMax-M3", diff --git a/src/selftest/cases/45-provider-profile-management.ts b/src/selftest/cases/45-provider-profile-management.ts index ef1c9d6..bf3162f 100644 --- a/src/selftest/cases/45-provider-profile-management.ts +++ b/src/selftest/cases/45-provider-profile-management.ts @@ -13,8 +13,8 @@ const selfTest: SelfTestCase = async (context) => { 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('verbs: ["get", "patch", "update"]'), true); - assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3"]'), true); - for (const profile of ["codex", "deepseek", "minimax-m3"]) { + 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", "ofcx-go"]) { assert.equal(gitopsRenderer.includes(`agentrun-v01-provider-${profile}`), true); } @@ -88,7 +88,7 @@ process.exit(1); try { const client = new ManagerClient(server.baseUrl); 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("redacted-fixture"), false);