Skip to content

Commit 5a4b2c8

Browse files
z23cchomanp
andauthored
feat: improve model configuration and settings management (#59)
* feat: improve model configuration and settings management - Refactor model configuration system with unified settings approach - Add support for user-level default models and project-level current models - Implement automatic saving of API key and base URL from command line arguments - Remove model descriptions for cleaner UI and easier extensibility - Fix commander.js subcommand argument parsing with fallback mechanism - Improve configuration file structure and priority handling - Add comprehensive model configuration utilities in src/utils/model-config.ts Configuration priority: project current model > user default model > system default Both main command and git subcommand now save credentials automatically * refactor: unify settings management - Add SettingsManager singleton for user/project settings - Eliminate duplicate settings code across files - Clear separation: user settings vs project settings * docs: improve README clarity and organization - Simplify setup section with quick start approach - Consolidate configuration info into unified section - Add clear explanation of user vs project settings - Document OpenAI-compatible API support - Remove duplicate model configuration sections * bump sdk --------- Co-authored-by: Ismail Pelaseyed <[email protected]>
1 parent 346097a commit 5a4b2c8

File tree

12 files changed

+534
-251
lines changed

12 files changed

+534
-251
lines changed

README.md

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Create `~/.grok/user-settings.json`:
6666

6767
### Custom Base URL (Optional)
6868

69-
You can configure a custom Grok API endpoint (choose one method):
69+
By default, the CLI uses `https://api.x.ai/v1` as the Grok API endpoint. You can configure a custom endpoint if needed (choose one method):
7070

7171
**Method 1: Environment Variable**
7272
```bash
@@ -75,7 +75,7 @@ export GROK_BASE_URL=https://your-custom-endpoint.com/v1
7575

7676
**Method 2: Command Line Flag**
7777
```bash
78-
grok --api-key your_api_key_here --baseurl https://your-custom-endpoint.com/v1
78+
grok --api-key your_api_key_here --base-url https://your-custom-endpoint.com/v1
7979
```
8080

8181
**Method 3: User Settings File**
@@ -87,6 +87,89 @@ Add to `~/.grok/user-settings.json`:
8787
}
8888
```
8989

90+
## Configuration Files
91+
92+
Grok CLI uses two types of configuration files to manage settings:
93+
94+
### User-Level Settings (`~/.grok/user-settings.json`)
95+
96+
This file stores **global settings** that apply across all projects. These settings rarely change and include:
97+
98+
- **API Key**: Your Grok API key
99+
- **Base URL**: Custom API endpoint (if needed)
100+
- **Default Model**: Your preferred model (e.g., `grok-4-latest`)
101+
- **Available Models**: List of models you can use
102+
103+
**Example:**
104+
```json
105+
{
106+
"apiKey": "your_api_key_here",
107+
"baseURL": "https://api.x.ai/v1",
108+
"defaultModel": "grok-4-latest",
109+
"models": [
110+
"grok-4-latest",
111+
"grok-3-latest",
112+
"grok-3-fast",
113+
"grok-3-mini-fast"
114+
]
115+
}
116+
```
117+
118+
### Project-Level Settings (`.grok/settings.json`)
119+
120+
This file stores **project-specific settings** in your current working directory. It includes:
121+
122+
- **Current Model**: The model currently in use for this project
123+
- **MCP Servers**: Model Context Protocol server configurations
124+
125+
**Example:**
126+
```json
127+
{
128+
"model": "grok-3-fast",
129+
"mcpServers": {
130+
"linear": {
131+
"name": "linear",
132+
"transport": "stdio",
133+
"command": "npx",
134+
"args": ["@linear/mcp-server"]
135+
}
136+
}
137+
}
138+
```
139+
140+
### How It Works
141+
142+
1. **Global Defaults**: User-level settings provide your default preferences
143+
2. **Project Override**: Project-level settings override defaults for specific projects
144+
3. **Directory-Specific**: When you change directories, project settings are loaded automatically
145+
4. **Fallback Logic**: Project model → User default model → System default (`grok-4-latest`)
146+
147+
This means you can have different models for different projects while maintaining consistent global settings like your API key.
148+
149+
### Using Other API Providers
150+
151+
**Important**: Grok CLI uses **OpenAI-compatible APIs**. You can use any provider that implements the OpenAI chat completions standard.
152+
153+
**Popular Providers**:
154+
- **X.AI (Grok)**: `https://api.x.ai/v1` (default)
155+
- **OpenAI**: `https://api.openai.com/v1`
156+
- **OpenRouter**: `https://openrouter.ai/api/v1`
157+
- **Groq**: `https://api.groq.com/openai/v1`
158+
159+
**Example with OpenRouter**:
160+
```json
161+
{
162+
"apiKey": "your_openrouter_key",
163+
"baseURL": "https://openrouter.ai/api/v1",
164+
"defaultModel": "anthropic/claude-3.5-sonnet",
165+
"models": [
166+
"anthropic/claude-3.5-sonnet",
167+
"openai/gpt-4o",
168+
"meta-llama/llama-3.1-70b-instruct"
169+
]
170+
}
171+
```
172+
90173
## Usage
91174

92175
### Interactive Mode
@@ -143,11 +226,11 @@ Add to `~/.grok/user-settings.json`:
143226
```json
144227
{
145228
"apiKey": "your_api_key_here",
146-
"model": "grok-4-latest"
229+
"defaultModel": "grok-4-latest"
147230
}
148231
```
149232

150-
Priority order: `--model` flag > `GROK_MODEL` environment variable > user settings > default (grok-4-latest)
233+
**Model Priority**: `--model` flag > `GROK_MODEL` environment variable > user default model > system default (grok-4-latest)
151234

152235
### Command Line Options
153236

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vibe-kit/grok-cli",
3-
"version": "0.0.17",
3+
"version": "0.0.18",
44
"description": "An open-source AI agent that brings the power of Grok directly into your terminal.",
55
"main": "dist/index.js",
66
"bin": {

src/agent/grok-agent.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { ToolResult } from "../types";
1818
import { EventEmitter } from "events";
1919
import { createTokenCounter, TokenCounter } from "../utils/token-counter";
2020
import { loadCustomInstructions } from "../utils/custom-instructions";
21-
import { getSetting } from "../utils/settings";
21+
import { getSettingsManager } from "../utils/settings-manager";
2222

2323
export interface ChatEntry {
2424
type: "user" | "assistant" | "tool_result" | "tool_call";
@@ -54,7 +54,8 @@ export class GrokAgent extends EventEmitter {
5454

5555
constructor(apiKey: string, baseURL?: string, model?: string) {
5656
super();
57-
const savedModel = getSetting("model");
57+
const manager = getSettingsManager();
58+
const savedModel = manager.getCurrentModel();
5859
const modelToUse = model || savedModel || "grok-4-latest";
5960
this.grokClient = new GrokClient(apiKey, modelToUse, baseURL);
6061
this.textEditor = new TextEditorTool();

src/hooks/use-input-handler.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { useState, useRef } from "react";
1+
import { useState, useMemo } from "react";
22
import { useInput } from "ink";
33
import { GrokAgent, ChatEntry } from "../agent/grok-agent";
44
import { ConfirmationService } from "../utils/confirmation-service";
5-
import { updateSetting } from "../utils/settings";
5+
66
import { filterCommandSuggestions } from "../ui/components/command-suggestions";
7+
import { loadModelConfig, updateCurrentModel } from "../utils/model-config";
78

89
interface UseInputHandlerProps {
910
agent: GrokAgent;
@@ -26,7 +27,6 @@ interface CommandSuggestion {
2627

2728
interface ModelOption {
2829
model: string;
29-
description: string;
3030
}
3131

3232
export function useInputHandler({
@@ -62,15 +62,10 @@ export function useInputHandler({
6262
{ command: "/exit", description: "Exit the application" },
6363
];
6464

65-
const availableModels: ModelOption[] = [
66-
{
67-
model: "grok-4-latest",
68-
description: "Latest Grok-4 model (most capable)",
69-
},
70-
{ model: "grok-3-latest", description: "Latest Grok-3 model" },
71-
{ model: "grok-3-fast", description: "Fast Grok-3 variant" },
72-
{ model: "grok-3-mini-fast", description: "Fastest Grok-3 variant" },
73-
];
65+
// Load models from configuration with fallback to defaults
66+
const availableModels: ModelOption[] = useMemo(() => {
67+
return loadModelConfig(); // Return directly, interface already matches
68+
}, []);
7469

7570
const handleDirectCommand = async (input: string): Promise<boolean> => {
7671
const trimmedInput = input.trim();
@@ -102,24 +97,27 @@ export function useInputHandler({
10297
Built-in Commands:
10398
/clear - Clear chat history
10499
/help - Show this help
105-
/models - Switch Grok models
100+
/models - Switch between available models
106101
/exit - Exit application
107102
exit, quit - Exit application
108-
103+
109104
Git Commands:
110105
/commit-and-push - AI-generated commit + push to remote
111-
106+
112107
Keyboard Shortcuts:
113108
Shift+Tab - Toggle auto-edit mode (bypass confirmations)
114109
115110
Direct Commands (executed immediately):
116111
ls [path] - List directory contents
117-
pwd - Show current directory
112+
pwd - Show current directory
118113
cd <path> - Change directory
119114
cat <file> - View file contents
120115
mkdir <dir> - Create directory
121116
touch <file>- Create empty file
122117
118+
Model Configuration:
119+
Edit ~/.grok/models.json to add custom models (Claude, GPT, Gemini, etc.)
120+
123121
For complex operations, just describe what you want in natural language.
124122
Examples:
125123
"edit package.json and add a new script"
@@ -150,7 +148,7 @@ Examples:
150148

151149
if (modelNames.includes(modelArg)) {
152150
agent.setModel(modelArg);
153-
updateSetting("model", modelArg);
151+
updateCurrentModel(modelArg); // Update project current model
154152
const confirmEntry: ChatEntry = {
155153
type: "assistant",
156154
content: `✓ Switched to model: ${modelArg}`,
@@ -172,6 +170,7 @@ Available models: ${modelNames.join(", ")}`,
172170
return true;
173171
}
174172

173+
175174
if (trimmedInput === "/commit-and-push") {
176175
const userEntry: ChatEntry = {
177176
type: "user",
@@ -665,7 +664,7 @@ Respond with ONLY the commit message, no additional text.`;
665664
if (key.tab || key.return) {
666665
const selectedModel = availableModels[selectedModelIndex];
667666
agent.setModel(selectedModel.model);
668-
updateSetting("model", selectedModel.model);
667+
updateCurrentModel(selectedModel.model); // Update project current model
669668
const confirmEntry: ChatEntry = {
670669
type: "assistant",
671670
content: `✓ Switched to model: ${selectedModel.model}`,

0 commit comments

Comments
 (0)