https://你的域名
登录成功后通过 Set-Cookie 写入 session_id(HttpOnly、Secure、SameSite=Lax,有效期 7 天)。后续所有 /admin/* 请求需携带该 Cookie。
| 端点 | 方法 | 说明 |
|---|---|---|
/admin/login |
GET | 登录页面 |
/admin/login |
POST | 登录提交 |
/admin/logout |
GET | 退出登录 |
提交 JSON 进行登录校验(用户名明文比对,密码 SHA-256 哈希比对)。
请求体:
{
"username": "admin",
"password": "your_password"
}成功响应 (200):
{
"success": true,
"message": "登录成功"
}失败响应:
| 状态码 | 场景 | 响应 |
|---|---|---|
| 400 | 用户名/密码为空 | { "success": false, "message": "请输入用户名和密码" } |
| 401 | 用户名或密码错误 | { "success": false, "message": "用户名或密码错误" } |
| 500 | 未配置管理员账号 | { "success": false, "message": "未配置管理员账号,请在 Cloudflare 环境变量中设置 ADMIN_USERNAME 和 ADMIN_PASSWORD" } |
删除当前 Session 并清除 Cookie,重定向到首页 (/)。
所有 /v1/* 请求需在 Header 中携带转发 API Key(即管理后台生成的 sk_cf_*):
Authorization: Bearer sk_cf_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
失败响应 (401):
{
"error": { "message": "缺少或无效的 Authorization 头,格式: Bearer sk_cf_*", "type": "authentication_error" }
}或
{
"error": { "message": "API Key 无效或已禁用", "type": "authentication_error" }
}首页,返回站点信息与所有已启用提供商/模型列表(无需认证)。
返回所有已启用的模型列表(提供商与模型均需处于启用状态)。
响应:
{
"object": "list",
"data": [
{
"id": "opencode/deepseek-v4-flash-free",
"provider": "opencode",
"provider_name": "OpenCode",
"object": "model",
"created": 1712345678,
"owned_by": "opencode"
}
]
}转发 OpenAI 兼容的聊天补全请求。
请求体:
{
"model": "opencode/deepseek-v4-flash-free",
"messages": [{"role": "user", "content": "Hello!"}]
}模型格式: 提供商ID/模型ID
响应: 透传 AI 提供商的原始响应(含流式响应)。
转发 Anthropic 兼容的 Messages 请求。需将模型指定为 anthropic/<模型ID>。
请求体:
{
"model": "anthropic/claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 1024
}响应: 透传 Anthropic 的原始响应。
其他 /v1/* 子路径请求会原样透传到对应提供商。转发逻辑:
- 解析
model字段中的提供商ID/模型ID,定位提供商与模型配置 - 校验提供商/模型是否启用、是否配置了可用 API Key
- 将请求体中的
model改写为纯模型ID,路径去除/v1/前缀拼接到提供商baseUrl - Key 排序与健康检查:
- 读取该提供商下每个 Key 的历史健康状态(基于 KV 持久化)
- 健康 Key(无失败记录):Fisher-Yates 洗牌后优先使用
- 不健康 Key(有失败记录,< 5 次):追加到队列末尾
- 降权 Key(连续失败 >= 5 次):进入冷却排除,1 小时后自动恢复试用
- 试用 Key(冷却到期):追加到不健康 Key 之后,限试一次
- 仅有 1 个 Key 时跳过所有健康检查
- 按排序后的顺序依次尝试;遇
401/403/5xx或网络错误时标记该 Key 失败(failures++、demotedAt刷新)并切换下一个,成功时重置该 Key 的健康状态;遇429时不记录失败,切换下一个key
Key 健康状态存储在 KV 中(key:health:{providerId}),每次请求后更新,仅保留有失败记录的 Key。
Anthropic 协议的提供商请求会使用
x-api-key+anthropic-version: 2023-06-01头;OpenAI 协议使用Authorization: Bearer <key>头。请求超时为 60 秒。
OpenCode 是全新部署唯一的默认提供商,默认启用以下模型:
deepseek-v4-flash-freemimo-v2.5-freenemotron-3-ultra-freehy3-free
默认官方地址为 https://opencode.ai/zen/v1,上游 API Key 可以留空:
- 配置了启用的 Key 时,先使用后台配置的 OpenCode 地址和用户 Key。
- 官方请求未成功后,从随机起点依次尝试三个固定公共镜像。
- 未配置 Key 时直接进入公共镜像链路。
- 公共镜像使用内置
Authorization: Bearer public,不会写入 KV 或显示在管理页。 - 镜像遇到网络错误、超时或任意非成功 HTTP 状态时继续下一镜像;每个镜像最多尝试一次。
- 一旦收到成功响应便直接透传,包括 SSE 流式响应;流中途失败不会重新请求。
- 后台检测到的 OpenCode 模型列表仅显示
big-pickle和以-free结尾的模型 ID。
管理后台 OpenCode 特殊处理:
- 创建:ID 输入
opencode时自动填充官方 API 地址https://opencode.ai/zen/v1,模型字段留空,API Key 可选 - 测试:未填写 API Key 时自动走镜像地址获取可用模型列表;若镜像未配置则提示"请先填写 API Key 或配置 OPENCODE_MIRRORS_URL 环境变量"
- 编辑:提供"获取模型"按钮,一键从镜像或官方获取可用模型列表并添加到表单
类型:string(多行文本,每行一个 URL)
控制 OpenCode 镜像降级时使用的地址列表。默认值由部署脚本写入三个镜像地址:
https://opencode.ai.cmliussss.net/zen/v1https://opencode.fastly.cmliussss.net/zen/v1https://opencode.gcore.cmliussss.net/zen/v1
用户可通过 GitHub Actions Variables 设置 OPENCODE_MIRRORS_URL,内容追加到默认地址之后,全局去重(保留首次出现顺序)。设置方式:
- GitHub 仓库 → Settings → Secrets and variables → Actions → Variables → 新增
OPENCODE_MIRRORS_URL - 支持换行或逗号分隔,每行/每段一个 URL
若部署时未设置或设为空字符串,则 mirrorUrls = [],官方地址失败后不做镜像降级。
已有 KV 中的 Provider 不会被删除或覆盖;缺少 opencode 时只追加默认配置。其他 Provider 仍使用原有单地址和 Key 健康调度逻辑。
所有 /admin/api/* 端点需先登录并携带 Session Cookie,未登录返回 401:
{ "success": false, "message": "未登录" }Session 过期返回 401:
{ "success": false, "message": "Session 已过期" }获取系统状态总览。
响应:
{
"success": true,
"data": {
"providersCount": 4,
"enabledProvidersCount": 4,
"modelsCount": 12,
"enabledModelsCount": 12,
"proxyKeysCount": 2,
"adminConfigured": true,
"baseUrl": "https://your-domain.com"
}
}| 字段 | 说明 |
|---|---|
providersCount |
提供商总数 |
enabledProvidersCount |
已启用提供商数 |
modelsCount |
模型总数 |
enabledModelsCount |
已启用模型数 |
proxyKeysCount |
已启用的转发 Key 数 |
adminConfigured |
是否已配置 ADMIN_USERNAME / ADMIN_PASSWORD |
baseUrl |
当前部署的根域名 |
获取所有提供商列表(含完整 API Key)。
响应:
{
"success": true,
"data": [
{
"id": "deepseek",
"name": "DeepSeek",
"baseUrl": "https://api.deepseek.com",
"apiType": "openai",
"apiKeys": [
{ "key": "sk-xxx1", "enabled": true },
{ "key": "sk-xxx2", "enabled": false }
],
"models": [
{ "id": "deepseek-chat", "enabled": true },
{ "id": "deepseek-reasoner", "enabled": false }
],
"enabled": true,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
]
}添加新提供商。
请求体:
{
"id": "my-provider",
"name": "我的提供商",
"baseUrl": "https://api.example.com",
"apiType": "openai",
"apiKeys": ["sk-xxx"],
"models": ["model-1", "model-2"],
"enabled": true
}| 字段 | 必填 | 说明 |
|---|---|---|
id |
✅ | 提供商唯一标识,需全局唯一。当 id 为 opencode 且未传 baseUrl 时自动填充 https://opencode.ai/zen/v1 |
name |
✅ | 显示名称 |
baseUrl |
✅ ¹ | 提供商 API 基础地址,尾部 / 会被自动去除 |
apiType |
❌ | openai(默认)或 anthropic |
apiKeys |
❌ | 字符串数组或 {key, enabled} 对象数组。opencode 可留空(走镜像) |
models |
❌ | 字符串数组或 {id, enabled} 对象数组 |
enabled |
❌ | 默认 true |
¹ 当
id为opencode时baseUrl可选,后台自动填充,不传不会触发必填校验错误。
成功响应 (201): 返回新建的 Provider 对象。
冲突响应 (409): 提供商 id "my-provider" 已存在。
更新提供商配置。id、baseUrl、apiType 等字段均可更新,updatedAt 自动刷新。
请求体(所有字段可选):
{
"name": "新名称",
"baseUrl": "https://new-api.example.com",
"apiType": "anthropic",
"apiKeys": [{"key": "sk-new-key", "enabled": true}],
"models": [{"id": "new-model", "enabled": true}],
"enabled": false
}
apiKeys/models传数组时为整体替换,支持字符串数组或{key/id, enabled}对象数组。
成功响应: 返回更新后的 Provider 对象。
未找到 (404): 提供商不存在。
删除提供商。
成功响应:
{ "success": true, "message": "提供商已删除" }测试指定提供商下某个模型的连接是否可用。发送最小请求(max_tokens: 1,超时 15 秒)。
请求体:
{
"modelId": "deepseek-chat"
}响应:
{
"success": true,
"data": {
"success": true,
"message": "连接成功",
"statusCode": 200
}
}
data.success表示实际连接是否成功;外层success固定为true表示测试流程本身执行完成。
测试指定 API Key 的连接是否可用(用于"添加新提供商"表单,无需提供商已保存)。通过服务端代理请求上游 /models 端点,避免浏览器跨域限制。
请求体:
{
"url": "https://api.deepseek.com",
"apiKey": "sk-xxx",
"apiType": "openai",
"providerId": "opencode"
}| 字段 | 必填 | 说明 |
|---|---|---|
url |
✅ | API 基础地址,尾部 / 会被自动去除 |
apiKey |
✅ (opencode 可选) | 待测试的 API Key。opencode 可留空,将走镜像地址获取模型 |
apiType |
❌ | openai(默认)或 anthropic |
providerId |
❌ | 提供商 ID。当为 opencode 时走专用逻辑;为空则走标准测试 |
opencode 特殊行为:
apiKey为空时,自动使用OPENCODE_MIRRORS_URL配置的镜像地址(Bearer public)获取模型- 若镜像未配置(
OPENCODE_MIRRORS_URL为空),返回明确错误提示:"请先填写 API Key 或配置 OPENCODE_MIRRORS_URL 环境变量" - 返回的模型列表自动过滤,仅保留
-free结尾和big-pickle模型
成功响应:
{
"success": true,
"data": {
"success": true,
"statusCode": 200,
"data": { "object": "list", "data": [...] }
}
}连接成功时
data.data包含上游返回的模型列表;连接失败时data.success为false,message包含错误描述,statusCode为0(网络错误)或具体 HTTP 状态码。
测试指定模型的连接是否可用(用于"添加新提供商"表单)。通过服务端代理请求上游 /chat/completions 或 /messages 端点,避免浏览器跨域限制。
请求体:
{
"url": "https://api.deepseek.com",
"apiKey": "sk-xxx",
"apiType": "openai",
"model": "deepseek-chat"
}| 字段 | 必填 | 说明 |
|---|---|---|
url |
✅ | API 基础地址 |
apiKey |
✅ | 待测试的 API Key |
apiType |
❌ | 决定使用 /chat/completions(openai)或 /messages(anthropic) |
model |
✅ | 模型 ID |
成功响应:
{
"success": true,
"data": {
"success": true,
"statusCode": 200
}
}获取所有转发 API Key 列表。返回的 key 字段会做脱敏处理(仅显示前 8 位 + **** + 后 4 位)。
响应:
{
"success": true,
"data": [
{
"id": "uuid",
"key": "sk_cf_xxxxxx****xxxx",
"name": "测试 Key",
"enabled": true,
"createdAt": "2024-01-01T00:00:00.000Z",
"expiresAt": null
}
]
}生成新的转发 API Key。Key 格式为 sk_cf_ + 32 位随机 hex,仅在此响应中返回完整明文,之后不再可见。
请求体(全部可选):
{
"name": "我的Key名称",
"expiresIn": "90d"
}expiresIn 可选值:
| 值 | 有效期 |
|---|---|
30d |
30 天 |
90d |
90 天 |
180d |
180 天 |
1y |
1 年(365 天) |
forever |
永久(默认) |
成功响应 (201):
{
"success": true,
"data": {
"id": "uuid",
"key": "sk_cf_abcdef0123456789abcdef0123456789",
"name": "我的Key名称",
"enabled": true,
"createdAt": "2024-01-01T00:00:00.000Z",
"expiresAt": "2024-04-01T00:00:00.000Z"
},
"message": "请立即保存此 Key,关闭后将不再显示"
}更新转发 Key 的启用状态。
请求体:
{ "enabled": false }成功响应: 返回更新后的 ProxyKey 对象(key 仍为完整值)。
未找到 (404): 转发 Key 不存在。
删除转发 API Key。
成功响应:
{ "success": true, "message": "转发 Key 已删除" }所有 API 错误返回以下格式:
{
"error": {
"message": "错误描述",
"type": "error_type"
}
}部分错误(如所有 Key 耗尽)会附带 detail 字段:
{
"error": {
"message": "所有 API Key 已用完,最后一次错误: HTTP 429",
"type": "key_exhausted",
"detail": "..."
}
}常见错误类型:
| 类型 | 说明 |
|---|---|
authentication_error |
认证失败(缺少/无效 Token 或 Session) |
invalid_request_error |
请求参数错误(如缺少 model、模型格式错误、提供商/模型不存在) |
provider_disabled |
提供商已禁用 |
model_disabled |
模型已禁用 |
configuration_error |
配置错误(如提供商未配置可用 API Key) |
key_exhausted |
所有 API Key 均失败 |
proxy_error |
转发过程出错(如网络异常) |
server_error |
服务器内部错误 |
not_found |
接口不存在(404) |
管理 API 的错误响应使用 success: false + message 的格式:
{ "success": false, "message": "错误描述" }