fix: 接入 dsflash-go model catalog

This commit is contained in:
Codex
2026-06-08 23:31:33 +08:00
parent 1bd65a4d1a
commit 6dd8c75528
27 changed files with 485 additions and 123 deletions
+3 -1
View File
@@ -13,9 +13,11 @@ 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, "008_v01_dsflash_go_backend_profile");
assert.equal(postgresContract.latestMigrationId, "009_v01_dsflash_go_model_catalog");
assert.equal((postgresContract.migrationIds as string[]).includes("008_v01_dsflash_go_backend_profile"), true);
assert.equal((postgresContract.migrationIds as string[]).includes("009_v01_dsflash_go_model_catalog"), 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.ok(typeof (postgresContract.checksums as Record<string, string>)["009_v01_dsflash_go_model_catalog"] === "string" && (postgresContract.checksums as Record<string, string>)["009_v01_dsflash_go_model_catalog"].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"));
+27 -1
View File
@@ -96,11 +96,30 @@ const selfTest: SelfTestCase = async (context) => {
sourceCommit: "self-test",
});
assertRunnerJobUsesWritableCodexHome(dsflashGoRendered.manifest as JsonRecord, context.deepseekHome, "dsflash-go-0", "/var/run/agentrun/secrets/dsflash-go-0");
assertRunnerJobSecretKeys(dsflashGoRendered, "dsflash-go", ["auth.json", "config.toml", "model-catalog.json"]);
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 legacyDsflashRun = await client.post("/api/v1/runs", {
tenantId: "unidesk",
projectId: "pikasTech/unidesk",
workspaceRef: { kind: "host-path", path: context.workspace },
providerId: "G14",
backendProfile: "dsflash-go",
executionPolicy: {
sandbox: "workspace-write",
approval: "never",
timeoutMs: 15_000,
network: "default",
secretScope: { allowCredentialEcho: false, providerCredentials: [{ profile: "dsflash-go", secretRef: { name: "agentrun-v01-provider-dsflash-go", keys: ["auth.json", "config.toml"], mountPath: context.deepseekHome } }] },
},
traceSink: null,
}) as RunRecord;
const legacyDsflashCredential = legacyDsflashRun.executionPolicy.secretScope.providerCredentials?.[0];
assert.deepEqual(legacyDsflashCredential?.secretRef.keys, ["auth.json", "config.toml", "model-catalog.json"]);
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
@@ -208,7 +227,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-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"] };
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-dsflash-go-legacy-secretref-normalized", "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()));
}
@@ -278,6 +297,13 @@ function assertRunnerJobUsesWritableCodexHome(manifest: JsonRecord, expectedCode
assert.notEqual(value("CODEX_HOME"), value("AGENTRUN_CODEX_SECRET_HOME"));
}
function assertRunnerJobSecretKeys(rendered: JsonRecord, profile: string, expectedKeys: string[]): void {
const refs = rendered.secretRefs as JsonRecord[];
const ref = refs.find((item) => item.profile === profile);
assert.ok(ref, `${profile} SecretRef summary must be present`);
assert.deepEqual(ref.keys, expectedKeys);
}
function assertRunnerJobDoesNotMountProfile(manifest: JsonRecord, volumeName: string): void {
const spec = manifest.spec as JsonRecord;
const template = spec.template as JsonRecord;
+4 -1
View File
@@ -62,8 +62,10 @@ const selfTest: SelfTestCase = async (context) => {
assert.equal(dsflashGoResult.terminalStatus, "completed");
await access(path.join(dsflashGoHome, "auth.json"));
await access(path.join(dsflashGoHome, "config.toml"));
await access(path.join(dsflashGoHome, "model-catalog.json"));
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");
assert.ok(dsflashGoEvents.items?.some((event) => event.type === "backend_status" && JSON.stringify(event.payload).includes("\"contextWindow\":1000000")), "dsflash-go backend_status should include 1M context metadata");
assertNoSecretLeak(dsflashGoEvents);
await assert.rejects(
@@ -213,6 +215,7 @@ const selfTest: SelfTestCase = async (context) => {
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-401-rpc-error", expectedStatus: "failed", expectedFailureKind: "provider-auth-failed" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-429-terminal", expectedStatus: "failed", expectedFailureKind: "provider-rate-limited" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-invalid-tool-call", expectedStatus: "failed", expectedFailureKind: "provider-invalid-tool-call" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-compact-404-terminal", expectedStatus: "failed", expectedFailureKind: "provider-compact-unsupported" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-rpc-error", expectedStatus: "failed", expectedFailureKind: "provider-unavailable" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-terminal", expectedStatus: "failed", expectedFailureKind: "provider-unavailable" });
await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-retry-event", expectedStatus: "failed", expectedFailureKind: "provider-unavailable", expectRetryError: true });
@@ -227,7 +230,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-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"] };
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-dsflash-go-config-metadata", "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-compact-unsupported", "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()));
}
+2 -1
View File
@@ -35,8 +35,9 @@ const selfTest: SelfTestCase = async (context) => {
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.deepEqual(dsflashGoSecretPlan.keys, ["auth.json", "config.toml", "model-catalog.json"]);
assert.equal(JSON.stringify(dsflashGoSecretPlan).includes("test-token-material-deepseek"), false);
assert.equal(JSON.stringify(dsflashGoSecretPlan).includes("deepseek-test"), false);
assert.equal(JSON.stringify(dsflashGoSecretPlan).includes("deepseek-v4-flash"), false);
await assert.rejects(
() => renderCodexProviderSecretPlan({ codexHome: path.join(context.tmp, "missing-codex-home"), dryRun: true }),
@@ -159,7 +159,7 @@ process.exit(1);
assert.equal(config.configTomlPrinted, true);
assert.equal(JSON.stringify(config).includes("redacted-fixture"), false);
const updatedConfigToml = "model = \"fixture-updated\"\n";
const updatedConfigToml = "model = \"fixture-updated\"\nbase_url = \"http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1\"\n";
const updatedConfig = await client.put("/api/v1/provider-profiles/deepseek/config", {
configToml: updatedConfigToml,
delegatedBy: { system: "hwlab-v02", userId: "u1", username: "tester", requestId: "req-config-selftest" },
@@ -243,10 +243,14 @@ process.exit(1);
const createdData = createdSecretManifest.data as JsonRecord;
const createdAuthJson = Buffer.from(String(createdData["auth.json"]), "base64").toString("utf8");
const createdConfigToml = Buffer.from(String(createdData["config.toml"]), "base64").toString("utf8");
const createdModelCatalog = Buffer.from(String(createdData["model-catalog.json"]), "base64").toString("utf8");
assert.equal(createdAuthJson.includes(secretText), true);
assert.equal(createdAuthJson.includes("OPENAI_API_KEY"), true);
assert.equal(createdConfigToml.includes("deepseek-v4-flash"), true);
assert.equal(createdConfigToml.includes("model_catalog_json = \"/home/agentrun/.codex-dsflash-go/model-catalog.json\""), true);
assert.equal(createdConfigToml.includes("hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local"), true);
assert.equal(JSON.parse(createdModelCatalog).models[0].context_window, 1000000);
assert.equal(JSON.parse(createdModelCatalog).models[0].auto_compact_token_limit, 900000);
const dsflashShown = await client.get("/api/v1/provider-profiles/dsflash-go") as JsonRecord;
assert.equal(dsflashShown.configured, true);
assert.equal(dsflashShown.failureKind, null);
@@ -341,7 +345,7 @@ process.exit(1);
assert.equal(finalValidation.status, "completed");
assert.equal(JSON.stringify(finalValidation).includes(secretText), false);
assertNoSecretLeak(finalValidation);
return { name: "provider-profile-management", tests: ["provider-profiles-list-redacted", "provider-profile-config", "provider-profile-set-key-redacted", "provider-profile-set-auth-json-redacted", "provider-profile-secret-replace-annotation-cleanup", "provider-profile-secret-create-upsert", "provider-profile-config-only-create", "provider-profile-dynamic-slug-roundtrip", "provider-profile-remove-builtin", "provider-profile-remove-dynamic-slug", "provider-profile-deepseek-moon-bridge", "provider-profile-manager-secret-rbac", "provider-profile-validation-runner-job"] };
return { name: "provider-profile-management", tests: ["provider-profiles-list-redacted", "provider-profile-config", "provider-profile-set-key-redacted", "provider-profile-set-auth-json-redacted", "provider-profile-secret-replace-annotation-cleanup", "provider-profile-secret-create-upsert", "provider-profile-config-only-create", "provider-profile-dsflash-go-model-catalog", "provider-profile-dynamic-slug-roundtrip", "provider-profile-remove-builtin", "provider-profile-remove-dynamic-slug", "provider-profile-deepseek-moon-bridge", "provider-profile-manager-secret-rbac", "provider-profile-validation-runner-job"] };
} finally {
await new Promise<void>((resolve) => server.server.close(() => resolve()));
}
+14
View File
@@ -128,6 +128,20 @@ for await (const line of rl) {
respond(message.id, { turn });
continue;
}
if (mode === "provider-compact-404-terminal") {
turnCounter += 1;
const turn = {
id: `turn_selftest_${turnCounter}`,
status: "failed",
error: {
message: "Error running remote compact task: unexpected status 404 Not Found: 404 page not found, url: http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1/responses/compact",
},
};
notify("turn/started", { turn: { id: turn.id, status: "running" } });
notify("turn/completed", { turn });
respond(message.id, { turn });
continue;
}
if (mode === "provider-503-retry-event") {
turnCounter += 1;
const turn = {
+4 -2
View File
@@ -5,6 +5,7 @@ import assert from "node:assert/strict";
import { ManagerClient } from "../mgr/client.js";
import type { BackendProfile, JsonRecord } from "../common/types.js";
import { backendProfileSpec } from "../common/backend-profiles.js";
import { dsflashGoModelCatalogJson } from "../common/model-catalogs.js";
export interface SelfTestContext {
root: string;
@@ -41,7 +42,8 @@ export async function createSelfTestContext(root: string): Promise<SelfTestConte
await writeFile(path.join(codexHome, "auth.json"), JSON.stringify({ token: "test-token-material" }));
await writeFile(path.join(codexHome, "config.toml"), "model = \"gpt-test\"\n");
await writeFile(path.join(deepseekHome, "auth.json"), JSON.stringify({ token: "test-token-material-deepseek" }));
await writeFile(path.join(deepseekHome, "config.toml"), "model = \"deepseek-test\"\n");
await writeFile(path.join(deepseekHome, "config.toml"), "model_provider = \"opencode\"\nmodel = \"deepseek-v4-flash\"\nreview_model = \"deepseek-v4-flash\"\nmodel_context_window = 1000000\nmodel_auto_compact_token_limit = 900000\nmodel_catalog_json = \"model-catalog.json\"\n[model_providers.opencode]\nname = \"OpenCode\"\nbase_url = \"http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1\"\nwire_api = \"responses\"\nrequires_openai_auth = true\n");
await writeFile(path.join(deepseekHome, "model-catalog.json"), dsflashGoModelCatalogJson());
await writeFile(path.join(minimaxM3Home, "auth.json"), JSON.stringify({ token: "test-token-material-minimax-m3" }));
await writeFile(path.join(minimaxM3Home, "config.toml"), "model = \"MiniMax-M3\"\nmodel_provider = \"minimax\"\n[model_providers.minimax]\nname = \"MiniMax\"\nbase_url = \"https://api.minimaxi.com/v1\"\nenv_key = \"MINIMAX_API_KEY\"\nwire_api = \"responses\"\n");
await writeFile(path.join(workspace, "README.md"), "self-test workspace\n");
@@ -93,7 +95,7 @@ function providerCredentials(context: Pick<SelfTestContext, "codexHome"> & Parti
profile,
secretRef: {
name: backendProfileSpec(profile)?.defaultSecretName ?? `agentrun-v01-provider-${profile}`,
keys: ["auth.json", "config.toml"],
keys: [...(backendProfileSpec(profile)?.requiredSecretKeys ?? ["auth.json", "config.toml"])],
mountPath: profileSecretHome(context, profile),
},
}));