Skip to content

Commit 797045e

Browse files
rekram1-nodeadamdotdevin
authored andcommitted
feat: add configuration persistence for model selections
1 parent c8f8d67 commit 797045e

1 file changed

Lines changed: 58 additions & 51 deletions

File tree

internal/config/config.go

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ type Provider struct {
5656

5757
// Data defines storage configuration.
5858
type Data struct {
59-
Directory string `json:"directory"`
59+
Directory string `json:"directory,omitempty"`
6060
}
6161

6262
// LSPConfig defines configuration for Language Server Protocol integration.
@@ -80,7 +80,7 @@ type Config struct {
8080
MCPServers map[string]MCPServer `json:"mcpServers,omitempty"`
8181
Providers map[models.ModelProvider]Provider `json:"providers,omitempty"`
8282
LSP map[string]LSPConfig `json:"lsp,omitempty"`
83-
Agents map[AgentName]Agent `json:"agents"`
83+
Agents map[AgentName]Agent `json:"agents,omitempty"`
8484
Debug bool `json:"debug,omitempty"`
8585
DebugLSP bool `json:"debugLSP,omitempty"`
8686
ContextPaths []string `json:"contextPaths,omitempty"`
@@ -704,6 +704,52 @@ func GetUsername() (string, error) {
704704
return currentUser.Username, nil
705705
}
706706

707+
func updateCfgFile(updateCfg func(config *Config)) error {
708+
if cfg == nil {
709+
return fmt.Errorf("config not loaded")
710+
}
711+
712+
// Get the config file path
713+
configFile := viper.ConfigFileUsed()
714+
var configData []byte
715+
if configFile == "" {
716+
homeDir, err := os.UserHomeDir()
717+
if err != nil {
718+
return fmt.Errorf("failed to get home directory: %w", err)
719+
}
720+
configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
721+
slog.Info("config file not found, creating new one", "path", configFile)
722+
configData = []byte(`{}`)
723+
} else {
724+
// Read the existing config file
725+
data, err := os.ReadFile(configFile)
726+
if err != nil {
727+
return fmt.Errorf("failed to read config file: %w", err)
728+
}
729+
configData = data
730+
}
731+
732+
// Parse the JSON
733+
var userCfg *Config
734+
if err := json.Unmarshal(configData, &userCfg); err != nil {
735+
return fmt.Errorf("failed to parse config file: %w", err)
736+
}
737+
738+
updateCfg(userCfg)
739+
740+
// Write the updated config back to file
741+
updatedData, err := json.MarshalIndent(userCfg, "", " ")
742+
if err != nil {
743+
return fmt.Errorf("failed to marshal config: %w", err)
744+
}
745+
746+
if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
747+
return fmt.Errorf("failed to write config file: %w", err)
748+
}
749+
750+
return nil
751+
}
752+
707753
func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
708754
if cfg == nil {
709755
panic("config not loaded")
@@ -734,7 +780,12 @@ func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
734780
return fmt.Errorf("failed to update agent model: %w", err)
735781
}
736782

737-
return nil
783+
return updateCfgFile(func(config *Config) {
784+
if config.Agents == nil {
785+
config.Agents = make(map[AgentName]Agent)
786+
}
787+
config.Agents[agentName] = newAgentCfg
788+
})
738789
}
739790

740791
// UpdateTheme updates the theme in the configuration and writes it to the config file.
@@ -746,52 +797,8 @@ func UpdateTheme(themeName string) error {
746797
// Update the in-memory config
747798
cfg.TUI.Theme = themeName
748799

749-
// Get the config file path
750-
configFile := viper.ConfigFileUsed()
751-
var configData []byte
752-
if configFile == "" {
753-
homeDir, err := os.UserHomeDir()
754-
if err != nil {
755-
return fmt.Errorf("failed to get home directory: %w", err)
756-
}
757-
configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
758-
slog.Info("config file not found, creating new one", "path", configFile)
759-
configData = []byte(`{}`)
760-
} else {
761-
// Read the existing config file
762-
data, err := os.ReadFile(configFile)
763-
if err != nil {
764-
return fmt.Errorf("failed to read config file: %w", err)
765-
}
766-
configData = data
767-
}
768-
769-
// Parse the JSON
770-
var configMap map[string]any
771-
if err := json.Unmarshal(configData, &configMap); err != nil {
772-
return fmt.Errorf("failed to parse config file: %w", err)
773-
}
774-
775-
// Update just the theme value
776-
tuiConfig, ok := configMap["tui"].(map[string]any)
777-
if !ok {
778-
// TUI config doesn't exist yet, create it
779-
configMap["tui"] = map[string]any{"theme": themeName}
780-
} else {
781-
// Update existing TUI config
782-
tuiConfig["theme"] = themeName
783-
configMap["tui"] = tuiConfig
784-
}
785-
786-
// Write the updated config back to file
787-
updatedData, err := json.MarshalIndent(configMap, "", " ")
788-
if err != nil {
789-
return fmt.Errorf("failed to marshal config: %w", err)
790-
}
791-
792-
if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
793-
return fmt.Errorf("failed to write config file: %w", err)
794-
}
795-
796-
return nil
800+
// Update the file config
801+
return updateCfgFile(func(config *Config) {
802+
config.TUI.Theme = themeName
803+
})
797804
}

0 commit comments

Comments
 (0)