mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix: normalize gemini auth provider config
This commit is contained in:
@@ -131,6 +131,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Google/Gemini: normalize retired Gemini 3 Pro Preview ids inside emitted Google provider model config, so regenerated models.json rows test `google/gemini-3.1-pro-preview`.
|
||||
- Google/Gemini: normalize retired Gemini 3 Pro Preview ids for explicit OpenAI-compatible Google and Gemini CLI provider configs, so emitted config targets `google/gemini-3.1-pro-preview`.
|
||||
- Google/Gemini: normalize retired Gemini 3 Pro Preview ids preserved from existing merged models.json providers so config emission keeps targeting `google/gemini-3.1-pro-preview`.
|
||||
- Google/Gemini: normalize retired Gemini 3 Pro Preview ids inside provider auth config patches so setup-emitted provider catalogs test `google/gemini-3.1-pro-preview`.
|
||||
- GitHub Copilot: mint short-lived Copilot API tokens with the same `vscode-chat` integration identity used by runtime requests, and refresh legacy cached tokens missing that identity so image-capable Copilot models no longer inherit the `copilot-language-server` scope. Fixes #79946, #80074. Thanks @TurboTheTurtle.
|
||||
- Plugins/doctor: drop stale managed npm install records when `openclaw doctor --fix` removes npm packages that shadow bundled plugins, so the rebuilt registry no longer resurrects the removed package metadata.
|
||||
- Discord/voice: reuse or suppress late realtime consult tool calls without stealing newer speaker context or speaking forced fallback answers twice.
|
||||
|
||||
@@ -154,6 +154,36 @@ describe("applyProviderAuthConfigPatch", () => {
|
||||
"google/gemini-3.1-pro-preview": {},
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes retired Google Gemini provider catalog rows from provider config patches", () => {
|
||||
const patch = {
|
||||
models: {
|
||||
providers: {
|
||||
google: {
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
|
||||
api: "openai-completions",
|
||||
apiKey: "GOOGLE_API_KEY",
|
||||
models: [
|
||||
{
|
||||
id: "google/gemini-3-pro-preview",
|
||||
name: "Gemini 3 Pro Preview",
|
||||
input: ["text", "image"],
|
||||
reasoning: true,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 1_048_576,
|
||||
maxTokens: 65_536,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies OpenClawConfig;
|
||||
|
||||
const next = applyProviderAuthConfigPatch({}, patch);
|
||||
|
||||
expect(next.models?.providers?.google?.models?.[0]?.id).toBe("google/gemini-3.1-pro-preview");
|
||||
expect(next.models?.providers?.google?.api).toBe("openai-completions");
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyDefaultModel", () => {
|
||||
|
||||
@@ -3,6 +3,8 @@ import {
|
||||
normalizeAgentModelMapForConfig,
|
||||
normalizeAgentModelRefForConfig,
|
||||
} from "../config/model-input.js";
|
||||
import { normalizeProviderConfigForConfigDefaults } from "../config/provider-policy.js";
|
||||
import type { ModelProviderConfig } from "../config/types.models.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
@@ -119,12 +121,96 @@ function normalizeAgentModelMapForWrite(value: unknown): unknown {
|
||||
return normalizeAgentModelMapForConfig(value);
|
||||
}
|
||||
|
||||
function normalizeConfigModelRefsForWrite(cfg: OpenClawConfig): OpenClawConfig {
|
||||
const defaults = cfg.agents?.defaults;
|
||||
if (!defaults) {
|
||||
const GOOGLE_CONFIG_MODEL_PROVIDERS = new Set(["google", "google-gemini-cli", "google-vertex"]);
|
||||
|
||||
function normalizeProviderCatalogModelIdForWrite(provider: string, modelId: string): string {
|
||||
const trimmed = modelId.trim();
|
||||
if (!trimmed) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
const slash = trimmed.indexOf("/");
|
||||
if (slash > 0 && slash < trimmed.length - 1) {
|
||||
return normalizeAgentModelRefForConfig(trimmed);
|
||||
}
|
||||
|
||||
const providerId = normalizeProviderId(provider);
|
||||
if (!GOOGLE_CONFIG_MODEL_PROVIDERS.has(providerId)) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
const normalizedQualified = normalizeAgentModelRefForConfig(`${providerId}/${trimmed}`);
|
||||
const prefix = `${providerId}/`;
|
||||
return normalizedQualified.startsWith(prefix)
|
||||
? normalizedQualified.slice(prefix.length)
|
||||
: normalizedQualified;
|
||||
}
|
||||
|
||||
function normalizeProviderCatalogModelIdsForWrite(
|
||||
provider: string,
|
||||
providerConfig: ModelProviderConfig,
|
||||
): ModelProviderConfig {
|
||||
const models = providerConfig.models;
|
||||
if (!Array.isArray(models) || models.length === 0) {
|
||||
return providerConfig;
|
||||
}
|
||||
|
||||
let mutated = false;
|
||||
const nextModels = models.map((model) => {
|
||||
const nextId = normalizeProviderCatalogModelIdForWrite(provider, model.id);
|
||||
if (nextId === model.id) {
|
||||
return model;
|
||||
}
|
||||
mutated = true;
|
||||
return Object.assign({}, model, { id: nextId });
|
||||
});
|
||||
|
||||
return mutated ? { ...providerConfig, models: nextModels } : providerConfig;
|
||||
}
|
||||
|
||||
function normalizeModelProviderConfigsForWrite(cfg: OpenClawConfig): OpenClawConfig {
|
||||
const providers = cfg.models?.providers;
|
||||
if (!providers) {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
let mutated = false;
|
||||
const nextProviders = { ...providers };
|
||||
for (const [provider, providerConfig] of Object.entries(providers)) {
|
||||
const normalizedProviderConfig = normalizeProviderCatalogModelIdsForWrite(
|
||||
provider,
|
||||
normalizeProviderConfigForConfigDefaults({
|
||||
provider,
|
||||
providerConfig,
|
||||
}),
|
||||
);
|
||||
if (normalizedProviderConfig === providerConfig) {
|
||||
continue;
|
||||
}
|
||||
nextProviders[provider] = normalizedProviderConfig;
|
||||
mutated = true;
|
||||
}
|
||||
|
||||
if (!mutated) {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
models: {
|
||||
...cfg.models,
|
||||
providers: nextProviders,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeConfigModelRefsForWrite(cfg: OpenClawConfig): OpenClawConfig {
|
||||
const providerNormalized = normalizeModelProviderConfigsForWrite(cfg);
|
||||
const defaults = providerNormalized.agents?.defaults;
|
||||
if (!defaults) {
|
||||
return providerNormalized;
|
||||
}
|
||||
|
||||
const nextDefaults: NonNullable<NonNullable<OpenClawConfig["agents"]>["defaults"]> = {
|
||||
...defaults,
|
||||
};
|
||||
@@ -136,9 +222,9 @@ function normalizeConfigModelRefsForWrite(cfg: OpenClawConfig): OpenClawConfig {
|
||||
}
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
...providerNormalized,
|
||||
agents: {
|
||||
...cfg.agents,
|
||||
...providerNormalized.agents,
|
||||
defaults: nextDefaults,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user