Skip to content
Merged
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
9 changes: 7 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ PI_THINKING=
AGENT_OPENAI_BASE_URL=
AGENT_OPENAI_API_KEY=

# Claude Code agent only: official Anthropic API key. Custom gateways, OAuth,
# Bedrock, and Vertex are not supported by the shared launcher.
# Claude Code direct mode: official Anthropic API key. OpenRouter uses the
# separate Agent key below; other gateways, OAuth, Bedrock, and Vertex are
# unsupported.
AGENT_ANTHROPIC_API_KEY=

# OpenRouter Agent mode (--openrouter) for Codex or Claude Code. Separate from
# OPENROUTER_API_KEY used by task submissions and ANSWER_JUDGE_API_KEY.
AGENT_OPENROUTER_API_KEY=

# Optional Codex or Claude Code reasoning effort.
AGENT_REASONING_EFFORT=

Expand Down
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ For other runs, fill only the matching sections already present in `.env`:
- Pi + GLM-5.3-Flash: `AGENT_MODEL=zai/glm-5.3-flash` and `ZAI_API_KEY`.
- Codex: `AGENT_MODEL`, `AGENT_OPENAI_BASE_URL`, and `AGENT_OPENAI_API_KEY`.
- Claude Code: `AGENT_MODEL` and `AGENT_ANTHROPIC_API_KEY`; the launcher uses
only Anthropic's official API.
Anthropic's official API by default.
- OpenRouter Agent mode: `AGENT_OPENROUTER_API_KEY`, `--openrouter`, and a full
`provider/model` slug with Codex or Claude Code.
- Task 1-3: the three `ANSWER_JUDGE_*` values are also required.
- Optional submission APIs: use `TASK_1_1_OPENROUTER_API_KEY`,
`OPENROUTER_API_KEY`, or `JINA_API_KEY` only for the tasks identified by the
Expand Down Expand Up @@ -169,7 +171,7 @@ it.

#### Claude Code and the official Anthropic API

Claude Code 2.1.273 is preinstalled in every task image. Set an Anthropic model
Claude Code 2.1.283 is preinstalled in every task image. Set an Anthropic model
available to your API account and the dedicated coding-agent key:

```dotenv
Expand All @@ -182,9 +184,31 @@ bash scripts/run_task.sh --task task-1-1 --agent claude-code \
--reasoning-effort high --output jobs/task-1-1-claude
```

The shared launcher supports API-key authentication to `api.anthropic.com`;
custom gateways, subscription OAuth, Bedrock, Vertex, ACP, and custom Claude
settings are intentionally outside the initial support scope. The
#### Codex or Claude Code through OpenRouter

Add a dedicated OpenRouter Agent key to `.env`:

```dotenv
AGENT_OPENROUTER_API_KEY=YOUR_AGENT_OPENROUTER_KEY
```

Choose an Agent and pass its full OpenRouter model ID:

```bash
bash scripts/run_task.sh --task task-1-1 --agent codex --openrouter \
--model openai/gpt-6-astra --output jobs/task-1-1-codex-openrouter

bash scripts/run_task.sh --task task-1-1 --agent claude-code --openrouter \
--model anthropic/claude-opus-5.5 --output jobs/task-1-1-claude-openrouter
```

Add `--dry-run` to either command to preview it before launching. The launcher
sets the OpenRouter API addresses and keeps this key separate from the
submission `OPENROUTER_API_KEY` and verifier credentials. Keep the `VERIFIER_*`
settings from the main example.

