remove Vercel AI Gateway and Vercel Sandbox (#33067)

* remove Vercel AI Gateway provider and Vercel Sandbox terminal backend

Both Vercel-hosted integrations are removed end-to-end. Users on the AI
Gateway should switch to OpenRouter or one of the other aggregators
(Nous Portal, Kilo Code). Users on the Vercel Sandbox backend should
switch to Docker, Modal, Daytona, or SSH.

What's removed:
- `plugins/model-providers/ai-gateway/` provider plugin
- `hermes_cli/vercel_auth.py` Vercel-Sandbox auth helper
- `tools/environments/vercel_sandbox.py` terminal backend
- `ai-gateway` provider wiring across auth, doctor, setup, models,
  config, status, providers, main, web_server, model_normalize, dump
- `vercel_sandbox` backend wiring across terminal_tool, file_tools,
  code_execution_tool, file_operations, approval, skills_tool,
  environments/local, credential_files, lazy_deps, prompt_builder,
  cli, gateway/run
- `AI_GATEWAY_BASE_URL` constant, `_AI_GATEWAY_HEADERS` auxiliary-client
  header set, run_agent base-URL header/reasoning special-cases
- `[vercel]` pyproject extra and `vercel`/`vercel-workers` from uv.lock
- env vars: `AI_GATEWAY_API_KEY`, `AI_GATEWAY_BASE_URL`, `VERCEL_TOKEN`,
  `VERCEL_PROJECT_ID`, `VERCEL_TEAM_ID`, `VERCEL_OIDC_TOKEN`,
  `TERMINAL_VERCEL_RUNTIME`
- Tests: deletes test_ai_gateway_models.py and
  test_vercel_sandbox_environment.py; scrubs references across 23
  surviving test files (no entire tests deleted unless they were
  dedicated to AI Gateway / Sandbox)
- Docs: provider tables, env-var reference, setup guides, security
  notes, tool config, terminal-backend tables — English plus zh-Hans
  i18n parity
- `hermes-agent` skill: provider table entry and remote-backend list

What stays (intentional):
- `popular-web-designs/templates/vercel.md` — CSS design reference,
  unrelated to Vercel-the-AI-product
- `x-vercel-id` in `stream_diag.py` headers — generic Vercel CDN
  response header, useful diag signal on any Vercel-hosted endpoint
- `vercel-labs/agent-browser` URL in browser config — lightpanda
  browser project, different OSS effort
- `userStories.json` historical contributor entry mentioning Vercel
  Sandbox — archive, not active docs

Validation:
- 1153 tests in the 22 targeted files pass (`scripts/run_tests.sh`)
- Full repo `py_compile` clean
- Live import of every touched module + invariant check (no
  `ai-gateway` in `PROVIDER_REGISTRY`, no `_AI_GATEWAY_HEADERS`, no
  `vercel_sandbox` in `_REMOTE_TERMINAL_BACKENDS`)

* test: convert profile-count check from change-detector to invariant

The hardcoded "== 34" assertion broke when ai-gateway was removed.
Per AGENTS.md change-detector-test guidance, assert the relationship
(registry count >= number of plugin dirs) instead of a literal count.
Counts shift when providers are added/removed; that's expected.
This commit is contained in:
Teknium
2026-05-27 00:43:32 -07:00
committed by GitHub
parent cb38ce28cb
commit febc4cfec0
95 changed files with 111 additions and 3088 deletions
@@ -83,11 +83,11 @@ delegation:
## 终端后端配置
Hermes 支持种终端后端。每种后端决定 agent 的 shell 命令实际在哪里执行 —— 本地机器、Docker 容器、通过 SSH 的远程服务器、Modal 云沙箱(直接或通过 Nous 托管的 gateway)、Daytona 工作区、Vercel Sandbox,或 Singularity/Apptainer 容器。
Hermes 支持种终端后端。每种后端决定 agent 的 shell 命令实际在哪里执行 —— 本地机器、Docker 容器、通过 SSH 的远程服务器、Modal 云沙箱(直接或通过 Nous 托管的 gateway)、Daytona 工作区,或 Singularity/Apptainer 容器。
```yaml
terminal:
backend: local # local | docker | ssh | modal | daytona | vercel_sandbox | singularity
backend: local # local | docker | ssh | modal | daytona | singularity
cwd: "." # Gateway/cron 工作目录(CLI 始终使用启动目录)
timeout: 180 # 每条命令的超时时间(秒)
env_passthrough: [] # 转发到沙箱执行的环境变量名(terminal + execute_code
@@ -96,7 +96,7 @@ terminal:
daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Daytona 后端的容器镜像
```
对于 ModalDaytona 和 Vercel Sandbox 等云沙箱,`container_persistent: true` 表示 Hermes 将尝试在沙箱重建后保留文件系统状态。这并不保证相同的活跃沙箱、PID 空间或后台进程之后仍在运行。
对于 ModalDaytona 等云沙箱,`container_persistent: true` 表示 Hermes 将尝试在沙箱重建后保留文件系统状态。这并不保证相同的活跃沙箱、PID 空间或后台进程之后仍在运行。
### 后端概览
@@ -107,7 +107,6 @@ terminal:
| **ssh** | 通过 SSH 的远程服务器 | 网络边界 | 远程开发、强大硬件 |
| **modal** | Modal 云沙箱 | 完全(云 VM) | 临时云计算、评估 |
| **daytona** | Daytona 工作区 | 完全(云容器) | 托管云开发环境 |
| **vercel_sandbox** | Vercel Sandbox | 完全(云 microVM) | 带快照文件系统持久化的云执行 |
| **singularity** | Singularity/Apptainer 容器 | 命名空间(--containall | HPC 集群、共享机器 |
### Local 后端
@@ -232,49 +231,6 @@ terminal:
**磁盘限制:** Daytona 强制执行 10 GiB 最大值。超过此值的请求将被截断并发出警告。
### Vercel Sandbox 后端
在 [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox) 云 microVM 中运行命令。Hermes 使用普通的终端和文件工具接口;没有 Vercel 特定的面向模型的工具。
```yaml
terminal:
backend: vercel_sandbox
vercel_runtime: node24 # node24 | node22 | python3.13
cwd: /vercel/sandbox # 默认工作区根目录
container_persistent: true # 快照/恢复文件系统
container_disk: 51200 # 仅共享默认值;不支持自定义磁盘
```
**必需安装:** 安装可选 SDK 扩展:
```bash
pip install 'hermes-agent[vercel]'
```
**必需认证:** 使用 `VERCEL_TOKEN``VERCEL_PROJECT_ID``VERCEL_TEAM_ID` 三者全部配置访问令牌认证。这是在 Render、Railway、Docker 及类似宿主上部署和正常长期运行 Hermes 进程的受支持设置。
对于一次性本地开发,Hermes 也接受短期 Vercel OIDC token
```bash
VERCEL_OIDC_TOKEN="$(vc project token <project-name>)" hermes chat
```
在已链接的 Vercel 项目目录中,可以省略项目名称:
```bash
VERCEL_OIDC_TOKEN="$(vc project token)" hermes chat
```
OIDC token 是短期的,不应作为文档化的部署路径使用。
**运行时:** `terminal.vercel_runtime` 支持 `node24``node22``python3.13`。未设置时,Hermes 默认使用 `node24`
**持久化:**`container_persistent: true` 时,Hermes 在清理期间对沙箱文件系统进行快照,并从该快照为同一任务恢复后续沙箱。快照内容可以包括复制到沙箱中的 Hermes 同步凭据、技能和缓存文件。这仅保留文件系统状态;不保留活跃沙箱身份、PID 空间、shell 状态或正在运行的后台进程。
**后台命令:** `terminal(background=true)` 使用 Hermes 的通用非本地后台进程流程。您可以在沙箱存活期间通过普通进程工具生成、轮询、等待、查看日志和终止进程。Hermes 不提供清理或重启后的原生 Vercel 分离进程恢复。
**磁盘大小:** Vercel Sandbox 目前不支持 Hermes 的 `container_disk` 资源旋钮。将 `container_disk` 保持未设置或使用共享默认值 `51200`;非默认值会导致诊断和后端创建失败,而不是被静默忽略。
### Singularity/Apptainer 后端
在 [Singularity/Apptainer](https://apptainer.org) 容器中运行命令。专为 Docker 不可用的 HPC 集群和共享机器设计。
@@ -818,7 +774,7 @@ Hermes 中的每个模型槽位 —— 辅助任务、压缩、回退 —— 使
当设置 `base_url` 时,Hermes 忽略 provider 并直接调用该端点(使用 `api_key``OPENAI_API_KEY` 进行认证)。当仅设置 `provider` 时,Hermes 使用该 provider 的内置认证和基础 URL。
辅助任务的可用 providers`auto``main`,以及[provider 注册表](/reference/environment-variables)中的任何 provider —— `openrouter``nous``openai-codex``copilot``copilot-acp``anthropic``gemini``google-gemini-cli``qwen-oauth``zai``kimi-coding``kimi-coding-cn``minimax``minimax-cn``minimax-oauth``deepseek``nvidia``xai``xai-oauth``ollama-cloud``alibaba``bedrock``huggingface``arcee``xiaomi``kilocode``opencode-zen``opencode-go``ai-gateway``azure-foundry` —— 或您 `custom_providers` 列表中任何命名的自定义 provider(例如 `provider: "beans"`)。
辅助任务的可用 providers`auto``main`,以及[provider 注册表](/reference/environment-variables)中的任何 provider —— `openrouter``nous``openai-codex``copilot``copilot-acp``anthropic``gemini``google-gemini-cli``qwen-oauth``zai``kimi-coding``kimi-coding-cn``minimax``minimax-cn``minimax-oauth``deepseek``nvidia``xai``xai-oauth``ollama-cloud``alibaba``bedrock``huggingface``arcee``xiaomi``kilocode``opencode-zen``opencode-go``azure-foundry` —— 或您 `custom_providers` 列表中任何命名的自定义 provider(例如 `provider: "beans"`)。
:::tip MiniMax OAuth
`minimax-oauth` 通过浏览器 OAuth 登录(无需 API 密钥)。运行 `hermes model` 并选择 **MiniMax (OAuth)** 进行认证。辅助任务自动使用 `MiniMax-M2.7-highspeed`。参阅 [MiniMax OAuth 指南](../guides/minimax-oauth.md)。
@@ -47,7 +47,6 @@ fallback_model:
| 提供商 | 值 | 要求 |
|----------|-------|-------------|
| AI Gateway | `ai-gateway` | `AI_GATEWAY_API_KEY` |
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
| Nous Portal | `nous` | `hermes setup --portal`(全新安装)或 `hermes auth add nous`OAuth |
| OpenAI Codex | `openai-codex` | `hermes model`ChatGPT OAuth |
@@ -65,14 +65,13 @@ hermes tools
| `singularity` | HPC 容器 | 集群计算、无 root 权限 |
| `modal` | 云端执行 | 无服务器、弹性扩展 |
| `daytona` | 云端沙箱工作区 | 持久化远程开发环境 |
| `vercel_sandbox` | Vercel Sandbox 云微虚拟机 | 带快照文件系统持久化的云端执行 |
### 配置
```yaml
# 在 ~/.hermes/config.yaml 中
terminal:
backend: local # 或:docker, ssh, singularity, modal, daytona, vercel_sandbox
backend: local # 或:docker, ssh, singularity, modal, daytona
cwd: "." # 工作目录
timeout: 180 # 命令超时时间(秒)
```
@@ -123,41 +122,13 @@ modal setup
hermes config set terminal.backend modal
```
### Vercel Sandbox
```bash
pip install 'hermes-agent[vercel]'
hermes config set terminal.backend vercel_sandbox
hermes config set terminal.vercel_runtime node24
```
需同时配置 `VERCEL_TOKEN``VERCEL_PROJECT_ID``VERCEL_TEAM_ID` 三个凭据。此访问令牌配置方式是在 Render、Railway、Docker 及类似平台上进行部署和正常长期运行 Hermes 进程的推荐路径。支持的运行时为 `node24``node22``python3.13`Hermes 默认使用 `/vercel/sandbox` 作为远程工作区根目录。
对于本地一次性开发,Hermes 也接受短期 Vercel OIDC token
```bash
VERCEL_OIDC_TOKEN="$(vc project token <project-name>)" hermes chat
```
在已关联的 Vercel 项目目录中:
```bash
VERCEL_OIDC_TOKEN="$(vc project token)" hermes chat
```
启用 `container_persistent: true` 后,Hermes 使用 Vercel 快照在同一任务的沙箱重建时保留文件系统状态,其中可包含沙箱内 Hermes 同步的凭据、技能和缓存文件。快照不保留活跃进程、PID 空间或相同的活跃沙箱标识。
后台终端命令使用 Hermes 通用的非本地进程流程:在沙箱存活期间,spawn、poll、wait、log 和 kill 均通过标准 process 工具运行,但 Hermes 不提供清理或重启后的原生 Vercel 后台进程恢复能力。
`container_disk` 保持未设置或使用共享默认值 `51200`Vercel Sandbox 不支持自定义磁盘大小,设置后将导致诊断/后端创建失败。
### 容器资源
为所有容器后端配置 CPU、内存、磁盘和持久化:
```yaml
terminal:
backend: docker # 或 singularity, modal, daytona, vercel_sandbox
backend: docker # 或 singularity, modal, daytona
container_cpu: 1 # CPU 核心数(默认:1
container_memory: 5120 # 内存(MB,默认:5GB
container_disk: 51200 # 磁盘(MB,默认:50GB
@@ -144,7 +144,7 @@ approvals:
| `gateway run` 配合 `&`/`disown`/`nohup`/`setsid` | 防止在服务管理器外启动 gateway |
:::info
**容器绕过**:在 `docker``singularity``modal``daytona``vercel_sandbox` 后端运行时,危险命令检查会被**跳过**,因为容器本身就是安全边界。容器内的破坏性命令不会危害宿主机。
**容器绕过**:在 `docker``singularity``modal``daytona` 后端运行时,危险命令检查会被**跳过**,因为容器本身就是安全边界。容器内的破坏性命令不会危害宿主机。
:::
### 审批流程(CLI
@@ -340,7 +340,7 @@ terminal:
- **临时模式**`container_persistent: false`):工作区使用 tmpfs——清理后所有内容丢失
:::tip
对于生产 gateway 部署,使用 `docker``modal``daytona``vercel_sandbox` 后端,将 Agent 命令与宿主机系统隔离。这样可以完全消除危险命令审批的需要。
对于生产 gateway 部署,使用 `docker``modal``daytona` 后端,将 Agent 命令与宿主机系统隔离。这样可以完全消除危险命令审批的需要。
:::
:::warning
@@ -357,7 +357,6 @@ terminal:
| **singularity** | 容器 | ❌ 跳过 | HPC 环境 |
| **modal** | 云沙箱 | ❌ 跳过 | 可扩展的云隔离 |
| **daytona** | 云沙箱 | ❌ 跳过 | 持久化云工作区 |
| **vercel_sandbox** | 云微虚拟机 | ❌ 跳过 | 带快照持久化的云执行 |
## 环境变量透传 {#environment-variable-passthrough}
@@ -401,7 +401,6 @@ Profiles 使用 `~/.hermes/profiles/<name>/`,布局相同。
| Alibaba / DashScope | API key | `DASHSCOPE_API_KEY` |
| Xiaomi MiMo | API key | `XIAOMI_API_KEY` |
| Kilo Code | API key | `KILOCODE_API_KEY` |
| AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` |
| OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` |
| OpenCode Go | API key | `OPENCODE_GO_API_KEY` |
| Qwen OAuth | OAuth | `hermes auth add qwen-oauth` |
@@ -922,7 +921,7 @@ monkeypatch.setattr(platform, "release", lambda: "6.8.0-generic")
关于宿主 OS、用户 home、cwd、终端后端和 shellWindows 上的 bash vs PowerShell)的事实性指导从 `agent/prompt_builder.py::build_environment_hints()` 输出。WSL 提示和每个后端的探测逻辑也在此处。约定:
- **本地终端后端** → 输出宿主信息(OS、`$HOME`、cwd+ Windows 特有说明(hostname ≠ username`terminal` 使用 bash 而非 PowerShell)。
- **远程终端后端**`_REMOTE_TERMINAL_BACKENDS` 中的任何内容:`docker, singularity, modal, daytona, ssh, vercel_sandbox, managed_modal`)→ **完全抑制**宿主信息,仅描述后端。通过 `tools.environments.get_environment(...).execute(...)` 在后端内运行实时 `uname`/`whoami`/`pwd` 探测,每进程缓存在 `_BACKEND_PROBE_CACHE` 中,探测超时时使用静态回退。
- **远程终端后端**`_REMOTE_TERMINAL_BACKENDS` 中的任何内容:`docker, singularity, modal, daytona, ssh, managed_modal`)→ **完全抑制**宿主信息,仅描述后端。通过 `tools.environments.get_environment(...).execute(...)` 在后端内运行实时 `uname`/`whoami`/`pwd` 探测,每进程缓存在 `_BACKEND_PROBE_CACHE` 中,探测超时时使用静态回退。
- **prompt 编写的关键事实:** 当 `TERMINAL_ENV != "local"` 时,*每个*文件工具(`read_file``write_file``patch``search_files`)都在后端容器内运行,而非宿主上。在这种情况下,系统 prompt 绝不能描述宿主——agent 无法访问它。
完整设计说明、确切输出字符串和测试陷阱:`references/prompt-builder-environment-hints.md`