Files
2026-07-13 13:33:09 +08:00

256 lines
6.9 KiB
Go

package lib
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"plandex-cli/api"
"plandex-cli/fs"
"plandex-cli/schema"
"plandex-cli/term"
shared "plandex-shared"
"github.com/fatih/color"
)
var DefaultModelSettingsPath string
func init() {
DefaultModelSettingsPath = filepath.Join(fs.HomePlandexDir, "default-model-settings.json")
}
func GetPlanModelSettingsPath(planId string) string {
return filepath.Join(fs.HomePlandexDir, planId, "model-settings.json")
}
type ModelSettingsCheckLocalChangesResult struct {
HasLocalChanges bool
LocalModelPackSchemaRoles *shared.ModelPackSchemaRoles
}
func ModelSettingsCheckLocalChanges(path string) (ModelSettingsCheckLocalChangesResult, error) {
hashPath := path + ".hash"
exists, err := fs.FileExists(path)
if err != nil {
return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error checking model settings file: %v", err)
}
if !exists {
return ModelSettingsCheckLocalChangesResult{}, nil
}
lastSavedHash, err := os.ReadFile(hashPath)
if err != nil && !os.IsNotExist(err) {
return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error reading hash file: %v", err)
}
localJsonData, err := os.ReadFile(path)
if err != nil {
return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error reading JSON file: %v", err)
}
var clientModelPackSchemaRoles *shared.ClientModelPackSchemaRoles
err = json.Unmarshal(localJsonData, &clientModelPackSchemaRoles)
if err != nil {
return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error unmarshalling JSON file: %v", err)
}
currentHash, err := clientModelPackSchemaRoles.ToModelPackSchemaRoles().Hash()
if err != nil {
return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error hashing model pack: %v", err)
}
modelPackSchemaRoles := clientModelPackSchemaRoles.ToModelPackSchemaRoles()
return ModelSettingsCheckLocalChangesResult{
HasLocalChanges: currentHash != string(lastSavedHash),
LocalModelPackSchemaRoles: &modelPackSchemaRoles,
}, nil
}
func WriteModelSettingsFile(path string, originalSettings *shared.PlanSettings) error {
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return fmt.Errorf("error creating directory: %v", err)
}
modelPackSchemaRoles := originalSettings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles
clientModelPackRoles := modelPackSchemaRoles.ToClientModelPackSchemaRoles()
bytes, err := json.MarshalIndent(clientModelPackRoles, "", " ")
if err != nil {
return fmt.Errorf("error marshalling model pack: %v", err)
}
err = os.WriteFile(path, bytes, 0644)
if err != nil {
return fmt.Errorf("error writing JSON file: %v", err)
}
err = SaveModelPackRolesHash(path, &modelPackSchemaRoles)
if err != nil {
return fmt.Errorf("error saving model pack roles hash: %v", err)
}
return nil
}
func SaveModelPackRolesHash(basePath string, serverModelPack *shared.ModelPackSchemaRoles) error {
hashPath := basePath + ".hash"
hash, err := serverModelPack.Hash()
if err != nil {
return fmt.Errorf("error hashing model pack: %v", err)
}
err = os.WriteFile(hashPath, []byte(hash), 0644)
if err != nil {
return fmt.Errorf("error writing hash file: %v", err)
}
return nil
}
func ApplyModelSettings(path string, originalSettings *shared.PlanSettings) (*shared.PlanSettings, error) {
jsonData, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("error reading JSON file: %v", err)
}
settings, err := originalSettings.DeepCopy()
if err != nil {
return nil, fmt.Errorf("error copying settings: %v", err)
}
clientModelPackRoles, err := schema.ValidateModelPackInlineJSON(jsonData)
if err != nil {
term.StopSpinner()
color.New(color.Bold, term.ColorHiRed).Println("🚨 Error validating JSON file")
fmt.Println(err.Error())
os.Exit(1)
}
modelPackRoles := clientModelPackRoles.ToModelPackSchemaRoles()
modelPackSchema := shared.ModelPackSchema{
Name: "custom",
Description: "Model pack with custom settings",
ModelPackSchemaRoles: modelPackRoles,
}
modelPack := modelPackSchema.ToModelPack()
settings.SetCustomModelPack(&modelPack)
err = SaveModelPackRolesHash(path, &modelPackRoles)
if err != nil {
return nil, fmt.Errorf("error saving model settings hash: %v", err)
}
return settings, nil
}
func SaveLatestPlanModelSettingsIfNeeded() (bool, error) {
path := GetPlanModelSettingsPath(CurrentPlanId)
jsonData, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, fmt.Errorf("error reading JSON file: %v", err)
}
var clientModelPackSchemaRoles *shared.ClientModelPackSchemaRoles
err = json.Unmarshal(jsonData, &clientModelPackSchemaRoles)
if err != nil {
return false, fmt.Errorf("error unmarshalling JSON file: %v", err)
}
modelPackSchemaRoles := clientModelPackSchemaRoles.ToModelPackSchemaRoles()
localHash, err := modelPackSchemaRoles.Hash()
if err != nil {
return false, fmt.Errorf("error hashing model pack: %v", err)
}
settings, apiErr := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
if apiErr != nil {
return false, fmt.Errorf("error getting settings: %v", apiErr)
}
serverHash, err := settings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles.Hash()
if err != nil {
return false, fmt.Errorf("error hashing model pack: %v", err)
}
if localHash == serverHash {
return false, nil
}
err = WriteModelSettingsFile(path, settings)
if err != nil {
return false, fmt.Errorf("error writing model settings file: %v", err)
}
return true, nil
}
// save settings in file to server
func SyncPlanModelSettings() error {
settings, err := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
if err != nil {
return fmt.Errorf("error getting settings: %v", err)
}
updatedSettings, apiErr := ApplyModelSettings(GetPlanModelSettingsPath(CurrentPlanId), settings)
if apiErr != nil {
return fmt.Errorf("error applying model settings: %v", err)
}
res, updateErr := api.Client.UpdateSettings(CurrentPlanId, CurrentBranch, shared.UpdateSettingsRequest{
ModelPackName: updatedSettings.ModelPackName,
ModelPack: updatedSettings.ModelPack,
})
if updateErr != nil {
return fmt.Errorf("error updating settings: %v", err)
}
if res == nil {
return nil
}
fmt.Println(res.Msg)
return nil
}
func SyncDefaultModelSettings() error {
settings, err := api.Client.GetOrgDefaultSettings()
if err != nil {
return fmt.Errorf("error getting settings: %v", err)
}
updatedSettings, apiErr := ApplyModelSettings(DefaultModelSettingsPath, settings)
if apiErr != nil {
return fmt.Errorf("error applying model settings: %v", err)
}
res, updateErr := api.Client.UpdateOrgDefaultSettings(shared.UpdateSettingsRequest{
ModelPackName: updatedSettings.ModelPackName,
ModelPack: updatedSettings.ModelPack,
})
if updateErr != nil {
return fmt.Errorf("error updating settings: %v", err)
}
if res == nil {
return nil
}
fmt.Println(res.Msg)
return nil
}