Other custom gateways, subscription OAuth, Bedrock, Vertex, ACP, and custom
Claude settings remain outside the supported scope. The
[quick start guide](docs/quickstart.md) covers the default Codex path;
the [evaluation guide](docs/evaluation.md) covers the per-task credential and
hardware matrix plus GPU, network-policy, and custom-provider options.
Expand Down
32 changes: 28 additions & 4 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ VERIFIER_OPENAI_API_KEY=YOUR_DEEPSEEK_KEY
- Codex:设置 `AGENT_MODEL`、`AGENT_OPENAI_BASE_URL` 和
`AGENT_OPENAI_API_KEY`。
- Claude Code:设置 `AGENT_MODEL` 和 `AGENT_ANTHROPIC_API_KEY`;共享启动器
只使用 Anthropic 官方 API。
默认使用 Anthropic 官方 API。
- OpenRouter Agent 模式:设置 `AGENT_OPENROUTER_API_KEY`,并为 Codex 或
Claude Code 指定 `--openrouter` 和完整的 `provider/model` 模型 ID。
- Task 1-3:还必须填写三个 `ANSWER_JUDGE_*` 变量。
- 可选 submission API:只在 `.env.example` 注释所列任务确实使用时,填写
`TASK_1_1_OPENROUTER_API_KEY`、`OPENROUTER_API_KEY` 或 `JINA_API_KEY`。
Expand Down Expand Up @@ -158,7 +160,7 @@ bash scripts/run_task.sh --task task-1-1 --agent codex \

#### Claude Code 和 Anthropic 官方 API

所有任务镜像都预装 Claude Code 2.1.273。填写 API 账户可用的 Anthropic 模型
所有任务镜像都预装 Claude Code 2.1.283。填写 API 账户可用的 Anthropic 模型
和独立的编码智能体密钥:

```dotenv
Expand All @@ -171,8 +173,30 @@ bash scripts/run_task.sh --task task-1-1 --agent claude-code \
--reasoning-effort high --output jobs/task-1-1-claude
```

共享启动器只支持通过 API key 访问 `api.anthropic.com`;首版有意不支持自定义
gateway、订阅 OAuth、Bedrock、Vertex、ACP 和自定义 Claude settings。默认 Codex
#### 通过 OpenRouter 运行 Codex 或 Claude Code

在 `.env` 中填写独立的 OpenRouter Agent 密钥:

```dotenv
AGENT_OPENROUTER_API_KEY=YOUR_AGENT_OPENROUTER_KEY
```

选择 Agent,并传入完整的 OpenRouter 模型 ID:

```bash
bash scripts/run_task.sh --task task-1-1 --agent codex --openrouter \
--model openai/gpt-6-astra --output jobs/task-1-1-codex-openrouter

bash scripts/run_task.sh --task task-1-1 --agent claude-code --openrouter \
--model anthropic/claude-opus-5.5 --output jobs/task-1-1-claude-openrouter
```

可以先为命令加上 `--dry-run` 预览。启动器已配置 OpenRouter 的 API 地址;
这个 Agent 密钥与任务提交用的 `OPENROUTER_API_KEY` 和裁判密钥分开。
保留主示例中的 `VERIFIER_*` 配置。

其他自定义 gateway、订阅 OAuth、Bedrock、Vertex、ACP 和自定义 Claude settings
仍不受支持。默认 Codex
流程见[快速开始指南](docs/quickstart.md);各任务的凭证与硬件矩阵,以及 GPU、
网络权限和自定义模型服务配置见[评测指南](docs/evaluation.md)。

Expand Down
41 changes: 33 additions & 8 deletions docs/evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,35 @@ AGENT_CODEX_CONFIG=provider.local.toml
The equivalent CLI option is `--codex-config`; CLI paths are resolved from the
current directory.

### Codex or Claude Code through OpenRouter

Set a separate Agent key in `.env`:

```dotenv
AGENT_OPENROUTER_API_KEY=YOUR_AGENT_OPENROUTER_KEY
```

Use a full OpenRouter model slug and select the route explicitly:

```bash
bash scripts/run_task.sh --task task-1-1 --agent codex --openrouter \
--model openai/gpt-6-astra --dry-run
bash scripts/run_task.sh --task task-1-1 --agent claude-code --openrouter \
--model anthropic/claude-opus-5.5 --dry-run
```

