Skip to content
Open
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
25 changes: 25 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ ANTHROPIC_API_KEY=sk-ant-api03-...
# Get your key at https://z.ai/manage-apikey/apikey-list
# ZHIPU_API_KEY=...

# MiniMax direct access with the open runtime. The image registers global and
# China OpenAI-compatible providers plus an Anthropic-compatible provider for
# MiniMax-M3 and MiniMax-M2.7.
# MINIMAX_API_KEY=...
# SWE_DEFAULT_RUNTIME=open_code
# SWE_DEFAULT_MODEL=minimax-global-openai/MiniMax-M3
# China endpoint: SWE_DEFAULT_MODEL=minimax-cn-openai/MiniMax-M3
# Anthropic-compatible endpoint:
# ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic
# SWE_DEFAULT_MODEL=minimax-anthropic/MiniMax-M3

# MiniMax direct access with the Claude runtime. Claude Code appends
# /v1/messages to this Anthropic-compatible base URL.
# ANTHROPIC_AUTH_TOKEN=...
# ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic
# China endpoint: ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic
# SWE_DEFAULT_RUNTIME=claude_code
# SWE_DEFAULT_MODEL=MiniMax-M3

# Note: Can reuse ANTHROPIC_API_KEY from above for Claude models via OpenCode

# --- Optional: Go node direct-LLM path (QA synthesizer) ---
Expand Down Expand Up @@ -153,6 +172,12 @@ GH_TOKEN=ghp_...
# Available open runtime model IDs (format: provider/model-name):
# deepseek/deepseek-chat # DeepSeek via OpenRouter
# minimax/minimax-m2.5 # MiniMax M2.5 via OpenRouter
# minimax-global-openai/MiniMax-M3 # MiniMax global OpenAI-compatible API
# minimax-global-openai/MiniMax-M2.7 # MiniMax global OpenAI-compatible API
# minimax-cn-openai/MiniMax-M3 # MiniMax China OpenAI-compatible API
# minimax-cn-openai/MiniMax-M2.7 # MiniMax China OpenAI-compatible API
# minimax-anthropic/MiniMax-M3 # MiniMax Anthropic-compatible API
# minimax-anthropic/MiniMax-M2.7 # MiniMax Anthropic-compatible API
# qwen/qwen-2.5-72b-instruct # Qwen via OpenRouter
# openai/gpt-4o # GPT-4 via OpenAI
# anthropic/claude-sonnet-4 # Claude via Anthropic
Expand Down
5 changes: 2 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ ENV PATH="/root/.opencode/bin:${PATH}"
# env override has *some* value to interpolate. Railway / docker-compose
# overrides win because their env injects after the image's ENV.
ENV HARNESS_MODEL=openrouter/moonshotai/kimi-k2.6
RUN mkdir -p /root/.config/opencode && \
echo '{"$schema":"https://opencode.ai/config.json","model":"{env:HARNESS_MODEL}","small_model":"{env:HARNESS_MODEL}","provider":{"openrouter":{"options":{"apiKey":"{env:OPENROUTER_API_KEY}"}}}}' \
> /root/.config/opencode/opencode.json
RUN mkdir -p /root/.config/opencode
COPY opencode.json /root/.config/opencode/opencode.json

# Git identity — env vars take highest precedence and are inherited by all
# subprocesses including Claude Code agent instances spawned by the SDK
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,29 @@ JSON

For OpenRouter with `open_code`, use model IDs in `openrouter/<provider>/<model>` format (for example `openrouter/minimax/minimax-m2.5`).

### MiniMax direct providers

The Docker images include direct MiniMax provider entries for both supported regions and API compatibility modes. `MiniMax-M3` and `MiniMax-M2.7` are available in every entry.

| Region | OpenAI-compatible `open_code` model IDs | Anthropic-compatible `open_code` model IDs | Anthropic base URL |
|---|---|---|---|
| Global | `minimax-global-openai/MiniMax-M3`, `minimax-global-openai/MiniMax-M2.7` | `minimax-anthropic/MiniMax-M3`, `minimax-anthropic/MiniMax-M2.7` | `https://api.minimax.io/anthropic` |
| China | `minimax-cn-openai/MiniMax-M3`, `minimax-cn-openai/MiniMax-M2.7` | `minimax-anthropic/MiniMax-M3`, `minimax-anthropic/MiniMax-M2.7` | `https://api.minimaxi.com/anthropic` |

| Model | Context window | Input modalities | Thinking | Service tier | Input range | Input / output / cache read / cache write per million tokens |
|---|---:|---|---|---|---|---|
| `MiniMax-M3` | 1,000,000 | text, image, video | adaptive or disabled | standard | up to 512,000 | $0.30 / $1.20 / $0.06 / not charged |
| `MiniMax-M3` | 1,000,000 | text, image, video | adaptive or disabled | standard | above 512,000 | $0.60 / $2.40 / $0.12 / not charged |
| `MiniMax-M3` | 1,000,000 | text, image, video | adaptive or disabled | priority | up to 512,000 | $0.45 / $1.80 / $0.09 / not charged |
| `MiniMax-M3` | 1,000,000 | text, image, video | adaptive or disabled | priority | above 512,000 | $0.90 / $3.60 / $0.18 / not charged |
| `MiniMax-M2.7` | 204,800 | text | always on | standard | all inputs | $0.30 / $1.20 / $0.06 / $0.375 |

