Skip to content

models.json Configuration Guide

Overview

models.json is a configuration file used to customize the model list and control the model dropdown display. This configuration supports two levels:

  • User-level: ~/.codebuddy/models.json - Global configuration applicable to all projects
  • Project-level: <workspace>/.codebuddy/models.json - Project-specific configuration with higher priority than user-level

Configuration File Locations

User-level Configuration

~/.codebuddy/models.json

Project-level Configuration

<project-root>/.codebuddy/models.json

Configuration Priority

Configuration merge priority from highest to lowest:

  1. Project-level models.json
  2. User-level models.json
  3. Built-in default configuration

Project-level configuration will override user-level configuration for the same model definitions (based on id field matching). availableModels field: project-level completely overrides user-level, no merging.

Configuration Structure

json
{
  "models": [
    {
      "id": "model-id",
      "name": "Model Display Name",
      "vendor": "vendor-name",
      "apiKey": "sk-actual-api-key-value",
      "maxInputTokens": 200000,
      "maxOutputTokens": 8192,
      "url": "https://api.example.com/v1/chat/completions",
      "temperature": 0.7,
      "supportsToolCall": true,
      "supportsImages": true
    }
  ],
  "availableModels": ["model-id-1", "model-id-2"]
}

Configuration Field Description

models

Type: Array<LanguageModel>

Define custom model list. You can add new models or override built-in model configurations.

LanguageModel Fields

FieldTypeRequiredDescription
idstringModel unique identifier
namestring-Model display name
vendorstring-Model vendor (e.g., OpenAI, Google)
apiKeystring-API key, supports environment variable references (see Security Configuration below)
maxInputTokensnumber-Maximum input tokens
maxOutputTokensnumber-Maximum output tokens
urlstring-API endpoint URL, supports environment variable references (must be complete interface path, typically ending with /chat/completions)
temperaturenumber-Sampling temperature, range 0-2, higher values produce more random output, lower values produce more deterministic output
supportsToolCallboolean-Whether tool calls are supported
supportsImagesboolean-Whether image input is supported
supportsReasoningboolean-Whether reasoning mode is supported
relatedModelsobject-Related model configuration, specifies which model id to use in different scenarios (lite/reasoning/vision/longContext/subagent). See Configuring Related Models for details

Important Notes:

  • Currently only supports OpenAI interface format API
  • url field must be the complete interface path, typically ending with /chat/completions
  • Examples: https://api.openai.com/v1/chat/completions or http://localhost:11434/v1/chat/completions

Security Configuration: Using Environment Variable References

To avoid storing API keys in plain text in configuration files, the apiKey and url fields support environment variable reference syntax ${VAR_NAME}.

Syntax Format:

${ENVIRONMENT_VARIABLE_NAME}

Configuration Example:

json
{
  "models": [
    {
      "id": "gpt-4o",
      "name": "GPT-4o",
      "vendor": "OpenAI",
      "apiKey": "${OPENAI_API_KEY}",
      "url": "https://api.openai.com/v1/chat/completions"
    }
  ]
}

Setting Environment Variables:

bash
# Add to ~/.zshrc or ~/.bashrc
export OPENAI_API_KEY="sk-your-actual-api-key"

# Or set temporarily at startup
OPENAI_API_KEY="sk-xxx" codebuddy

Using System Keychain (macOS):

bash
# Store key in Keychain
security add-generic-password -a "$USER" -s "openai-api-key" -w "sk-xxx"

# Configure auto-export in ~/.zshrc
export OPENAI_API_KEY=$(security find-generic-password -s "openai-api-key" -w 2>/dev/null)

Important Notes:

  • Environment variables are resolved at CLI startup
  • If an environment variable doesn't exist, the original placeholder is retained (which will cause API call failures)
  • It's recommended to set models.json file permissions to 600 (owner read/write only)
  • Do not commit configuration files containing actual keys to version control systems

availableModels

Type: Array<string>

Control which models are displayed in the model dropdown list. Only model IDs listed in this array will be shown in the UI.

  • If not configured or empty array, all models are displayed
  • When configured, only listed model IDs are displayed
  • Can include both built-in and custom model IDs

Use Cases

1. Add Custom Model

Add new model configuration at user or project level:

json
{
  "models": [
    {
      "id": "my-custom-model",
      "name": "My Custom Model",
      "vendor": "OpenAI",
      "apiKey": "sk-custom-key-here",
      "maxInputTokens": 128000,
      "maxOutputTokens": 4096,
      "url": "https://api.myservice.com/v1/chat/completions",
      "supportsToolCall": true
    }
  ]
}

2. Override Built-in Model Configuration

Modify default parameters of built-in models:

json
{
  "models": [
    {
      "id": "gpt-4-turbo",
      "name": "GPT-4 Turbo (Custom Endpoint)",
      "vendor": "OpenAI",
      "url": "https://my-proxy.example.com/v1/chat/completions",
      "apiKey": "sk-your-key-here"
    }
  ]
}

3. Limit Available Model List

Only display specific models in the dropdown list:

json
{
  "availableModels": [
    "gpt-4-turbo",
    "gpt-4o",
    "my-custom-model"
  ]
}

4. Project-Specific Configuration

Use different models or API endpoints for specific projects:

Project A (.codebuddy/models.json):

json
{
  "models": [
    {
      "id": "project-a-model",
      "name": "Project A Model",
      "vendor": "OpenAI",
      "url": "https://project-a-api.example.com/v1/chat/completions",
      "apiKey": "sk-project-a-key",
      "maxInputTokens": 100000,
      "maxOutputTokens": 4096
    }
  ],
  "availableModels": ["project-a-model", "gpt-4-turbo"]
}

Hot Reload

Configuration file supports hot reload:

  • File changes are automatically detected
  • Uses 1 second debounce delay to avoid frequent reloads
  • Configuration updates are automatically synced to the application

Monitored files:

  • ~/.codebuddy/models.json (user-level)
  • <workspace>/.codebuddy/models.json (project-level)

Tagging System

Models added through models.json are automatically tagged with the custom tag for easy identification and filtering in the UI.

Merge Strategy

Configuration uses SmartMerge strategy:

  • Model configurations with the same ID are overridden
  • Models with different IDs are appended
  • Project-level configuration takes priority over user-level configuration
  • availableModels filtering is executed after all merging is complete

Example Configurations

API Endpoint URL Format

Must use complete path: All custom model url fields should typically end with /chat/completions.

Correct Examples:

https://api.openai.com/v1/chat/completions
https://api.myservice.com/v1/chat/completions
http://localhost:11434/v1/chat/completions
https://my-proxy.example.com/v1/chat/completions

Incorrect Examples:

https://api.openai.com/v1
https://api.myservice.com
http://localhost:11434

OpenRouter Platform Configuration Example

Using OpenRouter to access various models:

json
{
  "models": [
    {
      "id": "openai/gpt-4o",
      "name": "open-router-model",
      "url": "https://openrouter.ai/api/v1/chat/completions",
      "apiKey": "sk-or-v1-your-openrouter-api-key",
      "maxInputTokens": 128000,
      "maxOutputTokens": 4096,
      "supportsToolCall": true,
      "supportsImages": false
    }
  ]
}

DeepSeek Platform Configuration Example

Using DeepSeek models (once url is configured, even entries with the same id as cloud defaults take effect with "full replacement" semantics and are not overridden by cloud default merges):

json
{
  "models": [
    {
      "id": "deepseek-v4-pro",
      "name": "DeepSeek V4 Pro",
      "vendor": "DeepSeek",
      "url": "https://api.deepseek.com/v1/chat/completions",
      "apiKey": "${DEEPSEEK_API_KEY}",
      "maxInputTokens": 128000,
      "maxOutputTokens": 8192,
      "supportsToolCall": true,
      "supportsImages": false
    },
    {
      "id": "deepseek-v4-flash",
      "name": "DeepSeek V4 Flash",
      "vendor": "DeepSeek",
      "url": "https://api.deepseek.com/v1/chat/completions",
      "apiKey": "${DEEPSEEK_API_KEY}",
      "maxInputTokens": 128000,
      "maxOutputTokens": 8192,
      "supportsToolCall": true,
      "supportsImages": false
    }
  ],
  "availableModels": [
    "deepseek-v4-pro",
    "deepseek-v4-flash"
  ]
}

Set the API key environment variable and start:

bash
export DEEPSEEK_API_KEY="<your-deepseek-api-key>"
codebuddy --model deepseek-v4-pro

Tip: If you prefer not to maintain a models.json, you can also connect to DeepSeek entirely through environment variables. See env-vars.md DeepSeek Integration Example.

During a single CodeBuddy Code session, the model is switched based on the scenario, to avoid using a large model for simple tasks or a general-purpose model for requests that need reasoning / vision / long-context. These scenarios are declared via the relatedModels field on a model entry.

Supported scenarios (variant type):

ScenarioPurposeCurrent Status
liteLightweight fast model, used for background extraction, summarization, and other low-value requests; also the model corresponding to the Agent tool's model: "lite" parameterActive
reasoningReasoning-enhanced model, used for complex reasoning requiring deep thinking; the model corresponding to the Agent tool's model: "reasoning" parameterActive
subagentDefault model used by sub-agents / team membersReserved, not yet active — currently the sub-agent model is determined by the CODEBUDDY_CODE_SUBAGENT_MODEL environment variable or the agent configuration's models[0], and this field is not read
visionVision understanding model, used for requests that need to process imagesReserved, not yet active — the type is defined but there is no call site consuming this variant
longContextLong-context model, used for requests with very long contextReserved, not yet active — the type is defined but there is no call site consuming this variant