Remove `--dry-run` to launch. This mode fixes Codex's Responses base URL to
`https://openrouter.ai/api/v1` and Claude Code's Anthropic base URL to
`https://openrouter.ai/api`. Claude Code accepts only `anthropic/` slugs here.
The launcher permits `openrouter.ai` in restricted Agent phases and keeps the
OpenRouter Agent key separate from `OPENROUTER_API_KEY` for submissions and
`ANSWER_JUDGE_API_KEY` for task-1-3. Verifier configuration is unchanged.
When using Codex, omit `--codex-config`; the launcher supplies the required
native provider configuration and ignores the direct mode's `AGENT_CODEX_CONFIG`.

### Claude Code with the official Anthropic API

Claude Code is pinned to version 2.1.273 and preinstalled in every task image.
Claude Code is pinned to version 2.1.283 and preinstalled in every task image.
Set a model available to your Anthropic API account and its dedicated
coding-agent key:

Expand All @@ -133,22 +159,21 @@ bash scripts/run_task.sh \
--dry-run
```

Claude Code 2.1.273 accepts `low`, `medium`, `high`, `xhigh`, and `max` effort.
Claude Code 2.1.283 accepts `low`, `medium`, `high`, `xhigh`, and `max` effort.
Use `AGENT_REASONING_EFFORT` as a local default or `--reasoning-effort` for an
explicit run. The launcher maps `AGENT_ANTHROPIC_API_KEY` to the agent-only
`ANTHROPIC_API_KEY`, permits only `api.anthropic.com` during restricted Agent
phases, and removes inherited Anthropic gateway, OAuth, and Bedrock selectors
before starting Harbor.

The shared launcher intentionally does not support custom Anthropic-compatible
gateways, Claude subscription OAuth, Bedrock, Vertex, ACP, or custom Claude
settings. These modes have different credential, executable-configuration, or
network requirements and must not be enabled by adding host environment
variables.
Other custom Anthropic-compatible gateways, Claude subscription OAuth, Bedrock,
Vertex, ACP, and custom Claude settings are not supported. They need different
credentials, executable configuration, or network permissions and must not be
enabled by adding host environment variables.

### Pi native providers

Pi is pinned to version 0.85.1 by the launcher. It currently accepts these
Pi is pinned to version 0.87.1 by the launcher. It currently accepts these
verified provider/model combinations:

| Model | Required variable |
Expand Down
11 changes: 6 additions & 5 deletions docs/network-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ these counters are not HTTP request counts.
## Current task matrix

`model host` below means exactly one coding-model hostname selected by the
launcher: the hostname in `AGENT_OPENAI_BASE_URL` for Codex,
launcher: the hostname in `AGENT_OPENAI_BASE_URL` for direct Codex,
`api.deepseek.com` for Pi + DeepSeek, `api.z.ai` for Pi + Z.AI, or the fixed
`api.anthropic.com` host for Claude Code. The launcher passes it through
`api.anthropic.com` host for direct Claude Code. With `--openrouter`, Codex and
Claude Code use `openrouter.ai`. The launcher passes the selected host through
Harbor's `--allow-agent-host`, which augments only the `agent.run()` phase.
Codex 0.147.0, Pi 0.85.1, and Claude Code 2.1.273 are preinstalled in every
Codex 0.157.1, Pi 0.87.1, and Claude Code 2.1.283 are preinstalled in every
agent image, so agent setup does not need package-registry or general internet
access.

Expand Down Expand Up @@ -144,7 +145,7 @@ invoking Harbor directly on a non-public task, add the matching hostname:
PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}" harbor run --path tasks/TASK_ID \
--env scripts.harbor_environments:PhaseScopedDocker \
--agent scripts.harbor_agents:PreinstalledCodex --model MODEL_ID \
--ak version=0.147.0 \
--ak version=0.157.1 \
--allow-agent-host MODEL_API_HOST
```

