( config: ManagedKimiConfigShape, entry: CustomRegistryProviderEntry, source: CustomRegistrySource, )
| 282 | * refresh dispatcher can rediscover it later. |
| 283 | */ |
| 284 | export function applyCustomRegistryProvider( |
| 285 | config: ManagedKimiConfigShape, |
| 286 | entry: CustomRegistryProviderEntry, |
| 287 | source: CustomRegistrySource, |
| 288 | ): void { |
| 289 | const providerKey = entry.id; |
| 290 | |
| 291 | config.providers[providerKey] = { |
| 292 | type: entry.type, |
| 293 | baseUrl: entry.api, |
| 294 | apiKey: source.apiKey, |
| 295 | source, |
| 296 | }; |
| 297 | |
| 298 | const existingModels = config.models ?? {}; |
| 299 | // Selectively merge upstream models into the existing config so any fields |
| 300 | // the user added by hand (or that upstream does not declare) survive a |
| 301 | // refresh. Models that upstream no longer lists are removed; the rest are |
| 302 | // merged field-by-field. |
| 303 | const upstreamKeys = new Set( |
| 304 | Object.keys(entry.models).map((modelKey) => `${providerKey}/${modelKey}`), |
| 305 | ); |
| 306 | for (const [key, alias] of Object.entries(existingModels)) { |
| 307 | if (isRecord(alias) && alias['provider'] === providerKey && !upstreamKeys.has(key)) { |
| 308 | delete existingModels[key]; |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | for (const [modelKey, model] of Object.entries(entry.models)) { |
| 313 | const aliasKey = `${providerKey}/${modelKey}`; |
| 314 | const maxContextSize = resolveMaxContextSize(model); |
| 315 | const capabilities = resolveCapabilities(model); |
| 316 | const displayName = |
| 317 | typeof model.name === 'string' && model.name.length > 0 ? model.name : model.id; |
| 318 | const existing = isRecord(existingModels[aliasKey]) ? existingModels[aliasKey] : {}; |
| 319 | |
| 320 | const remoteAlias: ManagedKimiModelAlias = { |
| 321 | provider: providerKey, |
| 322 | model: model.id, |
| 323 | maxContextSize, |
| 324 | capabilities, |
| 325 | displayName, |
| 326 | }; |
| 327 | existingModels[aliasKey] = mergeRefreshedModelAlias( |
| 328 | existing, |
| 329 | remoteAlias, |
| 330 | CUSTOM_REGISTRY_MODEL_FIELDS, |
| 331 | ); |
| 332 | } |
| 333 | |
| 334 | config.models = existingModels; |
| 335 | } |
| 336 | |
| 337 | /** |
| 338 | * Removes a custom-registry provider and every model alias that referenced it. |
no test coverage detected