feat: 将 ofcx-go backend 收敛为 dsflash-go
This commit is contained in:
+5
-5
@@ -58,11 +58,11 @@
|
||||
"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",
|
||||
"name": "dsflash-go-secret-projection",
|
||||
"secretRef": { "name": "agentrun-v01-provider-dsflash-go", "keys": ["auth.json", "config.toml"] },
|
||||
"projectionPath": "/var/run/agentrun/secrets/dsflash-go-0",
|
||||
"runtimeCopyPath": "/home/agentrun/.codex-dsflash-go",
|
||||
"profile": "dsflash-go",
|
||||
"readOnly": true,
|
||||
"writableCopy": true
|
||||
}
|
||||
|
||||
+5
-5
@@ -757,12 +757,12 @@ function help(): JsonRecord {
|
||||
"runs events <runId> --after-seq <n> --limit <n>",
|
||||
"runs result <runId> [--command-id <commandId>]",
|
||||
"runs cancel <runId> [--reason <text>]",
|
||||
"sessions ps [--state default|running|unread|terminal|idle|all] [--profile codex|deepseek|minimax-m3|M3] [--reader-id <reader>]",
|
||||
"sessions create [sessionId] [--profile codex|deepseek|minimax-m3|M3] [--expires-in-days <n>]",
|
||||
"sessions ps [--state default|running|unread|terminal|idle|all] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--reader-id <reader>]",
|
||||
"sessions create [sessionId] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--expires-in-days <n>]",
|
||||
"sessions storage <sessionId>",
|
||||
"sessions storage <sessionId> --delete",
|
||||
"sessions show <sessionId> [--reader-id <reader>]",
|
||||
"sessions turn [sessionId] --json-file <run-base.json> --prompt-file <file> [--profile minimax-m3|M3] [--runner-json-file <job.json>]",
|
||||
"sessions turn [sessionId] --json-file <run-base.json> --prompt-file <file> [--profile minimax-m3|dsflash-go|M3] [--runner-json-file <job.json>]",
|
||||
"sessions steer <sessionId> --prompt-file <file>",
|
||||
"sessions cancel <sessionId> [--reason <text>]",
|
||||
"sessions trace <sessionId> [--after-seq <n>] [--limit <n>] [--run-id <runId>]",
|
||||
@@ -772,7 +772,7 @@ function help(): JsonRecord {
|
||||
"commands show <commandId> --run-id <runId>",
|
||||
"commands result <commandId> --run-id <runId>",
|
||||
"commands cancel <commandId> [--reason <text>]",
|
||||
"runner start --run-id <runId> [--backend codex|deepseek|minimax-m3]",
|
||||
"runner start --run-id <runId> [--backend codex|deepseek|minimax-m3|dsflash-go]",
|
||||
"runner job --run-id <runId> --command-id <commandId> [--image <image>] [--runner-manager-url <url>] [--idempotency-key <key>]",
|
||||
"runner job --dry-run --run-id <runId> --command-id <commandId> --image <image>",
|
||||
"runner jobs --run-id <runId> [--command-id <commandId>]",
|
||||
@@ -786,7 +786,7 @@ function help(): JsonRecord {
|
||||
"queue cancel <taskId> [--reason <text>]",
|
||||
"queue dispatch <taskId> [--json-file <dispatch.json>] [--idempotency-key <key>] [--image <image>] [--namespace <namespace>]",
|
||||
"queue refresh <taskId>",
|
||||
"secrets codex render --dry-run [--profile codex|deepseek|minimax-m3] [--codex-home <dir>] [--namespace agentrun-v01] [--secret-name <name>]",
|
||||
"secrets codex render --dry-run [--profile codex|deepseek|minimax-m3|dsflash-go] [--codex-home <dir>] [--namespace agentrun-v01] [--secret-name <name>]",
|
||||
"provider-profiles list",
|
||||
"provider-profiles show <profile>",
|
||||
"provider-profiles config <profile>",
|
||||
|
||||
@@ -367,7 +367,7 @@ metadata:
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-ofcx-go"]
|
||||
resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-dsflash-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", "agentrun-v01-provider-ofcx-go"]
|
||||
resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-dsflash-go"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
||||
@@ -51,16 +51,16 @@ export const backendProfileSpecs: readonly BackendProfileSpec[] = [
|
||||
description: "MiniMax M3 OpenAI-compatible profile through Codex app-server stdio",
|
||||
},
|
||||
{
|
||||
profile: "ofcx-go",
|
||||
profile: "dsflash-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",
|
||||
defaultSecretName: "agentrun-v01-provider-dsflash-go",
|
||||
profileIsolation: "profile-scoped-codex-home",
|
||||
description: "OpenCode Zen Go DeepSeek V4 Flash profile through Moon Bridge",
|
||||
description: "DeepSeek V4 Flash profile through OpenCode Zen Go Moon Bridge",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
+1
-1
@@ -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" | "ofcx-go";
|
||||
export type BackendProfile = "codex" | "deepseek" | "minimax-m3" | "dsflash-go";
|
||||
export type QueueTaskState = "pending" | "running" | "completed" | "failed" | "blocked" | "cancelled";
|
||||
export type SessionExecutionState = "idle" | "running" | "terminal";
|
||||
export type SessionAttentionState = "active" | "unread" | "read";
|
||||
|
||||
@@ -137,6 +137,39 @@ ON CONFLICT (profile) DO UPDATE SET
|
||||
updated_at = EXCLUDED.updated_at;
|
||||
`;
|
||||
|
||||
const dsflashGoBackendProfileMigrationSql = `
|
||||
UPDATE agentrun_runs SET backend_profile = 'dsflash-go' WHERE backend_profile = 'ofcx-go';
|
||||
UPDATE agentrun_sessions SET backend_profile = 'dsflash-go' WHERE backend_profile = 'ofcx-go';
|
||||
UPDATE agentrun_runners SET backend_profile = 'dsflash-go' WHERE backend_profile = 'ofcx-go';
|
||||
UPDATE agentrun_queue_tasks SET backend_profile = 'dsflash-go' WHERE backend_profile = 'ofcx-go';
|
||||
UPDATE agentrun_runs
|
||||
SET execution_policy = replace(replace(replace(execution_policy::text,
|
||||
'"profile": "ofcx-go"',
|
||||
'"profile": "dsflash-go"'),
|
||||
'agentrun-v01-provider-ofcx-go',
|
||||
'agentrun-v01-provider-dsflash-go'),
|
||||
'/home/agentrun/.codex-ofcx-go',
|
||||
'/home/agentrun/.codex-dsflash-go')::jsonb
|
||||
WHERE execution_policy::text LIKE '%ofcx-go%';
|
||||
UPDATE agentrun_queue_tasks
|
||||
SET execution_policy = replace(replace(replace(execution_policy::text,
|
||||
'"profile": "ofcx-go"',
|
||||
'"profile": "dsflash-go"'),
|
||||
'agentrun-v01-provider-ofcx-go',
|
||||
'agentrun-v01-provider-dsflash-go'),
|
||||
'/home/agentrun/.codex-ofcx-go',
|
||||
'/home/agentrun/.codex-dsflash-go')::jsonb
|
||||
WHERE execution_policy IS NOT NULL AND execution_policy::text LIKE '%ofcx-go%';
|
||||
DELETE FROM agentrun_backends WHERE profile = 'ofcx-go';
|
||||
INSERT INTO agentrun_backends (profile, capabilities, capacity, health, updated_at)
|
||||
VALUES ${backendCapabilitiesSqlValues(["dsflash-go"])}
|
||||
ON CONFLICT (profile) DO UPDATE SET
|
||||
capabilities = EXCLUDED.capabilities,
|
||||
capacity = EXCLUDED.capacity,
|
||||
health = EXCLUDED.health,
|
||||
updated_at = EXCLUDED.updated_at;
|
||||
`;
|
||||
|
||||
const sessionControlMigrationSql = `
|
||||
ALTER TABLE agentrun_sessions ADD COLUMN IF NOT EXISTS version bigint NOT NULL DEFAULT 1;
|
||||
ALTER TABLE agentrun_sessions ADD COLUMN IF NOT EXISTS execution_state text NOT NULL DEFAULT 'idle';
|
||||
@@ -322,6 +355,11 @@ const postgresMigrations: MigrationDefinition[] = [
|
||||
checksum: checksumSql(sessionStateStorageMigrationSql),
|
||||
sql: sessionStateStorageMigrationSql,
|
||||
},
|
||||
{
|
||||
id: "008_v01_dsflash_go_backend_profile",
|
||||
checksum: checksumSql(dsflashGoBackendProfileMigrationSql),
|
||||
sql: dsflashGoBackendProfileMigrationSql,
|
||||
},
|
||||
];
|
||||
|
||||
export function postgresMigrationContract(): JsonRecord {
|
||||
|
||||
@@ -122,7 +122,7 @@ export async function setProviderProfileConfig(profileValue: string, body: unkno
|
||||
configHashSuffix: shortHash(configToml),
|
||||
updatedAt: objectPath(applied, ["metadata", "annotations", `${credentialAnnotationPrefix}-updated-at`]) ?? new Date().toISOString(),
|
||||
delegatedBy,
|
||||
requiresExternalBridgeUpdate: profile === "deepseek",
|
||||
requiresExternalBridgeUpdate: profile === "deepseek" || profile === "dsflash-go",
|
||||
configTomlPrinted: false,
|
||||
credentialValuesPrinted: false,
|
||||
valuesPrinted: false,
|
||||
@@ -180,7 +180,7 @@ export async function setProviderProfileCredential(profileValue: string, body: u
|
||||
updatedAt: objectPath(applied, ["metadata", "annotations", `${credentialAnnotationPrefix}-updated-at`]) ?? new Date().toISOString(),
|
||||
configSummary: rendered.config.configSummary,
|
||||
delegatedBy,
|
||||
requiresExternalBridgeUpdate: profile === "deepseek",
|
||||
requiresExternalBridgeUpdate: profile === "deepseek" || profile === "dsflash-go",
|
||||
valuesPrinted: false,
|
||||
pollCommands: {
|
||||
show: `./scripts/agentrun provider-profiles show ${profile}`,
|
||||
@@ -297,14 +297,15 @@ function authPayload(apiKey: string): JsonRecord {
|
||||
}
|
||||
|
||||
function renderConfigToml(config: ProfileConfig): string {
|
||||
const { contextWindow, autoCompactTokenLimit } = contextWindowSettings(config.model);
|
||||
return [
|
||||
`model_provider = ${tomlString(config.providerName)}`,
|
||||
`model = ${tomlString(config.model)}`,
|
||||
`review_model = ${tomlString(config.model)}`,
|
||||
"disable_response_storage = true",
|
||||
"network_access = \"enabled\"",
|
||||
"model_context_window = 128000",
|
||||
"model_auto_compact_token_limit = 110000",
|
||||
`model_context_window = ${contextWindow}`,
|
||||
`model_auto_compact_token_limit = ${autoCompactTokenLimit}`,
|
||||
"approvals_reviewer = \"user\"",
|
||||
"",
|
||||
`[model_providers.${config.providerName}]`,
|
||||
@@ -368,8 +369,8 @@ async function existingConfigToml(profile: BackendProfile, options: ProviderProf
|
||||
|
||||
function existingConfigAllowed(profile: BackendProfile, configToml: string): boolean {
|
||||
if (configToml.trim().length === 0) return false;
|
||||
if (profile === "deepseek" && configToml.includes("hyueapi.com")) return false;
|
||||
if (profile === "deepseek" && !configToml.includes("hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local")) return false;
|
||||
if ((profile === "deepseek" || profile === "dsflash-go") && configToml.includes("hyueapi.com")) return false;
|
||||
if ((profile === "deepseek" || profile === "dsflash-go") && !configToml.includes("hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -414,7 +415,7 @@ function defaultConfig(profile: BackendProfile): ProfileConfig {
|
||||
displayName: "OpenAI",
|
||||
};
|
||||
}
|
||||
if (profile === "ofcx-go") {
|
||||
if (profile === "dsflash-go") {
|
||||
return {
|
||||
model: "deepseek-v4-flash",
|
||||
providerName: "opencode",
|
||||
@@ -451,14 +452,21 @@ function validateBaseUrl(profile: BackendProfile, value: string): void {
|
||||
} catch {
|
||||
throw new AgentRunError("schema-invalid", "config.baseUrl must be a valid URL", { httpStatus: 400 });
|
||||
}
|
||||
if (profile === "deepseek" && url.hostname === "hyueapi.com") {
|
||||
throw new AgentRunError("tenant-policy-denied", "deepseek profile must use HWLAB Moon Bridge, not hyueapi.com", { httpStatus: 403 });
|
||||
if ((profile === "deepseek" || profile === "dsflash-go") && url.hostname === "hyueapi.com") {
|
||||
throw new AgentRunError("tenant-policy-denied", `${profile} profile must use HWLAB Moon Bridge, not hyueapi.com`, { httpStatus: 403 });
|
||||
}
|
||||
if (profile === "deepseek" && url.hostname !== "hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local") {
|
||||
throw new AgentRunError("tenant-policy-denied", "deepseek profile baseUrl must point to HWLAB v0.2 Moon Bridge", { httpStatus: 403 });
|
||||
if ((profile === "deepseek" || profile === "dsflash-go") && url.hostname !== "hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local") {
|
||||
throw new AgentRunError("tenant-policy-denied", `${profile} profile baseUrl must point to HWLAB v0.2 Moon Bridge`, { httpStatus: 403 });
|
||||
}
|
||||
}
|
||||
|
||||
function contextWindowSettings(model: string): { contextWindow: number; autoCompactTokenLimit: number } {
|
||||
if (model === "deepseek-v4-pro" || model === "deepseek-v4-flash") {
|
||||
return { contextWindow: 1_000_000, autoCompactTokenLimit: 900_000 };
|
||||
}
|
||||
return { contextWindow: 200_000, autoCompactTokenLimit: 180_000 };
|
||||
}
|
||||
|
||||
function validationExecutionPolicy(profile: BackendProfile, namespace: string): ExecutionPolicy {
|
||||
const spec = requiredSpec(profile);
|
||||
return {
|
||||
|
||||
@@ -13,9 +13,9 @@ const selfTest: SelfTestCase = async () => {
|
||||
(error) => error instanceof AgentRunError && error.failureKind === "infra-failed" && error.message.includes("DATABASE_URL is required"),
|
||||
);
|
||||
const postgresContract = postgresMigrationContract();
|
||||
assert.equal(postgresContract.latestMigrationId, "007_v01_session_state_storage");
|
||||
assert.equal((postgresContract.migrationIds as string[]).includes("007_v01_session_state_storage"), true);
|
||||
assert.ok(typeof (postgresContract.checksums as Record<string, string>)["007_v01_session_state_storage"] === "string" && (postgresContract.checksums as Record<string, string>)["007_v01_session_state_storage"].length > 0);
|
||||
assert.equal(postgresContract.latestMigrationId, "008_v01_dsflash_go_backend_profile");
|
||||
assert.equal((postgresContract.migrationIds as string[]).includes("008_v01_dsflash_go_backend_profile"), true);
|
||||
assert.ok(typeof (postgresContract.checksums as Record<string, string>)["008_v01_dsflash_go_backend_profile"] === "string" && (postgresContract.checksums as Record<string, string>)["008_v01_dsflash_go_backend_profile"].length > 0);
|
||||
assert.equal((postgresContract.checksums as Record<string, string>)["002_v01_backend_profiles"], "928b5c490cc4539cb64ecef34784557601b2724fa2870570f16a53576804e49c");
|
||||
assert.ok(Array.isArray(postgresContract.requiredTables));
|
||||
assert.ok(postgresContract.requiredTables.includes("agentrun_schema_migrations"));
|
||||
|
||||
@@ -86,6 +86,21 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assertRunnerJobDoesNotMountProfile(minimaxRendered.manifest as JsonRecord, "deepseek-0");
|
||||
assertNoSecretLeak(minimaxRendered);
|
||||
|
||||
const dsflashGoItem = await createRunWithCommand(client, { ...context, backendProfile: "dsflash-go" }, "dsflash-go job smoke", "selftest-dsflash-go-job-render", 15_000);
|
||||
const dsflashGoRendered = renderRunnerJobDryRun({
|
||||
run: await client.get(`/api/v1/runs/${dsflashGoItem.runId}`) as RunRecord,
|
||||
commandId: dsflashGoItem.commandId,
|
||||
managerUrl: server.baseUrl,
|
||||
image: "127.0.0.1:5000/agentrun/agentrun-mgr@sha256:1111111111111111111111111111111111111111111111111111111111111111",
|
||||
attemptId: "attempt_selftest_dsflash_go",
|
||||
sourceCommit: "self-test",
|
||||
});
|
||||
assertRunnerJobUsesWritableCodexHome(dsflashGoRendered.manifest as JsonRecord, context.deepseekHome, "dsflash-go-0", "/var/run/agentrun/secrets/dsflash-go-0");
|
||||
assertRunnerJobDoesNotMountProfile(dsflashGoRendered.manifest as JsonRecord, "codex-0");
|
||||
assertRunnerJobDoesNotMountProfile(dsflashGoRendered.manifest as JsonRecord, "deepseek-0");
|
||||
assertRunnerJobDoesNotMountProfile(dsflashGoRendered.manifest as JsonRecord, "minimax-m3-0");
|
||||
assertNoSecretLeak(dsflashGoRendered);
|
||||
|
||||
const fakeKubectl = path.join(context.tmp, "fake-kubectl.js");
|
||||
const createdManifest = path.join(context.tmp, "created-runner-job.json");
|
||||
await writeFile(fakeKubectl, `#!/usr/bin/env bun
|
||||
@@ -193,7 +208,7 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
assert.equal(envMap.get("AGENTRUN_SESSION_PVC_NAMESPACE"), "agentrun-v01");
|
||||
assert.equal(envMap.get("AGENTRUN_SESSION_PVC_MOUNT_PATH"), "/home/agentrun/.codex-codex/sessions");
|
||||
assert.equal(envMap.get("AGENTRUN_CODEX_ROLLOUT_SUBDIR"), "sessions");
|
||||
return { name: "runner-k8s-job", tests: ["runner-k8s-job-dry-run", "runner-k8s-job-deepseek-profile-dry-run", "runner-k8s-job-minimax-m3-profile-dry-run", "runner-k8s-job-create-api", "runner-k8s-job-retention-ttl", "runner-job-transient-env", "runner-job-tool-credential-env", "runner-job-unidesk-ssh-tool-credential-env", "runner-job-unidesk-ssh-transient-env-denied", "runner-k8s-job-session-pvc-volume-and-env"] };
|
||||
return { name: "runner-k8s-job", tests: ["runner-k8s-job-dry-run", "runner-k8s-job-deepseek-profile-dry-run", "runner-k8s-job-minimax-m3-profile-dry-run", "runner-k8s-job-dsflash-go-profile-dry-run", "runner-k8s-job-create-api", "runner-k8s-job-retention-ttl", "runner-job-transient-env", "runner-job-tool-credential-env", "runner-job-unidesk-ssh-tool-credential-env", "runner-job-unidesk-ssh-transient-env-denied", "runner-k8s-job-session-pvc-volume-and-env"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
|
||||
@@ -56,6 +56,16 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.ok(minimaxM3Events.items?.some((event) => event.type === "backend_status" && JSON.stringify(event.payload).includes("minimax-m3")), "minimax-m3 backend_status should include profile metadata");
|
||||
assertNoSecretLeak(minimaxM3Events);
|
||||
|
||||
const dsflashGoHome = path.join(context.tmp, "runtime-dsflash-go-home");
|
||||
const dsflashGo = await createRunWithCommand(client, { ...context, backendProfile: "dsflash-go" }, "hello dsflash-go", "selftest-dsflash-go-turn", 15_000);
|
||||
const dsflashGoResult = await runOnce({ managerUrl: server.baseUrl, runId: dsflashGo.runId, backendProfile: "dsflash-go", codexCommand: context.fakeCodexCommand, codexArgs: context.fakeCodexArgs, codexHome: dsflashGoHome, env: { CODEX_HOME: dsflashGoHome, AGENTRUN_CODEX_SECRET_HOME: context.deepseekHome }, oneShot: true });
|
||||
assert.equal(dsflashGoResult.terminalStatus, "completed");
|
||||
await access(path.join(dsflashGoHome, "auth.json"));
|
||||
await access(path.join(dsflashGoHome, "config.toml"));
|
||||
const dsflashGoEvents = await client.get(`/api/v1/runs/${dsflashGo.runId}/events?afterSeq=0&limit=100`) as { items?: Array<{ type: string; payload: unknown }> };
|
||||
assert.ok(dsflashGoEvents.items?.some((event) => event.type === "backend_status" && JSON.stringify(event.payload).includes("dsflash-go")), "dsflash-go backend_status should include profile metadata");
|
||||
assertNoSecretLeak(dsflashGoEvents);
|
||||
|
||||
await assert.rejects(
|
||||
() => createRunWithCommand(client, { ...context, backendProfile: "deepseek", includeOnlyProfile: "codex" }, "missing deepseek", "selftest-deepseek-missing-secret", 15_000),
|
||||
(error) => error instanceof Error && error.message.includes("requires a matching provider credential"),
|
||||
@@ -217,7 +227,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
await runSessionStorageSubdirCase({ client, managerUrl: server.baseUrl, context });
|
||||
await runSessionStorageNoSecretLeakCase({ client, managerUrl: server.baseUrl, context });
|
||||
|
||||
return { name: "codex-stdio", tests: ["runner-lease-heartbeat", "runner-lease-conflict-recovery", "codex-stdio-fake-turn", "codex-stdio-projected-writable-home", "codex-stdio-deepseek-profile-fake-turn", "codex-stdio-minimax-m3-profile-fake-turn", "codex-stdio-deepseek-missing-secret-no-fallback", "codex-stdio-minimax-m3-missing-secret-no-fallback", "codex-stdio-config-model-authoritative", "codex-stdio-explicit-model-forwarded", "codex-stdio-final-agent-message-only", "codex-stdio-web-search-progress", "codex-stdio-stale-thread-resume-failed", "codex-stdio-live-tool-events", "codex-stdio-noisy-reasoning-suppression", "codex-stdio-missing-turn-result", "codex-stdio-provider-auth-failed", "codex-stdio-provider-rate-limited", "codex-stdio-provider-invalid-tool-call", "codex-stdio-provider-503-rpc-error", "codex-stdio-provider-503-terminal", "codex-stdio-provider-503-retry-event", "codex-stdio-invalid-json", "codex-stdio-timeout", "codex-stdio-idle-timeout-progress-refresh", "codex-stdio-command-failure-keeps-run-open", "codex-stdio-secret-unavailable", "codex-stdio-spawn-failure"] };
|
||||
return { name: "codex-stdio", tests: ["runner-lease-heartbeat", "runner-lease-conflict-recovery", "codex-stdio-fake-turn", "codex-stdio-projected-writable-home", "codex-stdio-deepseek-profile-fake-turn", "codex-stdio-dsflash-go-profile-fake-turn", "codex-stdio-minimax-m3-profile-fake-turn", "codex-stdio-deepseek-missing-secret-no-fallback", "codex-stdio-minimax-m3-missing-secret-no-fallback", "codex-stdio-config-model-authoritative", "codex-stdio-explicit-model-forwarded", "codex-stdio-final-agent-message-only", "codex-stdio-web-search-progress", "codex-stdio-stale-thread-resume-failed", "codex-stdio-live-tool-events", "codex-stdio-noisy-reasoning-suppression", "codex-stdio-missing-turn-result", "codex-stdio-provider-auth-failed", "codex-stdio-provider-rate-limited", "codex-stdio-provider-invalid-tool-call", "codex-stdio-provider-503-rpc-error", "codex-stdio-provider-503-terminal", "codex-stdio-provider-503-retry-event", "codex-stdio-invalid-json", "codex-stdio-timeout", "codex-stdio-idle-timeout-progress-refresh", "codex-stdio-command-failure-keeps-run-open", "codex-stdio-secret-unavailable", "codex-stdio-spawn-failure"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
|
||||
@@ -32,6 +32,12 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.equal(JSON.stringify(minimaxM3SecretPlan).includes("MiniMax-M3"), false);
|
||||
assert.equal(JSON.stringify(minimaxM3SecretPlan).includes("api.minimaxi.com"), false);
|
||||
|
||||
const dsflashGoSecretPlan = await renderCodexProviderSecretPlan({ profile: "dsflash-go", codexHome: context.deepseekHome, dryRun: true });
|
||||
assert.equal(dsflashGoSecretPlan.secretName, "agentrun-v01-provider-dsflash-go");
|
||||
assert.equal(dsflashGoSecretPlan.profile, "dsflash-go");
|
||||
assert.equal(JSON.stringify(dsflashGoSecretPlan).includes("test-token-material-deepseek"), false);
|
||||
assert.equal(JSON.stringify(dsflashGoSecretPlan).includes("deepseek-test"), false);
|
||||
|
||||
await assert.rejects(
|
||||
() => renderCodexProviderSecretPlan({ codexHome: path.join(context.tmp, "missing-codex-home"), dryRun: true }),
|
||||
(error) => error instanceof AgentRunError && error.failureKind === "secret-unavailable",
|
||||
@@ -56,7 +62,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
(error) => error instanceof AgentRunError && error.failureKind === "schema-invalid",
|
||||
);
|
||||
|
||||
return { name: "secret-render", tests: ["codex-secret-dry-run", "deepseek-secret-dry-run", "minimax-m3-secret-dry-run"] };
|
||||
return { name: "secret-render", tests: ["codex-secret-dry-run", "deepseek-secret-dry-run", "minimax-m3-secret-dry-run", "dsflash-go-secret-dry-run"] };
|
||||
};
|
||||
|
||||
export default selfTest;
|
||||
|
||||
@@ -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", "agentrun-v01-provider-ofcx-go"]'), true);
|
||||
for (const profile of ["codex", "deepseek", "minimax-m3", "ofcx-go"]) {
|
||||
assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-dsflash-go"]'), true);
|
||||
for (const profile of ["codex", "deepseek", "minimax-m3", "dsflash-go"]) {
|
||||
assert.equal(gitopsRenderer.includes(`agentrun-v01-provider-${profile}`), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,9 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
async function assertBackendPreflight(client: ManagerClient): Promise<void> {
|
||||
const response = await client.get("/api/v1/backends") as { items?: JsonRecord[] };
|
||||
const items = response.items ?? [];
|
||||
assert.ok(items.length >= 3, "codex/deepseek/minimax-m3 backend capabilities should be visible");
|
||||
assert.ok(items.length >= 4, "codex/deepseek/minimax-m3/dsflash-go backend capabilities should be visible");
|
||||
assert.ok(items.some((item) => item.profile === "minimax-m3"), "minimax-m3 backend capability should be visible");
|
||||
assert.ok(items.some((item) => item.profile === "dsflash-go"), "dsflash-go backend capability should be visible");
|
||||
for (const item of items) {
|
||||
const preflight = item.preflight as JsonRecord;
|
||||
const defaultSecretRef = item.defaultSecretRef as JsonRecord;
|
||||
|
||||
@@ -109,6 +109,7 @@ export function assertNoSecretLeak(value: unknown): void {
|
||||
|
||||
export function profileSecretHome(context: Pick<SelfTestContext, "codexHome"> & Partial<Pick<SelfTestContext, "deepseekHome" | "minimaxM3Home">>, profile: BackendProfile): string {
|
||||
if (profile === "deepseek") return context.deepseekHome ?? context.codexHome;
|
||||
if (profile === "dsflash-go") return context.deepseekHome ?? context.codexHome;
|
||||
if (profile === "minimax-m3") return context.minimaxM3Home ?? context.codexHome;
|
||||
return context.codexHome;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user