Expand All @@ -156,7 +157,7 @@ PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}" harbor run --path tasks/TASK_ID \
--env scripts.harbor_environments:PhaseScopedDocker \
--agent scripts.harbor_agents:PreinstalledClaudeCode \
--model ANTHROPIC_MODEL_ID \
--ak version=2.1.273 \
--ak version=2.1.283 \
--ae 'ANTHROPIC_API_KEY=${AGENT_ANTHROPIC_API_KEY}' \
--allow-agent-host api.anthropic.com
```
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ the run as successful.
## Next steps

- Read the [full evaluation guide](evaluation.md) before selecting another task
or agent. It documents Codex, Pi, and the pinned Claude Code 2.1.273 launcher,
or agent. It documents Codex, Pi, and the pinned Claude Code 2.1.283 launcher,
and its task matrix lists exactly which additional credentials and hardware
each task uses.
- Read the selected task's `README.md` and `instruction.md` for its resource
Expand Down
43 changes: 40 additions & 3 deletions scripts/harbor_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
from harbor.agents.installed.pi import Pi
from harbor.environments.base import BaseEnvironment
import json
import shlex
import tempfile
from pathlib import Path

from harbor.models.trajectories.trajectory import Trajectory
from scripts.pi_trajectory import convert_events


CODEX_VERSION = "0.147.0"
CLAUDE_CODE_VERSION = "2.1.273"
PI_VERSION = "0.85.1"
CODEX_VERSION = "0.157.1"
CLAUDE_CODE_VERSION = "2.1.283"
PI_VERSION = "0.87.1"


async def _require_version(
Expand Down Expand Up @@ -48,6 +49,27 @@ async def install(self, environment: BaseEnvironment) -> None:
)


class PreinstalledOpenRouterCodex(PreinstalledCodex):
"""Keep the full OpenRouter model slug in Harbor's Codex command."""

async def exec_as_agent(self, environment, command, **kwargs):
# Harbor 0.22.0 strips the provider prefix in Codex.run(). Replace
# only its model flag; fail if a future Harbor release changes it.
if "codex exec " in command:
flags, separator, instruction = command.partition("-- ")
bare_model = self.model_name.split("/")[-1]
old = f"--model {bare_model} --json "
if not separator or flags.count(old) != 1:
raise RuntimeError(
"Harbor's Codex command format changed; OpenRouter model may be truncated"
)
command = (
flags.replace(old, f"--model {shlex.quote(self.model_name)} --json ", 1)
+ separator + instruction
)
return await super().exec_as_agent(environment, command, **kwargs)


class PreinstalledClaudeCode(ClaudeCode):
"""Run the pinned Claude Code CLI without runtime package downloads."""

Expand All @@ -65,6 +87,21 @@ async def install(self, environment: BaseEnvironment) -> None:
)


class PreinstalledOpenRouterClaudeCode(PreinstalledClaudeCode):
"""Use OpenRouter's bearer token with Claude Code's Anthropic endpoint."""

def _resolve_auth_env(self):
env = super()._resolve_auth_env()
token = self._get_env("ANTHROPIC_AUTH_TOKEN")
if not token or env.get("ANTHROPIC_BASE_URL") != "https://openrouter.ai/api":
raise RuntimeError(
"OpenRouter Claude Code requires its bearer token and fixed base URL"
)
env["ANTHROPIC_API_KEY"] = ""
env["ANTHROPIC_AUTH_TOKEN"] = token
return env


class PreinstalledPi(Pi):
"""Run the pinned Pi CLI without runtime package downloads."""

Expand Down
10 changes: 10 additions & 0 deletions scripts/openrouter_codex.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
model_provider = "openrouter"

[model_providers.openrouter]
name = "OpenRouter"
base_url = "https://openrouter.ai/api/v1"
wire_api = "responses"

[model_providers.openrouter.auth]
command = "sh"
args = ["-c", "printf %s \"$OPENAI_API_KEY\""]
Loading
Loading