@@ -9,7 +9,7 @@ import axios from "axios"
99import pWaitFor from "p-wait-for"
1010import * as vscode from "vscode"
1111
12- import type { GlobalState , ProviderName , ProviderSettings , RooCodeSettings } from "../../schemas"
12+ import type { GlobalState , ProviderName , ProviderSettings , RooCodeSettings , ProviderSettingsEntry } from "../../schemas"
1313import { t } from "../../i18n"
1414import { setPanel } from "../../activate/registerCommands"
1515import { requestyDefaultModelId , openRouterDefaultModelId , glamaDefaultModelId } from "../../shared/api"
@@ -246,7 +246,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
246246 return false
247247 }
248248
249- // check if there is a cline instance in the stack (if this provider has an active task)
249+ // Check if there is a cline instance in the stack (if this provider has an active task)
250250 if ( visibleProvider . getCurrentCline ( ) ) {
251251 return true
252252 }
@@ -795,39 +795,127 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
795795 await this . postStateToWebview ( )
796796 }
797797
798+ // Provider Profile Management
799+
800+ getProviderProfileEntries ( ) : ProviderSettingsEntry [ ] {
801+ return this . contextProxy . getValues ( ) . listApiConfigMeta || [ ]
802+ }
803+
804+ getProviderProfileEntry ( name : string ) : ProviderSettingsEntry | undefined {
805+ return this . getProviderProfileEntries ( ) . find ( ( profile ) => profile . name === name )
806+ }
807+
808+ public hasProviderProfileEntry ( name : string ) : boolean {
809+ return ! ! this . getProviderProfileEntry ( name )
810+ }
811+
812+ async upsertProviderProfile (
813+ name : string ,
814+ providerSettings : ProviderSettings ,
815+ activate : boolean = true ,
816+ ) : Promise < string | undefined > {
817+ try {
818+ // TODO: Do we need to be calling `activateProfile`? It's not
819+ // clear to me what the source of truth should be; in some cases
820+ // we rely on the `ContextProxy`'s data store and in other cases
821+ // we rely on the `ProviderSettingsManager`'s data store. It might
822+ // be simpler to unify these two.
823+ const id = await this . providerSettingsManager . saveConfig ( name , providerSettings )
824+
825+ if ( activate ) {
826+ const { mode } = await this . getState ( )
827+
828+ // These promises do the following:
829+ // 1. Adds or updates the list of provider profiles.
830+ // 2. Sets the current provider profile.
831+ // 3. Sets the current mode's provider profile.
832+ // 4. Copies the provider settings to the context.
833+ //
834+ // Note: 1, 2, and 4 can be done in one `ContextProxy` call:
835+ // this.contextProxy.setValues({ ...providerSettings, listApiConfigMeta: ..., currentApiConfigName: ... })
836+ // We should probably switch to that and verify that it works.
837+ // I left the original implementation in just to be safe.
838+ await Promise . all ( [
839+ this . updateGlobalState ( "listApiConfigMeta" , await this . providerSettingsManager . listConfig ( ) ) ,
840+ this . updateGlobalState ( "currentApiConfigName" , name ) ,
841+ this . providerSettingsManager . setModeConfig ( mode , id ) ,
842+ this . contextProxy . setProviderSettings ( providerSettings ) ,
843+ ] )
844+
845+ // Change the provider for the current task.
846+ // TODO: We should rename `buildApiHandler` for clarity (e.g. `getProviderClient`).
847+ const task = this . getCurrentCline ( )
848+
849+ if ( task ) {
850+ task . api = buildApiHandler ( providerSettings )
851+ }
852+ } else {
853+ await this . updateGlobalState ( "listApiConfigMeta" , await this . providerSettingsManager . listConfig ( ) )
854+ }
855+
856+ await this . postStateToWebview ( )
857+ return id
858+ } catch ( error ) {
859+ this . log (
860+ `Error create new api configuration: ${ JSON . stringify ( error , Object . getOwnPropertyNames ( error ) , 2 ) } ` ,
861+ )
862+
863+ vscode . window . showErrorMessage ( t ( "common:errors.create_api_config" ) )
864+ return undefined
865+ }
866+ }
867+
868+ async deleteProviderProfile ( profileToDelete : ProviderSettingsEntry ) {
869+ const globalSettings = this . contextProxy . getValues ( )
870+ let profileToActivate : string | undefined = globalSettings . currentApiConfigName
871+
872+ if ( profileToDelete . name === profileToActivate ) {
873+ profileToActivate = this . getProviderProfileEntries ( ) . find ( ( { name } ) => name !== profileToDelete . name ) ?. name
874+ }
875+
876+ if ( ! profileToActivate ) {
877+ throw new Error ( "You cannot delete the last profile" )
878+ }
879+
880+ const entries = this . getProviderProfileEntries ( ) . filter ( ( { name } ) => name !== profileToDelete . name )
881+
882+ await this . contextProxy . setValues ( {
883+ ...globalSettings ,
884+ currentApiConfigName : profileToActivate ,
885+ listApiConfigMeta : entries ,
886+ } )
887+
888+ await this . postStateToWebview ( )
889+ }
890+
798891 async activateProviderProfile ( args : { name : string } | { id : string } ) {
799- const { name, ...providerSettings } = await this . providerSettingsManager . activateProfile ( args )
892+ const { name, id , ...providerSettings } = await this . providerSettingsManager . activateProfile ( args )
800893
894+ // See `upsertProviderProfile` for a description of what this is doing.
801895 await Promise . all ( [
802896 this . contextProxy . setValue ( "listApiConfigMeta" , await this . providerSettingsManager . listConfig ( ) ) ,
803897 this . contextProxy . setValue ( "currentApiConfigName" , name ) ,
898+ this . contextProxy . setProviderSettings ( providerSettings ) ,
804899 ] )
805900
806- await this . updateApiConfiguration ( providerSettings )
807- await this . postStateToWebview ( )
808- }
809-
810- async updateApiConfiguration ( providerSettings : ProviderSettings ) {
811- // Update mode's default config.
812901 const { mode } = await this . getState ( )
813902
814- if ( mode ) {
815- const currentApiConfigName = this . getGlobalState ( "currentApiConfigName" )
816- const listApiConfig = await this . providerSettingsManager . listConfig ( )
817- const config = listApiConfig ?. find ( ( c ) => c . name === currentApiConfigName )
818-
819- if ( config ?. id ) {
820- await this . providerSettingsManager . setModeConfig ( mode , config . id )
821- }
903+ if ( id ) {
904+ await this . providerSettingsManager . setModeConfig ( mode , id )
822905 }
823906
824- await this . contextProxy . setProviderSettings ( providerSettings )
907+ // Change the provider for the current task.
908+ const task = this . getCurrentCline ( )
825909
826- if ( this . getCurrentCline ( ) ) {
827- this . getCurrentCline ( ) ! . api = buildApiHandler ( providerSettings )
910+ if ( task ) {
911+ task . api = buildApiHandler ( providerSettings )
828912 }
913+
914+ await this . postStateToWebview ( )
829915 }
830916
917+ // Task Management
918+
831919 async cancelTask ( ) {
832920 const cline = this . getCurrentCline ( )
833921
@@ -943,7 +1031,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
9431031 openRouterModelId : apiConfiguration ?. openRouterModelId || openRouterDefaultModelId ,
9441032 }
9451033
946- await this . upsertApiConfiguration ( currentApiConfigName , newConfiguration )
1034+ await this . upsertProviderProfile ( currentApiConfigName , newConfiguration )
9471035 }
9481036
9491037 // Glama
@@ -973,7 +1061,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
9731061 glamaModelId : apiConfiguration ?. glamaModelId || glamaDefaultModelId ,
9741062 }
9751063
976- await this . upsertApiConfiguration ( currentApiConfigName , newConfiguration )
1064+ await this . upsertProviderProfile ( currentApiConfigName , newConfiguration )
9771065 }
9781066
9791067 // Requesty
@@ -988,29 +1076,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
9881076 requestyModelId : apiConfiguration ?. requestyModelId || requestyDefaultModelId ,
9891077 }
9901078
991- await this . upsertApiConfiguration ( currentApiConfigName , newConfiguration )
992- }
993-
994- // Save configuration
995-
996- async upsertApiConfiguration ( configName : string , apiConfiguration : ProviderSettings ) {
997- try {
998- await this . providerSettingsManager . saveConfig ( configName , apiConfiguration )
999- const listApiConfig = await this . providerSettingsManager . listConfig ( )
1000-
1001- await Promise . all ( [
1002- this . updateGlobalState ( "listApiConfigMeta" , listApiConfig ) ,
1003- this . updateApiConfiguration ( apiConfiguration ) ,
1004- this . updateGlobalState ( "currentApiConfigName" , configName ) ,
1005- ] )
1006-
1007- await this . postStateToWebview ( )
1008- } catch ( error ) {
1009- this . log (
1010- `Error create new api configuration: ${ JSON . stringify ( error , Object . getOwnPropertyNames ( error ) , 2 ) } ` ,
1011- )
1012- vscode . window . showErrorMessage ( t ( "common:errors.create_api_config" ) )
1013- }
1079+ await this . upsertProviderProfile ( currentApiConfigName , newConfiguration )
10141080 }
10151081
10161082 // Task history
0 commit comments