Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 87 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Create `~/.grok/user-settings.json`:

### Custom Base URL (Optional)

You can configure a custom Grok API endpoint (choose one method):
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):

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

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

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

## Configuration Files

Grok CLI uses two types of configuration files to manage settings:

### User-Level Settings (`~/.grok/user-settings.json`)

This file stores **global settings** that apply across all projects. These settings rarely change and include:

- **API Key**: Your Grok API key
- **Base URL**: Custom API endpoint (if needed)
- **Default Model**: Your preferred model (e.g., `grok-4-latest`)
- **Available Models**: List of models you can use

**Example:**
```json
{
"apiKey": "your_api_key_here",
"baseURL": "https://api.x.ai/v1",
"defaultModel": "grok-4-latest",
"models": [
"grok-4-latest",
"grok-3-latest",
"grok-3-fast",
"grok-3-mini-fast"
]
}
```

### Project-Level Settings (`.grok/settings.json`)

This file stores **project-specific settings** in your current working directory. It includes:

- **Current Model**: The model currently in use for this project
- **MCP Servers**: Model Context Protocol server configurations

**Example:**
```json
{
"model": "grok-3-fast",
"mcpServers": {
"linear": {
"name": "linear",
"transport": "stdio",
"command": "npx",
"args": ["@linear/mcp-server"]
}
}
}
```

### How It Works

1. **Global Defaults**: User-level settings provide your default preferences
2. **Project Override**: Project-level settings override defaults for specific projects
3. **Directory-Specific**: When you change directories, project settings are loaded automatically
4. **Fallback Logic**: Project model → User default model → System default (`grok-4-latest`)

This means you can have different models for different projects while maintaining consistent global settings like your API key.

### Using Other API Providers

**Important**: Grok CLI uses **OpenAI-compatible APIs**. You can use any provider that implements the OpenAI chat completions standard.

**Popular Providers**:
- **X.AI (Grok)**: `https://api.x.ai/v1` (default)
- **OpenAI**: `https://api.openai.com/v1`
- **OpenRouter**: `https://openrouter.ai/api/v1`
- **Groq**: `https://api.groq.com/openai/v1`

**Example with OpenRouter**:
```json
{
"apiKey": "your_openrouter_key",
"baseURL": "https://openrouter.ai/api/v1",
"defaultModel": "anthropic/claude-3.5-sonnet",
"models": [
"anthropic/claude-3.5-sonnet",
"openai/gpt-4o",
"meta-llama/llama-3.1-70b-instruct"
]
}
```

## Usage

### Interactive Mode
Expand Down Expand Up @@ -143,11 +226,11 @@ Add to `~/.grok/user-settings.json`:
```json
{
"apiKey": "your_api_key_here",
"model": "grok-4-latest"
"defaultModel": "grok-4-latest"
}
```

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

### Command Line Options

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vibe-kit/grok-cli",
"version": "0.0.17",
"version": "0.0.18",
"description": "An open-source AI agent that brings the power of Grok directly into your terminal.",
"main": "dist/index.js",
"bin": {
Expand Down
5 changes: 3 additions & 2 deletions src/agent/grok-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ToolResult } from "../types";
import { EventEmitter } from "events";
import { createTokenCounter, TokenCounter } from "../utils/token-counter";
import { loadCustomInstructions } from "../utils/custom-instructions";
import { getSetting } from "../utils/settings";
import { getSettingsManager } from "../utils/settings-manager";

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

constructor(apiKey: string, baseURL?: string, model?: string) {
super();
const savedModel = getSetting("model");
const manager = getSettingsManager();
const savedModel = manager.getCurrentModel();
const modelToUse = model || savedModel || "grok-4-latest";
this.grokClient = new GrokClient(apiKey, modelToUse, baseURL);
this.textEditor = new TextEditorTool();
Expand Down
35 changes: 17 additions & 18 deletions src/hooks/use-input-handler.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useState, useRef } from "react";
import { useState, useMemo } from "react";
import { useInput } from "ink";
import { GrokAgent, ChatEntry } from "../agent/grok-agent";
import { ConfirmationService } from "../utils/confirmation-service";
import { updateSetting } from "../utils/settings";

import { filterCommandSuggestions } from "../ui/components/command-suggestions";
import { loadModelConfig, updateCurrentModel } from "../utils/model-config";

interface UseInputHandlerProps {
agent: GrokAgent;
Expand All @@ -26,7 +27,6 @@ interface CommandSuggestion {

interface ModelOption {
model: string;
description: string;
}

export function useInputHandler({
Expand Down Expand Up @@ -62,15 +62,10 @@ export function useInputHandler({
{ command: "/exit", description: "Exit the application" },
];

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

const handleDirectCommand = async (input: string): Promise<boolean> => {
const trimmedInput = input.trim();
Expand Down Expand Up @@ -102,24 +97,27 @@ export function useInputHandler({
Built-in Commands:
/clear - Clear chat history
/help - Show this help
/models - Switch Grok models
/models - Switch between available models
/exit - Exit application
exit, quit - Exit application

Git Commands:
/commit-and-push - AI-generated commit + push to remote

Keyboard Shortcuts:
Shift+Tab - Toggle auto-edit mode (bypass confirmations)

Direct Commands (executed immediately):
ls [path] - List directory contents
pwd - Show current directory
pwd - Show current directory
cd <path> - Change directory
cat <file> - View file contents
mkdir <dir> - Create directory
touch <file>- Create empty file

Model Configuration:
Edit ~/.grok/models.json to add custom models (Claude, GPT, Gemini, etc.)

For complex operations, just describe what you want in natural language.
Examples:
"edit package.json and add a new script"
Expand Down Expand Up @@ -150,7 +148,7 @@ Examples:

if (modelNames.includes(modelArg)) {
agent.setModel(modelArg);
updateSetting("model", modelArg);
updateCurrentModel(modelArg); // Update project current model
const confirmEntry: ChatEntry = {
type: "assistant",
content: `✓ Switched to model: ${modelArg}`,
Expand All @@ -172,6 +170,7 @@ Available models: ${modelNames.join(", ")}`,
return true;
}


if (trimmedInput === "/commit-and-push") {
const userEntry: ChatEntry = {
type: "user",
Expand Down Expand Up @@ -665,7 +664,7 @@ Respond with ONLY the commit message, no additional text.`;
if (key.tab || key.return) {
const selectedModel = availableModels[selectedModelIndex];
agent.setModel(selectedModel.model);
updateSetting("model", selectedModel.model);
updateCurrentModel(selectedModel.model); // Update project current model
const confirmEntry: ChatEntry = {
type: "assistant",
content: `✓ Switched to model: ${selectedModel.model}`,
Expand Down
Loading
Loading