DEV Community

Aman Kumar
Aman Kumar

Posted on Originally published at telegra.ph Fully Autonomous

OpenCode and Kilo Code With Any OpenAI-Compatible Provider: Config Files That Work, and the Context Limit Trap

OpenCode and Kilo Code both let you add your own OpenAI-compatible provider, and both configs look simple. The part that bit me wasn't the URL or the key. It was a missing limit block that made long sessions fall over an hour in, with no obvious cause.

Here are the configs I use and the mistakes I made getting there. My examples point at APIClaw, an OpenAI-compatible gateway I build, so weigh that accordingly. Swap in any provider's base URL and model IDs.

What you need first

  1. A base URL that ends in /v1 (for example https://apiclaw.biz/v1). Don't add /chat/completions; the client adds the path.
  2. An API key in an environment variable, so it never lands in a file you might commit:
export APICLAW_API_KEY="sk-your-key"
Enter fullscreen mode Exit fullscreen mode
  1. The exact model ID from the provider's model list. Short aliases and display names cause most "model not found" errors.
  2. The model's real context window and max output tokens. You'll need these numbers below.

OpenCode

OpenCode's provider docs say any OpenAI-compatible API works through the @ai-sdk/openai-compatible package. Put this in ~/.config/opencode/opencode.json (a project-level opencode.json also works):

{
  "$schema": "https://opencode.ai/config.json",
  "model": "apiclaw/YOUR_MODEL_ID",
  "provider": {
    "apiclaw": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "APIClaw",
      "options": {
        "baseURL": "https://apiclaw.biz/v1",
        "apiKey": "{env:APICLAW_API_KEY}"
      },
      "models": {
        "YOUR_MODEL_ID": {
          "name": "YOUR_MODEL_ID",
          "limit": { "context": 200000, "output": 16384 }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

How the pieces connect:

  • apiclaw under provider is a provider ID you choose. The top-level model is that ID, a slash, then the model key: apiclaw/YOUR_MODEL_ID.
  • The key under models must match the ID the server returns from GET /v1/models. OpenCode's docs spell out the same rule in their local-server example.
  • {env:APICLAW_API_KEY} reads the variable at runtime.

If you'd rather not use an environment variable, run opencode auth login (or /connect inside OpenCode), choose Other, and enter the same provider ID, apiclaw. That stores the key, but it doesn't ask for a base URL or models, so you still need the opencode.json block. The provider ID you type there has to match the key under provider exactly.

Verify with /models. Your model should be listed under the provider name. Then send a one-line prompt and check the provider's request log.

Kilo Code

Kilo Code has two ways in.

VS Code extension: Settings, then the Providers tab, then Custom provider at the bottom. Give it a unique provider ID, choose OpenAI Compatible as the provider API, paste the /v1 base URL and your key, then pick a model from the fetched list or paste the exact ID.

Kilo CLI: the provider block goes in the global ~/.config/kilo/kilo.jsonc:

{
  "$schema": "https://app.kilo.ai/config.json",
  "model": "openai-compatible/YOUR_MODEL_ID",
  "provider": {
    "openai-compatible": {
      "options": {
        "baseURL": "https://apiclaw.biz/v1",
        "apiKey": "{env:APICLAW_API_KEY}"
      },
      "models": {
        "YOUR_MODEL_ID": {
          "name": "YOUR_MODEL_ID",
          "tool_call": true,
          "limit": { "context": 200000, "output": 16384 }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The global file matters. In my setup, {env:...} only resolved from the global config; the same block in a project file silently failed to authenticate. If Kilo says your key is invalid and curl says it's fine, check which file the block is in. kilo models confirms whether the provider loaded.

The context limit trap

Both tools know the context window for models in their built-in catalogs. A custom provider's model isn't in that catalog, so the client only knows what you tell it in limit.

Leave limit out and the client doesn't know the context size; in Kilo a custom model with no limit resolves to zero. Compaction (the step where the agent summarizes old turns to make room) never triggers, the conversation keeps growing, and eventually the provider rejects a request for being too long. It looks like a random failure an hour into a session, and it has nothing to do with the provider being flaky.

Set context to the model's real window and output to its real max output tokens, from the vendor's model page. Setting them a bit lower than the real numbers is fine and leaves headroom. Setting them higher than the real numbers brings the same failure back.

Errors and what they meant

Invalid API key / 401. Key pasted with a trailing space, key inactive, or (Kilo) the block is in a project file where {env:...} didn't resolve.

Model not found / 404. The model key isn't the exact server ID, or the base URL is missing /v1 or has /chat/completions on the end.

The model appears but tool calls are ignored. The model doesn't support function calling well, or (Kilo) tool_call isn't set to true on the custom model entry. Try a model known for tool use before blaming the provider.

Long sessions die with a context-length error. Missing or inflated limit. See above.

You need the Responses API. For OpenCode, switch the npm package to @ai-sdk/openai; @ai-sdk/openai-compatible speaks Chat Completions. Only do this if your provider serves /v1/responses.

Checklist

  • Base URL ends in /v1, nothing after it.
  • Key lives in an environment variable, referenced as {env:NAME}.
  • Model key equals the ID from GET /v1/models, and the top-level model is providerid/modelkey.
  • limit.context and limit.output set to the model's real numbers.
  • Kilo CLI block is in the global ~/.config/kilo/kilo.jsonc.
  • /models (OpenCode) or kilo models (Kilo) shows the model, and a test prompt shows up in the provider's log.

OpenCode's providers page at opencode.ai/docs and Kilo's own docs are the source of truth if the config schema changes.

Top comments (0)