For the direct OpenAI-compatible path, set `MINIMAX_API_KEY`, use `runtime: "open_code"`, and select one of the `minimax-global-openai/*` or `minimax-cn-openai/*` model IDs above. The configured OpenAI-compatible base URLs are `https://api.minimax.io/v1` and `https://api.minimaxi.com/v1`.

For the Anthropic-compatible OpenCode path, set `MINIMAX_API_KEY`, set `ANTHROPIC_BASE_URL` to either regional `/anthropic` URL shown above, use `runtime: "open_code"`, and select `minimax-anthropic/MiniMax-M3` or `minimax-anthropic/MiniMax-M2.7`. The OpenCode adapter derives `/v1` internally; keep the configured base URL at `/anthropic`.

For the Anthropic-compatible Claude path, set `ANTHROPIC_AUTH_TOKEN`, set `ANTHROPIC_BASE_URL` to the regional `/anthropic` URL shown above, use `runtime: "claude_code"`, and select `MiniMax-M3` or `MiniMax-M2.7`. Do not append `/v1`; Claude Code adds `/v1/messages` to the configured base URL.

For Codex with ChatGPT subscription auth, install the Codex CLI on the host, run `codex login`, leave `OPENAI_API_KEY` unset for this process, and set `SWE_CODEX_AUTH_MODE=chatgpt` or `auto`. For OpenAI API-platform billing, set `SWE_CODEX_AUTH_MODE=api_key` and `OPENAI_API_KEY`.

