diff --git a/cmd/root.go b/cmd/root.go index cf37c07c..37753239 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -676,8 +676,8 @@ func globalShortcutsProviderForUI(k *kit.Kit) func() map[string]func() { } } -func runNormalMode(ctx context.Context) error { - // Validate flag combinations +// validateModeFlags rejects invalid flag combinations for the root command. +func validateModeFlags() error { if quietFlag && positionalPrompt == "" { return fmt.Errorf("--quiet requires a prompt (e.g. kit \"your question\" --quiet)") } @@ -690,21 +690,14 @@ func runNormalMode(ctx context.Context) error { if noExitFlag && positionalPrompt == "" { return fmt.Errorf("--no-exit requires a prompt (e.g. kit \"your question\" --no-exit)") } + return nil +} - // Set up logging - if debugMode { - log.SetFlags(log.LstdFlags | log.Lshortfile) - } - - // Update debug mode from viper - if viper.GetBool("debug") && !debugMode { - debugMode = viper.GetBool("debug") - log.SetFlags(log.LstdFlags | log.Lshortfile) - } - - // Restore persisted model preference when no explicit --model flag or - // config file model is set. Precedence: CLI flag > config file > saved - // preference > built-in default. This mirrors how themes are persisted. +// restorePersistedPreferences applies saved model / thinking-level +// preferences into viper when neither a CLI flag nor a config-file value +// takes precedence. Precedence: CLI flag > config file > saved preference > +// built-in default. This mirrors how themes are persisted. +func restorePersistedPreferences() { // Skip custom/* models unless --provider-url is also provided, since the // custom provider requires a URL that was only valid for the previous session. if !modelFlagChanged && !viper.InConfig("model") { @@ -723,6 +716,15 @@ func runNormalMode(ctx context.Context) error { viper.Set("thinking-level", pref) } } +} + +// applyProviderURLRouting rewrites the model in viper when --provider-url +// is set, routing requests through the "custom" (OpenAI-compatible) +// provider. Must run after restorePersistedPreferences. +func applyProviderURLRouting() { + if viper.GetString("provider-url") == "" { + return + } // When --provider-url is set but no explicit --model was provided, // default to "custom/custom" so the user doesn't need to remember a @@ -730,7 +732,7 @@ func runNormalMode(ctx context.Context) error { // This intentionally overrides saved preferences but respects config-file // models — if you specify a model in ~/.kit.yml, it will be used with // custom/custom's provider routing. - if viper.GetString("provider-url") != "" && !modelFlagChanged && !viper.InConfig("model") { + if !modelFlagChanged && !viper.InConfig("model") { viper.Set("model", "custom/custom") } @@ -745,7 +747,7 @@ func runNormalMode(ctx context.Context) error { // to point a non-OpenAI wire (Anthropic, Google, ...) at a proxy URL, // use the explicit `custom/` form to opt out of the rewrite by // configuring the proxy as that provider in your config file instead. - if viper.GetString("provider-url") != "" && modelFlagChanged { + if modelFlagChanged { model := viper.GetString("model") if model != "" { name := model @@ -757,6 +759,26 @@ func runNormalMode(ctx context.Context) error { } } } +} + +func runNormalMode(ctx context.Context) error { + if err := validateModeFlags(); err != nil { + return err + } + + // Set up logging + if debugMode { + log.SetFlags(log.LstdFlags | log.Lshortfile) + } + + // Update debug mode from viper + if viper.GetBool("debug") && !debugMode { + debugMode = viper.GetBool("debug") + log.SetFlags(log.LstdFlags | log.Lshortfile) + } + + restorePersistedPreferences() + applyProviderURLRouting() // Load MCP configuration. mcpConfig, err := config.LoadAndValidateConfig()