Introduces a new TODO.md file outlining steps to enforce specific AI models for commands like lint, edit, and agent. Includes updates to config.go, config.toml, and command files for consistent model defaults, optimizing performance and user experience. Also suggests additional features like prompt tweaks and auto-fix flags.
6.7 KiB
Enforcing specific models for specific actions is a great idea.
The lint fixes are now working after the model switch to "grok-4-1-fast-non-reasoning" (which is faster and more reliable for code editing tasks). To make this consistent and avoid manual --model flags every time, let's enforce model selection per command.
Why This Makes Sense
- Grok-4 is great for reasoning-heavy tasks (e.g. plan generation, reviews).
- Grok-4-1-fast-non-reasoning is better for quick code edits/fixes (faster, less "thinking" overhead).
- This way,
lintdefaults to the fast model, whilerevieworagentuses the full reasoning one. - We can make it configurable via config.toml.
How to Implement It
- Update config/config.go (add per-command defaults)
Replace your config/config.go with this:
package config
import (
"os"
"github.com/spf13/viper"
)
func Load() {
home, _ := os.UserHomeDir()
viper.SetConfigName("config")
viper.SetConfigType("toml")
viper.AddConfigPath(home + "/.config/grokkit")
viper.AddConfigPath(".")
viper.AutomaticEnv()
viper.SetDefault("default_model", "grok-4")
viper.SetDefault("temperature", 0.7)
viper.SetDefault("commands.lint.model", "grok-4-1-fast-non-reasoning")
viper.SetDefault("commands.agent.model", "grok-4")
// Add more defaults as needed
viper.ReadInConfig()
}
// GetModel returns the model, respecting command-specific defaults, then flag, then global
func GetModel(commandName string, flagModel string) string {
if flagModel != "" {
// Check alias
if alias := viper.GetString("aliases." + flagModel); alias != "" {
return alias
}
return flagModel
}
// Command-specific default
cmdModel := viper.GetString("commands." + commandName + ".model")
if cmdModel != "" {
return cmdModel
}
// Global default
return viper.GetString("default_model")
}
- Update your config.toml (~/.config/grokkit/config.toml or local one)
Add this section:
[commands]
[commands.lint]
model = "grok-4-1-fast-non-reasoning"
[commands.agent]
model = "grok-4"
- Update cmd/lint.go (use GetModel)
In the API call section, change:
model := "grok-4-1-fast-non-reasoning" // or whatever you had
to:
modelFlag, _ := cmd.Flags().GetString("model")
model := config.GetModel("lint", modelFlag)
Do the same for other commands (e.g. agent.go):
modelFlag, _ := cmd.Flags().GetString("model")
model := config.GetModel("agent", modelFlag)
Test it
build/grokkit lint pyrdle.py --debug
This should now default to "grok-4-1-fast-non-reasoning" for lint fixes without the flag.
Additional Suggestions
- Prompt tweaks for lint: Make the system prompt more explicit about fixing all issues (e.g. "Return ONLY the full fixed code. Fix EVERY whitespace, line length, and indentation issue from the linter output. Do not add or remove functionality.").
- Auto-fix flag: Add --auto-fix to apply without prompt.
- Re-run lint after fix: You already have this, but add a loop (max 3 iterations) if issues remain.
I strongly recommend following the same pattern for the edit and agent subcommands (and ideally all commands that make API calls). It's a smart way to make your tool more consistent, efficient, and user-friendly without requiring manual flags every time. Here's why, and how to do it step by step.
Why This Pattern is Worth Extending
- Performance & Cost Optimization: Different commands have different needs.
editis about quick code transformations, so "grok-4-1-fast-non-reasoning" is ideal (faster, cheaper, less "thinking" overhead).agentinvolves planning and multi-file reasoning, so "grok-4" (full reasoning) is better. This avoids overusing the heavy model for everything. - User Experience: Users can override with --model, but defaults "just work" out of the box.
- Scalability: As you add more commands, config.toml becomes the central place to tune them (e.g. add "chat.model = grok-4").
- Consistency: All your API-calling commands now use the same GetModel logic — easy to maintain.
Step-by-Step Implementation
- Update config/config.go (add defaults for edit and agent)
Replace your config/config.go with this expanded version:
package config
import (
"os"
"github.com/spf13/viper"
)
func Load() {
home, _ := os.UserHomeDir()
viper.SetConfigName("config")
viper.SetConfigType("toml")
viper.AddConfigPath(home + "/.config/grokkit")
viper.AddConfigPath(".")
viper.AutomaticEnv()
viper.SetDefault("default_model", "grok-4")
viper.SetDefault("temperature", 0.7)
viper.SetDefault("commands.lint.model", "grok-4-1-fast-non-reasoning")
viper.SetDefault("commands.edit.model", "grok-4-1-fast-non-reasoning") // Fast for edits
viper.SetDefault("commands.agent.model", "grok-4") // Reasoning for agent
viper.SetDefault("commands.chat.model", "grok-4") // Default for chat
viper.SetDefault("commands.review.model", "grok-4")
viper.SetDefault("commands.commit.model", "grok-4")
// Add more as needed
viper.ReadInConfig()
}
func GetModel(commandName string, flagModel string) string {
if flagModel != "" {
if alias := viper.GetString("aliases." + flagModel); alias != "" {
return alias
}
return flagModel
}
cmdModel := viper.GetString("commands." + commandName + ".model")
if cmdModel != "" {
return cmdModel
}
return viper.GetString("default_model")
}
- Update config.toml (add the new defaults)
Add this to your ~/.config/grokkit/config.toml (or local one):
[commands]
[commands.edit]
model = "grok-4-1-fast-non-reasoning" # Fast for single-file edits
[commands.agent]
model = "grok-4" # Full reasoning for multi-file
[commands.chat]
model = "grok-4" # Default for chat
- Update
cmd/edit.go(use GetModel)
In the Run function, change:
model := "grok-4-1-fast-non-reasoning" // old hardcode
to:
modelFlag, _ := cmd.Flags().GetString("model")
model := config.GetModel("edit", modelFlag)
- Update
cmd/agent.go(use GetModel)
In the Run function, change:
model := config.GetModel(modelFlag) // old
to:
modelFlag, _ := cmd.Flags().GetString("model")
model := config.GetModel("agent", modelFlag)
- Update
cmd/chat.go(use GetModel)
In the Run function, change:
model := config.GetModel(modelFlag) // old
to:
modelFlag, _ := cmd.Flags().GetString("model")
model := config.GetModel("chat", modelFlag)
Test it
go build -o build/grokkit .
build/grokkit edit somefile.py "make this cleaner" # should use fast model by default
build/grokkit agent "add headers to all files" # uses full grok-4
build/grokkit chat --model 4-1-fast-non-reasoning # override with alias