@@ -25,6 +25,7 @@ import { getProviderDefinition } from '#/kosong/provider/providerDefinition';
2525
2626import {
2727 DEFAULT_MODEL_SECTION ,
28+ DEFAULT_PROVIDER_SECTION ,
2829 MODELS_SECTION ,
2930 PROVIDERS_SECTION ,
3031 THINKING_SECTION ,
@@ -142,10 +143,11 @@ export class ProviderDiscoveryService implements IProviderDiscoveryService {
142143 }
143144
144145 private buildRefreshHost ( exclusion : StaticExclusion , userAgent : string ) : RefreshProviderHost {
146+ const pendingRemovals = new Set < string > ( ) ;
145147 return {
146148 getConfig : async ( ) => this . readUserConfigShape ( exclusion ) ,
147- removeProvider : ( providerId ) => this . shapeWithoutProvider ( providerId ) ,
148- setConfig : ( patch ) => this . applyRefreshPatch ( patch , exclusion ) ,
149+ removeProvider : ( providerId ) => this . queueProviderRemoval ( pendingRemovals , providerId ) ,
150+ setConfig : ( patch ) => this . applyRefreshPatch ( patch , pendingRemovals ) ,
149151 resolveOAuthToken : ( providerName , oauthRef ) => this . resolveOAuthToken ( providerName , oauthRef ) ,
150152 userAgent,
151153 } ;
@@ -173,7 +175,11 @@ export class ProviderDiscoveryService implements IProviderDiscoveryService {
173175 } ;
174176 }
175177
176- private shapeWithoutProvider ( providerId : string ) : Promise < ManagedKimiConfigShape > {
178+ private queueProviderRemoval (
179+ pendingRemovals : Set < string > ,
180+ providerId : string ,
181+ ) : Promise < ManagedKimiConfigShape > {
182+ pendingRemovals . add ( providerId ) ;
177183 const current = this . readUserConfigShape ( ) ;
178184 const providers = current . providers as Record < string , ProviderConfig > ;
179185 const restProviders = Object . fromEntries (
@@ -192,57 +198,54 @@ export class ProviderDiscoveryService implements IProviderDiscoveryService {
192198
193199 private async applyRefreshPatch (
194200 patch : ManagedKimiConfigShape ,
195- exclusion : StaticExclusion ,
201+ pendingRemovals : Set < string > ,
196202 ) : Promise < ManagedKimiConfigShape > {
197- const userProviders =
203+ await this . config . reload ( ) ;
204+ const removals = [ ...pendingRemovals ] ;
205+ pendingRemovals . clear ( ) ;
206+ const removed = new Set ( removals ) ;
207+ const providers =
198208 this . config . inspect < Record < string , ProviderConfig > > ( PROVIDERS_SECTION ) . userValue ?? { } ;
199- const userModels =
209+ const models =
200210 this . config . inspect < Record < string , ModelRecord > > ( MODELS_SECTION ) . userValue ?? { } ;
201211 const sections : Record < string , unknown > = { } ;
202- if ( patch . providers !== undefined ) {
203- sections [ PROVIDERS_SECTION ] = {
204- ...exclusion . providers ,
205- ...patch . providers ,
206- } ;
212+ if ( removals . length > 0 || patch . providers !== undefined ) {
213+ const nextProviders : Record < string , unknown > = Object . fromEntries (
214+ Object . entries ( providers ) . filter ( ( [ id ] ) => ! removed . has ( id ) ) ,
215+ ) ;
216+ if ( patch . providers !== undefined ) Object . assign ( nextProviders , patch . providers ) ;
217+ sections [ PROVIDERS_SECTION ] = nextProviders ;
207218 }
208- if ( patch . models !== undefined ) {
209- sections [ MODELS_SECTION ] = {
210- ...exclusion . models ,
211- ...( patch . models as Record < string , ModelRecord > ) ,
212- } ;
219+ if ( removals . length > 0 || patch . models !== undefined ) {
220+ const nextModels : Record < string , unknown > = Object . fromEntries (
221+ Object . entries ( models ) . filter (
222+ ( [ , record ] ) => record . provider === undefined || ! removed . has ( record . provider ) ,
223+ ) ,
224+ ) ;
225+ if ( patch . models !== undefined ) Object . assign ( nextModels , patch . models ) ;
226+ sections [ MODELS_SECTION ] = nextModels ;
213227 }
214- const restoreDefault = exclusion . defaultModel !== undefined ;
215228 if ( 'defaultModel' in patch ) {
216- sections [ DEFAULT_MODEL_SECTION ] = restoreDefault
217- ? exclusion . defaultModel
218- : patch . defaultModel ;
229+ sections [ DEFAULT_MODEL_SECTION ] = patch . defaultModel ;
230+ } else if ( removals . length > 0 ) {
231+ const defaultModel = this . config . inspect < string > ( DEFAULT_MODEL_SECTION ) . userValue ;
232+ if ( defaultModel !== undefined && removed . has ( models [ defaultModel ] ?. provider ?? '' ) ) {
233+ sections [ DEFAULT_MODEL_SECTION ] = undefined ;
234+ }
219235 }
220236 if ( 'thinking' in patch ) {
221- sections [ THINKING_SECTION ] = restoreDefault ? exclusion . thinking : patch . thinking ;
237+ sections [ THINKING_SECTION ] = patch . thinking ;
238+ }
239+ if ( 'defaultProvider' in patch ) {
240+ sections [ DEFAULT_PROVIDER_SECTION ] = patch [ 'defaultProvider' ] ;
241+ } else if ( removals . length > 0 ) {
242+ const defaultProvider = this . config . inspect < string > ( DEFAULT_PROVIDER_SECTION ) . userValue ;
243+ if ( defaultProvider !== undefined && removed . has ( defaultProvider ) ) {
244+ sections [ DEFAULT_PROVIDER_SECTION ] = undefined ;
245+ }
222246 }
223247 await this . config . replaceSections ( sections ) ;
224- return {
225- providers :
226- patch . providers !== undefined
227- ? ( { ...exclusion . providers , ...patch . providers } as ManagedKimiConfigShape [ 'providers' ] )
228- : ( userProviders as ManagedKimiConfigShape [ 'providers' ] ) ,
229- models :
230- patch . models !== undefined
231- ? ( { ...exclusion . models , ...patch . models } as ManagedKimiConfigShape [ 'models' ] )
232- : ( userModels as ManagedKimiConfigShape [ 'models' ] ) ,
233- defaultModel :
234- 'defaultModel' in patch
235- ? restoreDefault
236- ? exclusion . defaultModel
237- : patch . defaultModel
238- : this . config . inspect < string > ( DEFAULT_MODEL_SECTION ) . userValue ,
239- thinking :
240- 'thinking' in patch
241- ? restoreDefault
242- ? exclusion . thinking
243- : patch . thinking
244- : this . config . inspect < ManagedKimiConfigShape [ 'thinking' ] > ( THINKING_SECTION ) . userValue ,
245- } ;
248+ return this . readUserConfigShape ( ) ;
246249 }
247250
248251 private async resolveOAuthToken (
0 commit comments