> **Codex deployments using the Docker image must set `SWE_DEFAULT_MODEL=gpt-5.3-codex` on the environment** (or pass `models: {"default": "gpt-5.3-codex"}` in every build's `config`). The image bakes `HARNESS_MODEL=openrouter/moonshotai/kimi-k2.6` as an OpenCode fallback, and SWE-AF's model-resolution env cascade reads `HARNESS_MODEL` — so without `SWE_DEFAULT_MODEL` set, the Codex CLI receives an OpenRouter model id it can't handle and the Product Manager reasoner fails in ~13s. Setting `SWE_DEFAULT_MODEL` makes the cascade pin every role to the Codex model.
Expand Down
14 changes: 13 additions & 1 deletion agentfield-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ agent_node:

user_environment:
require_one_of:
# SWE-AF runs on either Claude (Anthropic) or open models via OpenRouter.
# SWE-AF runs on Claude-compatible APIs or open models via OpenCode.
# Provide one. With only an OpenRouter key it auto-selects the open_code
# runtime and defaults to openrouter/deepseek/deepseek-v4-flash.
- id: llm_provider
Expand All @@ -28,6 +28,14 @@ user_environment:
description: OpenRouter API key (DeepSeek/Qwen/Llama/… — 200+ models)
type: secret
scope: global
- name: MINIMAX_API_KEY
description: MiniMax API key for direct OpenCode providers
type: secret
scope: global
- name: ANTHROPIC_AUTH_TOKEN
description: Anthropic-compatible auth token for the Claude runtime
type: secret
scope: global
required:
# SWE-AF's core loop clones a repo, pushes a branch, and opens a pull
# request — all of which need GitHub write access. `gh`/`git` read this
Expand All @@ -38,8 +46,12 @@ user_environment:
type: secret
scope: global
optional:
- name: SWE_DEFAULT_RUNTIME
description: Default runtime (claude_code, open_code, or codex)
- name: SWE_DEFAULT_MODEL
description: Override the model id for every role (e.g. openrouter/deepseek/deepseek-v4-flash)
- name: ANTHROPIC_BASE_URL
description: Anthropic-compatible base URL for OpenCode or Claude Code
- name: AGENTFIELD_SERVER
description: Control-plane URL
default: http://localhost:8080
Expand Down
12 changes: 12 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ cp .env.example .env
| `OPENROUTER_API_KEY` | OpenRouter API key (200+ models) |
| `OPENAI_API_KEY` | OpenAI API key |
| `GOOGLE_API_KEY` | Google Gemini API key |
| `MINIMAX_API_KEY` | MiniMax API key for direct OpenAI- and Anthropic-compatible `open_code` providers |

**For direct MiniMax with the Claude runtime:**

| Variable | Purpose |
|---|---|
| `ANTHROPIC_AUTH_TOKEN` | MiniMax API key used by Claude Code |
| `ANTHROPIC_BASE_URL` | `https://api.minimax.io/anthropic` (global) or `https://api.minimaxi.com/anthropic` (China) |

**For Codex CLI runtime:**

Expand All @@ -50,6 +58,10 @@ cp .env.example .env
| `AGENTFIELD_SERVER` | Control plane URL | `http://control-plane:8080` (Docker) |
| `NODE_ID` | Agent node identifier | `swe-planner` |
| `PORT` | Agent listen port | `8003` |
| `SWE_DEFAULT_RUNTIME` | Default runtime: `claude_code`, `open_code`, or `codex` | `claude_code` |
| `SWE_DEFAULT_MODEL` | Default model ID for every role | runtime-specific |

The image registers `MiniMax-M3` and `MiniMax-M2.7` under the direct OpenAI-compatible providers `minimax-global-openai` and `minimax-cn-openai`, and under the Anthropic-compatible OpenCode provider `minimax-anthropic`. Set `ANTHROPIC_BASE_URL` to either regional `/anthropic` URL shown above; the OpenCode adapter derives `/v1` internally. Use the regional OpenAI base URLs `https://api.minimax.io/v1` and `https://api.minimaxi.com/v1`; keep the external Anthropic base URL exactly as shown without appending `/v1`.

### Package Versions

Expand Down
5 changes: 2 additions & 3 deletions go/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ ENV PATH="/root/.opencode/bin:${PATH}"
# value inside the image so a fresh container has *some* value to interpolate;
# Railway / docker-compose overrides win because their env injects afterward.
ENV HARNESS_MODEL=openrouter/moonshotai/kimi-k2.6
RUN mkdir -p /root/.config/opencode && \
echo '{"$schema":"https://opencode.ai/config.json","model":"{env:HARNESS_MODEL}","small_model":"{env:HARNESS_MODEL}","provider":{"openrouter":{"options":{"apiKey":"{env:OPENROUTER_API_KEY}"}}}}' \
> /root/.config/opencode/opencode.json
RUN mkdir -p /root/.config/opencode
COPY opencode.json /root/.config/opencode/opencode.json

# Git identity — env vars take highest precedence and are inherited by all
# subprocesses (including the CLIs the harness spawns).
Expand Down
198 changes: 198 additions & 0 deletions opencode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
{
"$schema": "https://opencode.ai/config.json",
"model": "{env:HARNESS_MODEL}",
"small_model": "{env:HARNESS_MODEL}",
"provider": {
"openrouter": {
"options": {
"apiKey": "{env:OPENROUTER_API_KEY}"
}
},
"minimax-global-openai": {
"name": "MiniMax Global (OpenAI-compatible)",
"env": [
"MINIMAX_API_KEY"
],
"npm": "@ai-sdk/openai-compatible",
"options": {
"apiKey": "{env:MINIMAX_API_KEY}",
"baseURL": "https://api.minimax.io/v1"
},
"models": {
"MiniMax-M3": {
"id": "MiniMax-M3",
"name": "MiniMax-M3",
"attachment": true,
"reasoning": true,
"limit": {
"context": 1000000,
"output": 524288
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06
},
"modalities": {
"input": [
"text",
"image",
"video"
],
"output": [
"text"
]
}
},
"MiniMax-M2.7": {
"id": "MiniMax-M2.7",
"name": "MiniMax-M2.7",
"attachment": false,
"reasoning": true,
"limit": {
"context": 204800,
"output": 204800
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06,
"cache_write": 0.375
},
"modalities": {
"input": [
"text"
],
"output": [
"text"
]
}
}
}
},
"minimax-cn-openai": {
"name": "MiniMax China (OpenAI-compatible)",
"env": [
"MINIMAX_API_KEY"
],
"npm": "@ai-sdk/openai-compatible",
"options": {
"apiKey": "{env:MINIMAX_API_KEY}",
"baseURL": "https://api.minimaxi.com/v1"
},
"models": {
"MiniMax-M3": {
"id": "MiniMax-M3",
"name": "MiniMax-M3",
"attachment": true,
"reasoning": true,
"limit": {
"context": 1000000,
"output": 524288
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06
},
"modalities": {
"input": [
"text",
"image",
"video"
],
"output": [
"text"
]
}
},
"MiniMax-M2.7": {
"id": "MiniMax-M2.7",
"name": "MiniMax-M2.7",
"attachment": false,
"reasoning": true,
"limit": {
"context": 204800,
"output": 204800
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06,
"cache_write": 0.375
},
"modalities": {
"input": [
"text"
],
"output": [
"text"
]
}
}
}
},
"minimax-anthropic": {
"name": "MiniMax (Anthropic-compatible)",
"env": [
"MINIMAX_API_KEY"
],
"npm": "@ai-sdk/anthropic",
"options": {
"apiKey": "{env:MINIMAX_API_KEY}",
"baseURL": "{env:ANTHROPIC_BASE_URL}/v1"
},
"models": {
"MiniMax-M3": {
"id": "MiniMax-M3",
"name": "MiniMax-M3",
"attachment": true,
"reasoning": true,
"limit": {
"context": 1000000,
"output": 524288
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06
},
"modalities": {
"input": [
"text",
"image",
"video"
],
"output": [
"text"
]
}
},
"MiniMax-M2.7": {
"id": "MiniMax-M2.7",
"name": "MiniMax-M2.7",
"attachment": false,
"reasoning": true,
"limit": {
"context": 204800,
"output": 204800
},
"cost": {
"input": 0.3,
"output": 1.2,
"cache_read": 0.06,
"cache_write": 0.375
},
"modalities": {
"input": [
"text"
],
"output": [
"text"
]
}
}
}
}
}
}
Loading