Skip to content

Latest commit

 

History

History
522 lines (383 loc) · 14.1 KB

File metadata and controls

522 lines (383 loc) · 14.1 KB

Provider Setup

This document covers how to configure each supported LLM provider with qcr.

Supported Providers

Provider ID Models
OpenAI openai gpt-4o, gpt-4o-mini, o1, o3-mini, ...
Anthropic anthropic claude-3-5-sonnet, claude-3-opus, ...
Google Gemini gemini / google gemini-2.5-pro, gemini-2.5-flash, ...
DashScope (Alibaba) dashscope / qwen qwen3-coder, qwen-max, qwen-turbo, qwen-plus, ...
Azure OpenAI Service azure / azure_openai gpt-4o, gpt-4o-mini, o1, o3-mini, ...
GitHub Copilot copilot / github_copilot gpt-4o, claude-3.5-sonnet, o3-mini, ...
MiniMax openai (proxy) minimax-m2.5, minimax-m2.5-highspeed, minimax-m2.1, ...
OpenAI-compatible proxy openai any

OpenAI

API Key

export OPENAI_API_KEY=sk-...

Or in ~/.qcr/settings.json:

{
  "providers": {
    "openai": {
      "api_key": "sk-..."
    }
  }
}

Model selection

qcr --provider openai --model gpt-4o "refactor this function"

Custom base URL (proxy / Azure)

export OPENAI_API_BASE=https://my-proxy.example.com/v1

Or in settings:

{
  "providers": {
    "openai": {
      "base_url": "https://my-proxy.example.com/v1",
      "api_key": "..."
    }
  }
}

Anthropic

API Key

export ANTHROPIC_API_KEY=sk-ant-...

Usage

qcr --provider anthropic --model claude-3-5-sonnet-20241022 "explain this code"

Settings file

{
  "model": {
    "model_id": "claude-3-5-sonnet-20241022",
    "provider": "anthropic"
  },
  "providers": {
    "anthropic": {
      "api_key": "sk-ant-..."
    }
  }
}

Google Gemini

API Key

export GEMINI_API_KEY=AIza...

Usage

qcr --provider gemini --model gemini-2.5-pro "write tests for this module"

The provider alias google is also accepted:

qcr --provider google --model gemini-2.5-flash "summarize"

DashScope (Alibaba Cloud / qwen3-coder)

API Key

export DASHSCOPE_API_KEY=sk-...

Usage

qcr --provider dashscope --model qwen-max "translate this"
# or
qcr --provider qwen --model qwen-turbo "translate this"

Both `dashscope` and `qwen` resolve to the DashScope endpoint (`https://dashscope.aliyuncs.com/compatible-mode/v1`).

---

## Azure OpenAI Service

Azure OpenAI requires a **resource endpoint** and a deployment-scoped API key.
The `--model` / `model_id` value is used as the **deployment name** in the URL.

### Environment variables

