























@@ -1,3 +1,6 @@
1+import fs from "node:fs/promises";
2+import os from "node:os";
3+import path from "node:path";
14import { beforeAll, describe, expect, it } from "vitest";
25import type { OpenClawConfig } from "../config/config.js";
36import { createConfigRuntimeEnv } from "../config/env-vars.js";
@@ -50,6 +53,24 @@ function createImplicitOpenAiProvider(overrides: Partial<ProviderConfig> = {}):
5053};
5154}
525556+function createImplicitGoogleVertexProvider(): ProviderConfig {
57+return {
58+baseUrl: "https://{location}-aiplatform.googleapis.com",
59+api: "google-vertex",
60+models: [
61+{
62+id: "gemini-2.5-pro",
63+name: "Gemini 2.5 Pro",
64+reasoning: true,
65+input: ["text", "image"],
66+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
67+contextWindow: 1_048_576,
68+maxTokens: 65_536,
69+},
70+],
71+};
72+}
73+5374async function resolveProvidersForConfigEnvTest(params: {
5475cfg: OpenClawConfig;
5576onResolveImplicitProviders: (env: NodeJS.ProcessEnv) => void;
@@ -403,6 +424,72 @@ describe("models-config", () => {
403424]);
404425});
405426427+it("keeps google-vertex static catalog rows when an auth profile supplies the API key", async () => {
428+const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-google-vertex-models-"));
429+try {
430+await fs.writeFile(
431+path.join(agentDir, "auth-profiles.json"),
432+`${JSON.stringify(
433+ {
434+ version: 1,
435+ profiles: {
436+ "google-vertex:default": {
437+ type: "api_key",
438+ provider: "google-vertex",
439+ keyRef: { source: "env", provider: "default", id: "GOOGLE_CLOUD_API_KEY" },
440+ },
441+ },
442+ },
443+ null,
444+ 2,
445+ )}\n`,
446+);
447+448+const plan = await planOpenClawModelsJsonWithDeps(
449+{
450+cfg: {
451+agents: {
452+defaults: {
453+models: {
454+"google-vertex/gemini-2.5-pro": {},
455+},
456+model: { primary: "google-vertex/gemini-2.5-pro" },
457+},
458+},
459+models: { providers: {} },
460+},
461+ agentDir,
462+env: {},
463+existingRaw: "",
464+existingParsed: null,
465+},
466+{
467+resolveImplicitProviders: async () => ({
468+"google-vertex": createImplicitGoogleVertexProvider(),
469+}),
470+},
471+);
472+473+expect(plan.action).toBe("write");
474+if (plan.action !== "write") {
475+throw new Error("Expected models.json write plan");
476+}
477+const parsed = JSON.parse(plan.contents) as {
478+providers?: Record<
479+string,
480+{ apiKey?: string; api?: string; models?: Array<{ id?: string }> }
481+>;
482+};
483+expect(parsed.providers?.["google-vertex"]?.api).toBe("google-vertex");
484+expect(parsed.providers?.["google-vertex"]?.apiKey).toBe("GOOGLE_CLOUD_API_KEY");
485+expect(parsed.providers?.["google-vertex"]?.models?.map((model) => model.id)).toEqual([
486+"gemini-2.5-pro",
487+]);
488+} finally {
489+await fs.rm(agentDir, { recursive: true, force: true });
490+}
491+});
492+406493it("uses config env.vars entries for implicit provider discovery without mutating process.env", async () => {
407494await withTempEnv(["OPENROUTER_API_KEY", TEST_ENV_VAR], async () => {
408495unsetEnv(["OPENROUTER_API_KEY", TEST_ENV_VAR]);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。