# Pipeline v2 Model Proxy Architecture

Pipeline v2 procedure runner 通过 model proxy 链路将容器内 OpenCode 的模型请求路由到外部 API 提供商。本文档记录 proxy 链路的稳定架构、各 model 组件的差异和 D601 宿主服务部署约束。

## Proxy Chain 总体架构

```text
OpenCode (container)
  ↓ HTTP (127.0.0.1:17655)
In-container model proxy (opencodeContainerHarness)
  ↓ HTTP/HTTPS
Upstream origin (per model config)
  ↓ (if host proxy)
External API provider (HTTPS)
```

每个 model 组件在 `config.json` 的 `proxy` 字段声明 in-container proxy 的监听端口和上游地址。OpenCode 的 provider config 中 `baseUrl` 固定指向 `http://127.0.0.1:{proxy.port}/{path}`，由 harness 在容器启动时写入。

In-container proxy 的职责：
- 注入 auth token（从容器环境变量读取，按 `ANTHROPIC_AUTH_TOKEN` → `ANTHROPIC_API_KEY` → `OPENAI_API_KEY` 优先级查找）
- 429 rate limit 自动重试与 quota pause 计时（暂停时间不计入 node active timeout）
- 请求/响应透传（streaming 兼容）

## Model 组件 Proxy 配置对比

| Model | proxy.upstreamOrigin | 宿主服务 | Auth env |
|-------|---------------------|----------|----------|
| `minimax-m27` | `https://api.minimaxi.com` | 无（容器直连） | `ANTHROPIC_AUTH_TOKEN` |
| `gpt-5.5` | `http://host.docker.internal:17680` | `hyueapi-proxy.service` | `OPENAI_API_KEY` |

### minimax-m27（直连模式）

容器内 proxy 直接 HTTPS 连接 `api.minimaxi.com`，无需宿主中间层。适用于上游 API 不需要 Host header 覆盖或 TLS SNI 特殊处理的场景。

### gpt-5.5（宿主 proxy 模式）

容器内 proxy 通过 Docker `host.docker.internal` 连接宿主 port 17680 的 HTTP reverse proxy，由宿主 proxy 完成 HTTP→HTTPS 升级和 `Host: hyueapi.com` header 注入。

两跳设计原因：hyueapi.com 使用 Cloudflare，要求 TLS SNI 与 Host header 匹配；容器内 Node.js HTTP proxy 只做 HTTP 转发，TLS 终止由宿主 proxy 完成，避免容器内处理 Cloudflare 证书验证和 SNI 问题。

## D601 宿主 hyueapi-proxy 服务

部署路径：`~/pipeline/services/hyueapi-proxy/proxy.mjs`

systemd user service：`~/.config/systemd/user/hyueapi-proxy.service`

```bash
# 状态检查
systemctl --user status hyueapi-proxy.service

# 重启
systemctl --user restart hyueapi-proxy.service

# 验证（需要 auth）
KEY=$(cat ~/pipeline/.state/secrets/gpt-5.5/OPENAI_API_KEY)
curl -H "Authorization: Bearer $KEY" http://127.0.0.1:17680/v1/models
```

服务行为：
- 监听 `0.0.0.0:17680`（容器通过 `host.docker.internal` 访问）
- 上游 `hyueapi.com:443`（HTTPS）
- 覆盖 `Host` header 为 `hyueapi.com`
- 透传所有其他 header（包括 `Authorization`）
- 无认证、无缓存、无日志（生产态）

## Harness Token 注入规则

`scripts/src/opencodeContainerHarness.ts` 中 in-container proxy 的 token 查找顺序：

```
ANTHROPIC_AUTH_TOKEN → ANTHROPIC_API_KEY → OPENAI_API_KEY
```

model 组件的 `auth.envNames` 声明注入到容器的环境变量名。对于 OpenAI-compatible 提供商（如 gpt-5.5），`envNames` 必须包含 `OPENAI_API_KEY`，harness 才能在 proxy 层自动注入 Bearer token。

## Smoke Test 验证

每个 model 组件应配套一个 smoke-test pipeline 用于验证端到端连通性：

```text
components/pipeline/gpt-5.5-smoke-test/config.json
components/procedure/gpt-5.5-smoke-connectivity/config.json
```

Smoke test 验证链路：
1. 容器启动，harness 写入 OpenCode provider config 并启动 in-container proxy
2. OpenCode server 启动，harness 创建 session 并发送 prompt
3. 模型通过 proxy chain 完成请求（`POST /v1/responses`）
4. 模型执行任务并通过 OA skill 提交 `benchmark-repair-result-v1`
5. Harness 验证 OA submission 存在且 container exit code = 0

运行方式：
```bash
cd ~/pipeline
npx tsx scripts/pipeline-cli.ts procedure start \
  --pipeline gpt-5.5-smoke-test \
  --node smoke \
  --task "Connectivity test: ..."
```

## 新增 Model 组件检查清单

1. 创建 `components/model/{id}/config.json`，声明 `opencode`、`auth`、`proxy` 和 `runtimeEnv`
2. 创建 `.state/secrets/{id}/{ENV_NAME}` 存放 API key
3. 如果上游需要 Host header 覆盖或 TLS 特殊处理，部署宿主 proxy 服务并将 `proxy.upstreamOrigin` 指向 `http://host.docker.internal:{port}`
4. 确认 `auth.envNames` 中的变量名在 harness token 查找链中（当前支持 `ANTHROPIC_AUTH_TOKEN`、`ANTHROPIC_API_KEY`、`OPENAI_API_KEY`）
5. 创建 smoke-test pipeline 和 procedure 组件
6. 运行 smoke test 验证端到端连通性
7. 提交到 pipeline 仓库
