fix(providers): preserve custom model metadata on edit

This commit is contained in:
hehuaiyu
2026-09-04 13:11:55 +08:00
parent 0d8709a72e
commit c6755768b8
6 changed files with 321 additions and 9 deletions
+44 -2
View File
@@ -152,6 +152,37 @@ function validateCustomProviderConfig(providerId, config, options = {}) {
return { ok: true, value: { providerId, config: normalized } };
}
function mergeCustomProviderConfig(existingValue, normalizedConfig) {
const existing = isPlainObject(existingValue) ? existingValue : {};
const existingOptions = isPlainObject(existing.options) ? existing.options : {};
const normalizedOptions = isPlainObject(normalizedConfig.options) ? normalizedConfig.options : {};
const mergedOptions = { ...existingOptions, ...normalizedOptions };
if (!Object.prototype.hasOwnProperty.call(normalizedOptions, 'headers')) {
delete mergedOptions.headers;
}
const existingModels = isPlainObject(existing.models) ? existing.models : {};
const normalizedModels = isPlainObject(normalizedConfig.models) ? normalizedConfig.models : {};
const mergedModels = Object.fromEntries(
Object.entries(normalizedModels).map(([modelId, normalizedModel]) => {
const existingModel = isPlainObject(existingModels[modelId]) ? existingModels[modelId] : {};
const nextModel = isPlainObject(normalizedModel) ? normalizedModel : {};
return [modelId, { ...existingModel, ...nextModel }];
}),
);
const merged = {
...existing,
...normalizedConfig,
options: mergedOptions,
models: mergedModels,
};
if (!Object.prototype.hasOwnProperty.call(normalizedConfig, 'env')) {
delete merged.env;
}
return merged;
}
/**
* Persist (create or update) a custom provider block in OpenCode user/project/custom config.
* Does not write secrets — API keys remain in auth.json via the OpenCode auth API.
@@ -183,8 +214,19 @@ function upsertProviderConfig(providerId, config, workingDirectory, scope = 'use
const targetConfig = getConfigForPath(layers, targetPath);
const providerConfig = isPlainObject(targetConfig.provider) ? { ...targetConfig.provider } : {};
providerConfig[validated.value.providerId] = validated.value.config;
const providersAlias = isPlainObject(targetConfig.providers) ? { ...targetConfig.providers } : {};
const existingProvider = providerConfig[validated.value.providerId] ?? providersAlias[validated.value.providerId];
const mergedConfig = mergeCustomProviderConfig(existingProvider, validated.value.config);
providerConfig[validated.value.providerId] = mergedConfig;
targetConfig.provider = providerConfig;
if (Object.prototype.hasOwnProperty.call(providersAlias, validated.value.providerId)) {
delete providersAlias[validated.value.providerId];
if (Object.keys(providersAlias).length === 0) {
delete targetConfig.providers;
} else {
targetConfig.providers = providersAlias;
}
}
if (Array.isArray(targetConfig.disabled_providers)) {
targetConfig.disabled_providers = targetConfig.disabled_providers.filter(
@@ -198,7 +240,7 @@ function upsertProviderConfig(providerId, config, workingDirectory, scope = 'use
return {
providerId: validated.value.providerId,
path: writePath,
config: validated.value.config,
config: mergedConfig,
};
}