# OpenCode LiteLLM Provider Config Generator

Generate OpenCode LiteLLM provider model configuration from LiteLLM model metadata and models.dev fallback data.

## Requirements

- Node.js 22 or newer
- an OpenCode configuration with a LiteLLM provider entry
- an API auth entry for the selected provider in the local OpenCode auth file
- Network access to `https://models.dev/api.json` during generation

## Run With npx

Generate model configuration for an OpenCode provider backed by a remote LiteLLM instance:

```bash
npx @devboost/opencode-litellm-provider-config-generator --provider <provider-id>
```

The installed command name is defined by the package `bin` entry:

```bash
opencode-litellm-provider-config-generator --provider <provider-id>
```

## OpenCode Configuration

The CLI reads the provider from the OpenCode configuration file selected by `OPENCODE_CONFIG` or the default paths:

- `~/.config/opencode/opencode.jsonc`
- `~/.config/opencode/opencode.json`

Example provider entry:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "litellm": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "LiteLLM",
      "options": {
        "baseURL": "https://litellm.example.com"
      },
      "models": {}
    }
  }
}
```

The selected provider must define `options.baseURL`. The CLI requests model metadata from LiteLLM, trying endpoints in
order: `<baseURL>/v2/model/info` → `<baseURL>/v1/model/info` → `<baseURL>/model/info`. The next endpoint is only tried
when the previous one returns an HTTP status outside the 2xx range (e.g. 404 or 500).

The matching API key is read from the OpenCode auth file at `~/.local/share/opencode/auth.json`:

```json
{
  "litellm": {
    "type": "api",
    "key": "sk-example"
  }
}
```

## Usage

Limit generated models to aliases that contain a name filter:

```bash
npx @devboost/opencode-litellm-provider-config-generator --provider <provider-id> --include-model gpt --include-model claude
```

Exclude aliases that contain a name filter:

```bash
npx @devboost/opencode-litellm-provider-config-generator --provider <provider-id> --exclude-model embedding --exclude-model deprecated
```

Replace the selected provider's model list directly in the OpenCode configuration file:

```bash
npx @devboost/opencode-litellm-provider-config-generator --provider <provider-id> --inplace
```

The short sed-style flag is also supported:

```bash
npx @devboost/opencode-litellm-provider-config-generator --provider <provider-id> -i
```

The CLI reads the selected OpenCode provider and auth entry, requests model metadata from LiteLLM (trying
`<baseURL>/v2/model/info`, then `<baseURL>/v1/model/info`, then `<baseURL>/model/info` as fallbacks for non-2xx
responses), enriches missing model fields from `https://models.dev/api.json`, and writes an OpenCode model
configuration object to stdout by default. The JSON object keys remain the LiteLLM model aliases so OpenCode can still
route requests through LiteLLM.

Use `-i` or `--inplace` to replace `provider.<provider-id>.models` in the OpenCode configuration file selected by
`OPENCODE_CONFIG` or the default OpenCode config path. Existing models for that provider are completely replaced; other
providers and unrelated configuration entries are not changed. The planned file content is parsed as JSONC and validated
against the full OpenCode JSON schema from `https://opencode.ai/config.json` before the file is overwritten. If schema
loading or validation fails, the original file is left unchanged. Comments and formatting outside the replaced `models`
block are preserved where JSONC editing allows it.

Use `--include-model <name-filter>` to keep only LiteLLM aliases whose `model_name` contains at least one include
filter. Use `--exclude-model <name-filter>` to remove LiteLLM aliases whose `model_name` contains an exclude filter.
Both parameters are repeatable, use case-insensitive substring matching, and can be combined. When both are provided,
include filters are applied first and exclude filters remove matches from that included set.
Unknown CLI options are rejected with a usage error instead of being ignored.

Example output:

```json
{
  "private-gpt-4o": {
    "name": "GPT-4o",
    "family": "gpt",
    "limit": {
      "context": 128000,
      "output": 16384
    },
    "cost": {
      "input": 2.5,
      "output": 10,
      "cache_read": 1.25,
      "cache_write": 1.25
    },
    "tool_call": true,
    "reasoning": false,
    "attachment": true,
    "modalities": {
      "input": ["text", "image", "pdf"],
      "output": ["text"]
    }
  }
}
```