```bash
export AZURE_OPENAI_API_KEY=...
export AZURE_OPENAI_ENDPOINT=https://my-resource.openai.azure.com
# Optional: override the REST API version (default: 2024-12-01-preview)
export AZURE_OPENAI_API_VERSION=2024-12-01-preview

Usage

qcr --provider azure --model gpt-4o "refactor this function"

Both azure and azure_openai are accepted as the provider ID.

Settings file

{
  "model": {
    "model_id": "gpt-4o",
    "provider": "azure"
  },
  "providers": {
    "azure": {
      "base_url": "https://my-resource.openai.azure.com",
      "api_key": "...",
      "custom_headers": {
        "api-version": "2024-12-01-preview"
      }
    }
  }
}

Note: The api-version entry in custom_headers controls the Azure REST API version query parameter. It is not sent as an HTTP header — qcr strips it before building the request and appends it to the URL automatically.

URL format

qcr constructs the request URL as:

https://{resource}.openai.azure.com/openai/deployments/{deployment}/chat/completions?api-version={version}

Authentication

Azure uses the api-key HTTP header (not Authorization: Bearer). For managed-identity / Entra ID scenarios, add "Authorization": "Bearer {token}" via custom_headers and omit the api_key field.

Available models

Supported models depend on which deployments exist in your Azure resource. Common deployment names:

Deployment name Underlying model
gpt-4o GPT-4o
gpt-4o-mini GPT-4o mini
o1 o1 reasoning model
o3-mini o3-mini reasoning model
gpt-4-turbo GPT-4 Turbo

GitHub Copilot

GitHub Copilot uses a two-step authentication flow: a GitHub OAuth token is exchanged for a short-lived Copilot API token, which is then used to call the OpenAI-compatible chat completions endpoint. qcr handles the token exchange and automatic refresh transparently.

Authentication

qcr resolves the GitHub OAuth token from these sources (first match wins):

  1. api_key in provider config — explicit setting in settings.json or CLI
  2. GH_COPILOT_TOKEN environment variable
  3. Local Copilot config files~/.config/github-copilot/hosts.json or apps.json (written by VS Code Copilot extension and GitHub CLI)

The easiest way to get started is to sign in to GitHub Copilot in VS Code or GitHub CLI first — qcr will pick up the cached OAuth token automatically.

# Option 1: Set the token directly
export GH_COPILOT_TOKEN=gho_...

# Option 2: Already signed in via VS Code / GitHub CLI — nothing to do
qcr --provider copilot --model gpt-4o "refactor this function"

Usage

qcr --provider copilot --model gpt-4o "explain this code"
qcr --provider copilot --model claude-3.5-sonnet "write tests"

The provider aliases copilot, github_copilot, and github-copilot are all accepted.

Settings file

{
  "model": {
    "model_id": "gpt-4o",
    "provider": "copilot"
  },
  "providers": {
    "copilot": {
      "api_key": "gho_..."
    }
  }
}

Note: You usually do not need to set api_key explicitly — qcr reads the token from ~/.config/github-copilot/hosts.json automatically.

GitHub Enterprise Server

For GitHub Enterprise (GHES) users, set base_url to your enterprise server URI. qcr derives the token exchange URL from this domain:

{
  "providers": {
    "copilot": {
      "base_url": "https://github.example.com"
    }
  }
}

This causes token exchange to go to https://api.github.example.com/copilot_internal/v2/token instead of the default https://api.github.com/copilot_internal/v2/token.

Available models

The models available depend on your Copilot subscription plan. Common models:

Model Notes
gpt-4o Default, fast and capable
gpt-4o-mini Faster, lower cost
claude-3.5-sonnet Anthropic model via Copilot
o3-mini OpenAI reasoning model (no temperature support)
o4-mini OpenAI reasoning model (no temperature support)
gpt-5.2-codex Codex model, uses Responses API (no temperature support)

How token exchange works

  1. qcr sends your GitHub OAuth token to the Copilot token endpoint
  2. The response includes a short-lived API key, an expiration timestamp, and the API endpoint URL
  3. qcr caches the API token and automatically refreshes it 5 minutes before expiry
  4. All chat completions requests use the dynamically assigned endpoint and API key

Troubleshooting

"no GitHub OAuth token available" — qcr could not find an OAuth token. Sign in to GitHub Copilot in VS Code, run gh auth login, or set GH_COPILOT_TOKEN.

401 from token exchange — your OAuth token is expired or revoked. Re-sign in to VS Code Copilot or regenerate the token.

400 Bad Request during a tool-use turn — several causes have been fixed across recent versions. Upgrade to the latest version first:

cargo install --path crates/qcr-cli --force
Version Root cause Fix
≤ 0.1.1 Assistant message missing "content" field on tool-call-only turns Always emit "content": null
≤ 0.1.2 OpenAI-only fields (intent, stream_options, n, presence_penalty, frequency_penalty) sent to Claude models via Copilot — Anthropic backend rejects them Strip these fields for Claude models
≤ 0.1.2 Empty string tool result content ("content": "") — Claude rejects blank tool results Replace empty content with "(no output)" placeholder
≤ 0.1.2 Tool call arguments serialised as "\"\"" (JSON string) instead of "{}" (JSON object) when Claude returns empty args for no-parameter tools like CronList Normalise non-object arguments to {}
≤ 0.1.15 temperature/top_p/presence_penalty sent to o-series and codex models — these reasoning models reject unsupported parameters with 400 Auto-detect o1/o3/o4-mini/codex models and skip temperature params

If you still see 400 errors after upgrading, enable debug logging to capture the full request/response bodies:

QCR_LOG=warn qcr --provider copilot --model claude-sonnet-4.6 "your prompt"
tail -f ~/.qcr/qcr.log

403 / subscription error — your GitHub account may not have an active Copilot subscription, or the model you requested is not included in your plan.


MiniMax

MiniMax models are accessed through any OpenAI-compatible proxy that serves them (e.g. aiproxies.win). Use openai as the provider and set a custom base_url.

Settings file

{
  "model": {
    "model_id": "minimax-m2.5",
    "provider": "openai"
  },
  "providers": {
    "openai": {
      "name": "openai",
      "base_url": "https://aiproxies.win/v1",
      "api_key": "YOUR_PROXY_KEY"
    }
  }
}

Available models

Model ID Notes
minimax-m2.5 Latest flagship model
minimax-m2.5-highspeed Faster, lower-latency variant
minimax-m2.1 Previous generation
minimax-m2.1-highspeed Fast variant of M2.1
minimax-m2 Baseline M2 generation

Usage

qcr --provider openai --model minimax-m2.5 "refactor this module"

List available models from the proxy:

curl -s https://aiproxies.win/v1/models \
  -H "Authorization: Bearer YOUR_PROXY_KEY" \
  | python3 -c "import sys,json; [print(m['id']) for m in json.load(sys.stdin)['data']]"

OpenAI-Compatible Proxies

Any service that speaks the OpenAI chat completions protocol works by setting OPENAI_API_BASE:

export OPENAI_API_BASE=https://openrouter.ai/api/v1
export OPENAI_API_KEY=sk-or-...
qcr --provider openai --model mistralai/mistral-7b-instruct "hello"

Tested proxies:

  • OpenRouter — access many models through one API
  • Together AI — open-source model hosting
  • Groq — fast inference
  • aiproxies.win — multi-model proxy (MiniMax, Gemini, and more)
  • Ollama — local models (use http://localhost:11434/v1)
  • LM Studio — local models (use http://localhost:1234/v1)

Ollama example

# Start Ollama with a model
ollama run llama3.2

# Point qcr at it
export OPENAI_API_BASE=http://localhost:11434/v1
export OPENAI_API_KEY=ollama   # any non-empty string
qcr --provider openai --model llama3.2 "explain this file"

Default Provider and Model

Set a persistent default in ~/.qcr/settings.json:

{
  "model": {
    "model_id": "minimax-m2.5",
    "provider": "openai"
  },
  "providers": {
    "openai": {
      "name": "openai",
      "base_url": "https://aiproxies.win/v1",
      "api_key": "YOUR_PROXY_KEY"
    }
  },
  "approval_mode": "suggest"
}

Switch to a different model for one session without changing settings:

qcr --model gemini-2.5-flash "summarize this PR"

Or via environment:

export QCR_PROVIDER=openai
export QCR_MODEL=minimax-m2.5

Command-line flags always take highest priority:

qcr --provider anthropic --model claude-3-5-sonnet-20241022 "..."

Provider Priority Resolution

When creating an API client, qcr resolves configuration in this order (highest wins):

  1. CLI flags: --provider, --model
  2. Environment variables: QCR_PROVIDER, QCR_MODEL, OPENAI_API_KEY, etc.
  3. Project settings: .qcr/settings.json in current directory
  4. Global settings: ~/.qcr/settings.json
  5. Built-in defaults: provider=dashscope, model=qwen3-coder

Prompt Caching Support

qcr supports prompt caching to reduce per-turn token costs. The static portion of the system prompt (base template) is marked as cacheable; dynamic content (memory, steering, memorix) is not cached.

Provider Cache Hints Sent Cache Tokens Read Mechanism
Anthropic yes read + write (streaming + non-streaming) cache_control: {type: "ephemeral"} in system array, anthropic-beta: prompt-caching-2024-07-31 header
OpenAI yes read only (streaming + non-streaming) Structured system message with cache_control, auto prefix caching
Azure yes read only (streaming + non-streaming) Same as OpenAI
Copilot yes read only (streaming + non-streaming) Same as OpenAI
Gemini no no No caching API in responses

Cache token usage is reported in the TokenUsage struct as cache_read_tokens and cache_write_tokens. These are visible in the TUI token counter when available.

No configuration is needed — prompt caching is automatic when SystemPromptBlocks are available (which they are in ACP mode). For TUI mode, blocks will be wired in a future release.


Troubleshooting

401 Unauthorized — API key is missing or wrong. Check echo $OPENAI_API_KEY.

approval_mode "prompt" is invalid — The valid values are always, never, and suggest. Using "prompt" causes a parse error and qcr silently falls back to defaults (no provider config → 401).

400 Bad Request after a tool call (any OpenAI-compatible provider) — qcr ≤ 0.1.1 omitted "content" entirely on assistant messages that contained only tool calls and no text. The OpenAI wire format requires "content": null in this case. Fixed in v0.1.2 — affects openai, azure, and copilot providers.

400 unknown provider for model — The proxy does not recognize the model name. List available models:

curl -s $OPENAI_API_BASE/models -H "Authorization: Bearer $OPENAI_API_KEY" \
  | python3 -c "import sys,json; [print(m['id']) for m in json.load(sys.stdin)['data']]"

Connection refusedOPENAI_API_BASE points to a server that is not running.

Rate limited — qcr respects 429 responses and surfaces a RateLimited error. Add retry logic or reduce request frequency.