1439
1440
async setModelConfiguration(modelId: string, values: IStringDictionary<unknown>): Promise<void> {
1442
>
if (!metadata) {
1443
return;
1444
}
1446
>
// Find the group from the configuration service (source of truth)
1447
>
const allGroups = this._languageModelsConfigurationService.getLanguageModelsProviderGroups();
1448
>
let group: ILanguageModelsProviderGroup | undefined;
1449
>
1450
>
// First try to find a group that already has config for this model.
1451
>
group = allGroups.find(g => g.vendor === metadata.vendor && g.settings?.[metadata.id] !== undefined);
1452
>
1453
>
// Otherwise find the group that actually *defines* this model. Several
1454
>
// groups can share the same `vendor` (e.g. multiple `customendpoint`
1455
>
// providers like DeepSeek and MyCustom), so matching by vendor alone would
1456
>
// write the config to the first group of that vendor — not the one the
1457
>
// model belongs to. Resolve via the model→group map instead. See #322872.
1458
>
if (!group) {
1459
>
const vendorGroups = this._modelsGroups.get(metadata.vendor);
1460
>
const containingGroup = vendorGroups?.find(vg => vg.modelIdentifiers.includes(modelId) && vg.group)?.group;
1461
>
if (containingGroup) {
1462
>
group = allGroups.find(g => g.vendor === containingGroup.vendor && g.name === containingGroup.name) ?? containingGroup;
1463
>
}
1464
>
}
1465
>
1466
>
// As a last resort (model not yet resolved into any group), fall back to
1467
>
// any group for this vendor.
1468
>
if (!group) {
1469
group = allGroups.find(g => g.vendor === metadata.vendor);
1470
}
1472
>
// Merge new values into existing config, removing properties set to their schema default
1473
>
const existingConfig = this._modelConfigurations.get(modelId) ?? {};
1474
>
const updatedConfig = { ...existingConfig, ...values };
1475
>
const schema = metadata.configurationSchema;
1476
>
if (schema?.properties) {
1477
>
for (const [key, value] of Object.entries(updatedConfig)) {
1478
>
const propSchema = schema.properties[key];
1479
>
if (propSchema?.default !== undefined && propSchema.default === value) {
1480
delete updatedConfig[key];
1481
}
1483
>
}
1484
>
1485
>
if (group) {
1486
>
const existingSettings = (group.settings as IStringDictionary<IStringDictionary<unknown>> | undefined) ?? {};
1487
>
let updatedSettings: IStringDictionary<IStringDictionary<unknown>>;
1488
>
if (Object.keys(updatedConfig).length === 0) {
1489
updatedSettings = { ...existingSettings };
1490
delete updatedSettings[metadata.id];
1492
>
updatedSettings = { ...existingSettings, [metadata.id]: updatedConfig };
1493
>
}
1494
>
const updatedGroup: ILanguageModelsProviderGroup = {
1495
>
...group,
1496
>
settings: Object.keys(updatedSettings).length > 0 ? updatedSettings : undefined
1497
>
};
1498
>
if (!updatedGroup.settings && Object.keys(updatedGroup).filter(k => k !== 'name' && k !== 'vendor' && k !== 'range' && k !== 'modelsRange' && k !== 'settings').length === 0) {
1499
// Remove the group entirely if it only had model config
1500
await this._languageModelsConfigurationService.removeLanguageModelsProviderGroup(group);
1502
>
await this._languageModelsConfigurationService.updateLanguageModelsProviderGroup(group, updatedGroup);
1503
>
}
1504
>
} else if (Object.keys(updatedConfig).length > 0) {
1505
// Only create a new group if there's non-default config
1506
// Use _vendors directly instead of getVendors() which filters by `when` clause,