





















@@ -390,9 +390,10 @@ export function normalizeLegacyOpenAICodexModelsAddMetadata(
390390return cfg;
391391}
392392393+const rawProviders: Record<string, unknown> = rawModels.providers;
393394let providersChanged = false;
394-const nextProviders = { ...rawModels.providers };
395-for (const [providerId, rawProvider] of Object.entries(rawModels.providers)) {
395+const nextProviders: Record<string, unknown> = { ...rawProviders };
396+for (const [providerId, rawProvider] of Object.entries(rawProviders)) {
396397if (normalizeProviderId(providerId) !== "openai-codex" || !isRecord(rawProvider)) {
397398continue;
398399}
@@ -413,7 +414,7 @@ export function normalizeLegacyOpenAICodexModelsAddMetadata(
413414) {
414415providerChanged = true;
415416const safeProviderId = sanitizeForLog(providerId);
416-const safeModelId = sanitizeForLog(model.id);
417+const safeModelId = sanitizeForLog(normalizeOptionalString(model.id) ?? "unknown");
417418changes.push(
418419`Marked models.providers.${safeProviderId}.models.${safeModelId} as /models add metadata so official OpenAI Codex metadata can override it.`,
419420);
@@ -446,6 +447,77 @@ export function normalizeLegacyOpenAICodexModelsAddMetadata(
446447};
447448}
448449450+export function normalizeLegacyOpenAIModelProviderApi(
451+cfg: OpenClawConfig,
452+changes: string[],
453+): OpenClawConfig {
454+const rawModels = cfg.models;
455+if (!isRecord(rawModels) || !isRecord(rawModels.providers)) {
456+return cfg;
457+}
458+459+const rawProviders: Record<string, unknown> = rawModels.providers;
460+let providersChanged = false;
461+const nextProviders: Record<string, unknown> = { ...rawProviders };
462+for (const [providerId, rawProvider] of Object.entries(rawProviders)) {
463+if (!isRecord(rawProvider)) {
464+continue;
465+}
466+467+let providerChanged = false;
468+const nextProvider: Record<string, unknown> = { ...rawProvider };
469+if (nextProvider.api === "openai") {
470+nextProvider.api = "openai-completions";
471+providerChanged = true;
472+changes.push(
473+`Moved models.providers.${sanitizeForLog(providerId)}.api "openai" → "openai-completions".`,
474+);
475+}
476+477+const rawProviderModels = rawProvider.models;
478+if (Array.isArray(rawProviderModels)) {
479+let modelsChanged = false;
480+const nextModels: unknown[] = [];
481+rawProviderModels.forEach((model, index) => {
482+if (!isRecord(model) || model.api !== "openai") {
483+nextModels.push(model);
484+return;
485+}
486+modelsChanged = true;
487+changes.push(
488+`Moved models.providers.${sanitizeForLog(providerId)}.models[${index}].api "openai" → "openai-completions".`,
489+);
490+nextModels.push({
491+ ...model,
492+api: "openai-completions",
493+});
494+});
495+if (modelsChanged) {
496+nextProvider.models = nextModels;
497+providerChanged = true;
498+}
499+}
500+501+if (!providerChanged) {
502+continue;
503+}
504+nextProviders[providerId] = nextProvider;
505+providersChanged = true;
506+}
507+508+if (!providersChanged) {
509+return cfg;
510+}
511+512+return {
513+ ...cfg,
514+models: {
515+ ...rawModels,
516+providers: nextProviders as NonNullable<OpenClawConfig["models"]>["providers"],
517+},
518+};
519+}
520+449521export function normalizeLegacyNanoBananaSkill(
450522cfg: OpenClawConfig,
451523changes: string[],
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。