Currently actually usable: only the two variants lite and reasoning are consumed by the agent-manager and mapped into the model switching logic. subagent / vision / longContext are only kept in the type definitions, reserved for future iterations; writing them into relatedModels today will not error but will also have no effect.

Key rule (must-read for custom models):

Custom models added via models.json do not inherit the product's built-in defaultRelatedModels. If relatedModels is not explicitly declared on the entry itself, all scenarios fall back to the main model itself — meaning sub-agents, lite, and reasoning all run on the same large model, which is inefficient in both cost and speed.

Configuration example (DeepSeek main model + flash as lite / reasoning):

json
{
  "models": [
    {
      "id": "deepseek-v4-pro",
      "name": "DeepSeek V4 Pro",
      "vendor": "DeepSeek",
      "url": "https://api.deepseek.com/v1/chat/completions",
      "apiKey": "${DEEPSEEK_API_KEY}",
      "maxInputTokens": 128000,
      "maxOutputTokens": 8192,
      "supportsToolCall": true,
      "relatedModels": {
        "lite": "deepseek-v4-flash",
        "reasoning": "deepseek-v4-pro"
      }
    },
    {
      "id": "deepseek-v4-flash",
      "name": "DeepSeek V4 Flash",
      "vendor": "DeepSeek",
      "url": "https://api.deepseek.com/v1/chat/completions",
      "apiKey": "${DEEPSEEK_API_KEY}",
      "maxInputTokens": 128000,
      "maxOutputTokens": 8192,
      "supportsToolCall": true
    }
  ],
  "availableModels": [
    "deepseek-v4-pro",
    "deepseek-v4-flash"
  ]
}

Resolution priority (from highest to lowest; currently only lite / reasoning go through this resolution chain):

  1. Environment variables explicitly specified (CODEBUDDY_SMALL_FAST_MODEL corresponds to lite, CODEBUDDY_BIG_SLOW_MODEL corresponds to reasoning)
  2. relatedModels[variant] on the current main model entry
  3. The product's built-in defaultRelatedModels[variant] (only takes effect for built-in models; custom models skip this step)
  4. Fall back to the main model itself

The resolution rule for sub-agent models does not go through relatedModels.subagent, but follows an independent chain: the Agent tool's model parameter > the CODEBUDDY_CODE_SUBAGENT_MODEL environment variable > the agent configuration's models[0] > the main model.

Trade-offs with the environment variable approach:

  • If you want a main model to automatically switch to another small model from the same vendor in the lite / reasoning scenarios: declaring relatedModels on the main model entry is the most intuitive way, and the binding follows the model.
  • If you want sub-agents to use a small model: currently you must go through the environment variable CODEBUDDY_CODE_SUBAGENT_MODEL, or write the small model into models[0] in the agent configuration — not via relatedModels.subagent.
  • If you want different large/small model combinations in different projects: use environment variables (CODEBUDDY_MODEL / CODEBUDDY_BIG_SLOW_MODEL / CODEBUDDY_SMALL_FAST_MODEL / CODEBUDDY_CODE_SUBAGENT_MODEL) combined with project-level .env switching.
  • When both approaches are active simultaneously, environment variables take priority.

Complete Example

json
{
  "models": [
    {
      "id": "gpt-4o",
      "name": "GPT-4o",
      "vendor": "OpenAI",
      "apiKey": "sk-your-openai-key",
      "maxInputTokens": 128000,
      "maxOutputTokens": 16384,
      "supportsToolCall": true,
      "supportsImages": true
    },
    {
      "id": "my-local-llm",
      "name": "My Local LLM",
      "vendor": "Ollama",
      "url": "http://localhost:11434/v1/chat/completions",
      "apiKey": "ollama",
      "maxInputTokens": 8192,
      "maxOutputTokens": 2048,
      "supportsToolCall": true
    }
  ],
  "availableModels": [
    "gpt-4o",
    "my-local-llm"
  ]
}

Troubleshooting

Configuration Not Taking Effect

  1. Check if JSON format is correct
  2. Confirm file path is correct
  3. View log output to confirm configuration is loaded
  4. Confirm API keys in environment variables are set

Model Not Showing in List

  1. Check if model ID is listed in availableModels
  2. Confirm models configuration is correct
  3. Verify all required fields (id, name, provider) are provided

Hot Reload Not Triggered

  • Configuration file changes have 1 second debounce delay
  • Ensure file is actually saved to disk
  • Check if file watching started normally (view debug logs)