From c64e9c0b4005ac31f91c6dff3715fb96b97283d9 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Mon, 1 Jun 2026 17:24:10 +0800 Subject: [PATCH] chore: remove .agents from git tracking Add .agents/ to .gitignore and untrack skill files. --- .agents/skills/cmd-add-channel/SKILL.md | 65 ------ .agents/skills/cmd-claude-stats/SKILL.md | 142 ------------ .agents/skills/cmd-debug-prod/SKILL.md | 209 ------------------ .agents/skills/cmd-deploy-local/SKILL.md | 98 -------- .agents/skills/cmd-deploy-wsl-test/SKILL.md | 44 ---- .agents/skills/cmd-deploy/SKILL.md | 34 --- .agents/skills/cmd-ob-commit/SKILL.md | 86 ------- .../skills/cmd-set-channel-pricing/SKILL.md | 103 --------- .gitignore | 1 + 9 files changed, 1 insertion(+), 781 deletions(-) delete mode 100644 .agents/skills/cmd-add-channel/SKILL.md delete mode 100644 .agents/skills/cmd-claude-stats/SKILL.md delete mode 100644 .agents/skills/cmd-debug-prod/SKILL.md delete mode 100644 .agents/skills/cmd-deploy-local/SKILL.md delete mode 100644 .agents/skills/cmd-deploy-wsl-test/SKILL.md delete mode 100644 .agents/skills/cmd-deploy/SKILL.md delete mode 100644 .agents/skills/cmd-ob-commit/SKILL.md delete mode 100644 .agents/skills/cmd-set-channel-pricing/SKILL.md diff --git a/.agents/skills/cmd-add-channel/SKILL.md b/.agents/skills/cmd-add-channel/SKILL.md deleted file mode 100644 index d988394..0000000 --- a/.agents/skills/cmd-add-channel/SKILL.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -allowed-tools: mcp__plugin_chrome-devtools-mcp_chrome-devtools__* -description: 'Command: add-channel (imported from Claude Code)' -name: cmd-add-channel ---- - -## 添加渠道 - -通过 Chrome DevTools MCP 在指定环境中操作浏览器完成渠道添加。 - -### 参数 - -用户在 `$ARGUMENTS` 中传入 JSON 格式的渠道信息(字段均可选,缺失时会询问): - -``` -{ - "base_url": "https://api.example.com", - "api_key": "sk-xxx", - "name": "渠道名称", - "type": "OpenAI", - "target": "http://localhost:23000", - "select_all_models": true -} -``` - -| 字段 | 说明 | 默认值 | -|------|------|--------| -| `target` | 目标环境地址 | 询问用户 | -| `base_url` | 渠道 API 地址 | 询问用户 | -| `api_key` | 渠道密钥 | 询问用户 | -| `name` | 渠道名称 | 自动从 base_url 提取域名 | -| `type` | 渠道类型 | `OpenAI` | -| `select_all_models` | 是否全选模型 | `true` | - -如果 `$ARGUMENTS` 不是 JSON,则按顺序解析为 `base_url` `api_key`,其余使用默认值。 - -### 操作流程 - -1. **导航到目标页面** — `navigate_page` 到 `{target}/console/channel` -2. **检查登录状态** — `take_snapshot`,如果没有登录(看不到侧边栏菜单),提示用户先登录 -3. **点击添加渠道** — 找到并点击"添加渠道"按钮 -4. **填写表单** — 按 snap 快照中的元素 uid,依次 `fill`: - - 名称(名称输入框) - - 密钥(密钥输入框) - - API地址(API地址输入框) -5. **获取并选择模型**: - - 点击"填入所有模型"按钮 - - 等待模型选择对话框出现 - - 如果 `select_all_models` 为 true,点击全选 checkbox,然后点击 confirm -6. **提交** — 点击"提交"按钮 -7. **验证** — `take_snapshot` 确认渠道列表中出现了新建的渠道 - -### 测试环境地址 - -| 环境 | 地址 | 说明 | -|------|------|------| -| 国内测试 | http://localhost:23000 | WSL 本地 | -| 国外测试 | http://localhost:13000 | WSL 本地 | -| 生产环境 | https://api.example.com | 按实际填写 | - -### 要求 - -- 每步操作后用 `take_snapshot` 验证页面状态 -- 如果某步操作失败(如获取模型列表超时),报告错误并询问用户是否继续 -- 完成后向用户总结创建结果(渠道名称、类型、模型数量、状态) diff --git a/.agents/skills/cmd-claude-stats/SKILL.md b/.agents/skills/cmd-claude-stats/SKILL.md deleted file mode 100644 index 6cfcecf..0000000 --- a/.agents/skills/cmd-claude-stats/SKILL.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -allowed-tools: Bash(wsl -- *) -description: 'Command: claude-stats (imported from Claude Code)' -name: cmd-claude-stats ---- - -## Claude 模型统计 - -查询 Claude 模型的**错误率**和**缓存率**,自动排除 `relay-pulse` 检测令牌。 - -### 参数 `$ARGUMENTS` - -根据 `$ARGUMENTS` 确定日期范围: - -| 传入格式 | 含义 | -|---------|------| -| (空) | 今天 | -| `2026-05-09` | 指定某一天 | -| `2026-05-01 2026-05-09` | 指定日期范围(含首尾两天) | -| `7d` | 最近 7 天 | - -### 执行步骤 - -**第一步:根据参数计算日期过滤条件** - -- `created_at` 字段是秒级 Unix 时间戳(bigint),用 `UNIX_TIMESTAMP('YYYY-MM-DD')` 转换 -- 今天:`created_at >= UNIX_TIMESTAMP(CURDATE())` -- 某一天 `D`:`created_at >= UNIX_TIMESTAMP('D') AND created_at < UNIX_TIMESTAMP('D') + 86400` -- 范围 `D1` 到 `D2`:`created_at >= UNIX_TIMESTAMP('D1') AND created_at < UNIX_TIMESTAMP('D2') + 86400` -- 最近 N 天:`created_at >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL N-1 DAY))` - -将计算好的条件替换到下面 SQL 中的 `{DATE_FILTER}` 占位符。 - -**第二步:上传 SQL 文件到服务器** - -```bash -wsl -- bash -c " -cat > /tmp/claude_stats_error.sql << 'ENDSQL' -SELECT - model_name, - SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) as success, - SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) as errors, - COUNT(*) as total, - ROUND(SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as error_rate_pct -FROM logs -WHERE {DATE_FILTER} - AND model_name LIKE '%claude%' - AND type IN (2, 5) - AND token_name != 'relay-pulse' -GROUP BY model_name -ORDER BY total DESC; -ENDSQL - -cat > /tmp/claude_stats_cache.sql << 'ENDSQL' -SELECT - model_name, - COUNT(*) as total_requests, - SUM(prompt_tokens) as prompt_tokens, - SUM(completion_tokens) as completion_tokens, - SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) as cache_read_tokens, - SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) as cache_creation_tokens, - SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) as cache_hit_requests, - ROUND( - SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), - 2 - ) as cache_hit_rate_pct, - ROUND( - (SUM(prompt_tokens) * 1.0 - + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) * 0.1 - + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.25) - * 100.0 - / NULLIF( - SUM(prompt_tokens) - + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) - + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)), - 0), - 2 - ) as cost_pct_of_full, - ROUND( - SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.0 - / NULLIF(SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)), 0), - 3 - ) as creation_to_read_ratio -FROM logs -WHERE {DATE_FILTER} - AND type = 2 - AND model_name LIKE '%claude%' - AND other IS NOT NULL - AND token_name != 'relay-pulse' -GROUP BY model_name -ORDER BY total_requests DESC; -ENDSQL - -cat > /tmp/claude_stats_errcode.sql << 'ENDSQL' -SELECT - model_name, - CAST(JSON_UNQUOTE(JSON_EXTRACT(other, '$.status_code')) AS UNSIGNED) as status_code, - COUNT(*) as cnt, - ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (PARTITION BY model_name), 1) as pct -FROM logs -WHERE {DATE_FILTER} - AND type = 5 - AND model_name LIKE '%claude%' - AND token_name != 'relay-pulse' - AND other IS NOT NULL -GROUP BY model_name, status_code -ORDER BY model_name, cnt DESC; -ENDSQL - -scp /tmp/claude_stats_error.sql root@139.180.189.205:/tmp/claude_stats_error.sql -scp /tmp/claude_stats_cache.sql root@139.180.189.205:/tmp/claude_stats_cache.sql -scp /tmp/claude_stats_errcode.sql root@139.180.189.205:/tmp/claude_stats_errcode.sql -" -``` - -**第三步:执行查询并展示结果** - -```bash -wsl -- bash -c "ssh -o ConnectTimeout=20 -o ServerAliveInterval=10 root@139.180.189.205 'echo \"=== 错误率 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_error.sql; echo; echo \"=== 缓存 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_cache.sql; echo; echo \"=== 错误状态码分布 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_errcode.sql' 2>&1 | grep -v 'Warning'" -``` - -### 字段说明 - -**错误率表:** -- `success` — 正常请求数(type=2) -- `errors` — 错误请求数(type=5) -- `error_rate_pct` — 错误率 % - -**缓存率表:** -- `cache_hit_rate_pct` — **次数缓存率** = 有缓存命中的请求数 / 总请求数(最能反映缓存策略是否生效) -- `cost_pct_of_full` — **实际成本占比** = `(prompt × 1 + cache_read × 0.1 + cache_creation × 1.25) / (全量按原价计费)`,越低越省钱(Anthropic 标准定价:cache_read 是原价 10%,cache_creation 是原价 125%) -- `creation_to_read_ratio` — **缓存创建/读取比** = `cache_creation_tokens / cache_read_tokens`,比值高说明缓存频繁失效再重建,命中复用差 - -**错误状态码分布表:** -- `status_code` — HTTP 状态码(504=上游超时,429=限流,400=请求参数错误) -- `cnt` — 该状态码的错误次数 -- `pct` — 占该模型全部错误的百分比 - -### 注意事项 - -- 日期以 OV 服务器(UTC+0)的时区为准,北京时间当天 08:00 后才对应同一自然日 -- `relay-pulse` 是自动探活令牌,已从统计中排除 diff --git a/.agents/skills/cmd-debug-prod/SKILL.md b/.agents/skills/cmd-debug-prod/SKILL.md deleted file mode 100644 index dfec79b..0000000 --- a/.agents/skills/cmd-debug-prod/SKILL.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -allowed-tools: Bash(wsl -- *) -description: 'Command: debug-prod (imported from Claude Code)' -name: cmd-debug-prod ---- - -## 线上排查命令 - -用户要求排查线上问题。根据 `$ARGUMENTS` 确定目标服务器,然后根据问题类型选择合适的操作。 - -### 参数 - -`$ARGUMENTS` 中可能传入: -- (空) — 默认排查国外服务器(OV,主节点) -- `cn` — 只排查国内服务器 -- `ov` — 只排查国外服务器 -- `all` — 排查两台服务器 - -如果用户没有明确指定,**默认排查 OV 服务器**(因为 MySQL 主库在 OV)。 - ---- - -### 服务器配置 - -| 节点 | SSH | docker-compose 目录 | new-api 容器名 | MySQL 容器名 | -|------|-----|---------------------|---------------|-------------| -| 🇨🇳 国内 CN | `root@123.57.74.135` | `/root/new-api/` | `cn-new-api` | `ov-mysql` | -| 🌏 国外 OV | `root@139.180.189.205` | `/root/new-api/new-api/` | `ov-new-api` | `mysql` | - -**重要**:两台服务器的 MySQL 实际都在 OV(国外节点)。CN 的 SQL_DSN 指向 `ov-mysql:3306`。所以查数据库统一用 OV 的 MySQL 容器 `mysql`。 - -MySQL 连接:`docker exec mysql mysql -uroot -pLanqi123456 new-api -e "SQL语句"` - ---- - -### 所有命令执行方式 - -**必须通过 WSL 执行**(SSH 密钥在 WSL 中): - -```bash -# 单条命令 -wsl -- bash -c "ssh root@HOST '命令'" - -# 多条命令(引号嵌套复杂时用 heredoc) -wsl -- bash -c "ssh root@HOST 'cmd1 && cmd2 && cmd3'" -``` - ---- - -### 操作指南 - -根据用户描述的问题,选择合适的排查步骤。**不要一次性执行所有操作**,应该根据问题逐步排查。 - -#### 1. 服务状态检查 - -```bash -# 查看所有容器状态 -wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose ps'" - -# 健康检查 -wsl -- bash -c "ssh root@HOST 'curl -s http://localhost:3000/api/status'" - -# 系统资源(CPU/内存/磁盘) -wsl -- bash -c "ssh root@HOST 'free -h && df -h / && docker stats --no-stream'" -``` - -#### 2. 应用日志 - -```bash -# 最近 N 行容器日志 -wsl -- bash -c "ssh root@HOST 'docker logs --tail 100 CONTAINER_NAME'" - -# 实时跟踪日志(带超时,避免阻塞) -wsl -- bash -c "ssh root@HOST 'timeout 5 docker logs --tail 50 --since 5m CONTAINER_NAME'" - -# 搜索特定关键词(如错误、某用户、某模型) -wsl -- bash -c "ssh root@HOST 'docker logs --tail 500 CONTAINER_NAME 2>&1 | grep -i KEYWORD'" - -# 应用日志文件(oneapi-*.log) -wsl -- bash -c "ssh root@HOST 'ls -lt COMPOSE_DIR/logs/ | head -5'" -wsl -- bash -c "ssh root@HOST 'tail -100 COMPOSE_DIR/logs/oneapi-XXXX.log'" -``` - -#### 3. MySQL 查询 - -**连接方式(在 OV 服务器上执行)**: -```bash -wsl -- bash -c "ssh root@139.180.189.205 'docker exec mysql mysql -uroot -pLanqi123456 new-api -e \"SQL语句\"'" -``` - -注意:SQL 语句中的双引号需要用 `\"` 转义。 - -**常用查询模板**: - -```sql --- 查用户信息 -SELECT id, username, email, role, status, quota, used_quota, \`group\`, aff_code FROM users WHERE username = 'XXX'; - --- 查用户最近的请求日志 -SELECT id, created_at, type, model_name, quota, channel_id, content FROM logs WHERE user_id = XXX ORDER BY created_at DESC LIMIT 20; - --- 查某时间段内的错误日志 -SELECT id, created_at, type, content, model_name FROM logs WHERE created_at >= '2026-04-16 00:00:00' AND type = 2 ORDER BY created_at DESC LIMIT 50; - --- 查渠道状态和余额 -SELECT id, name, type, status, balance, used_quota, models, \`group\`, priority FROM channels WHERE status != 3; - --- 查某渠道的最近请求 -SELECT id, created_at, model_name, quota, content FROM logs WHERE channel_id = XXX ORDER BY created_at DESC LIMIT 20; - --- 查 Token 信息 -SELECT id, name, \`key\`, status, remain_quota, used_quota, expired_time FROM tokens WHERE user_id = XXX; - --- 查最近的充值/支付记录 -SELECT id, user_id, amount, money, trade_no, status, created_at FROM topups ORDER BY created_at DESC LIMIT 20; - --- 查订阅订单 -SELECT id, user_id, plan_id, status, amount, created_at FROM subscription_orders ORDER BY created_at DESC LIMIT 20; - --- 查同步记录(主从同步问题) -SELECT * FROM pending_sync_records ORDER BY id DESC LIMIT 20; -SELECT * FROM quota_sync_logs ORDER BY id DESC LIMIT 20; - --- 查 Midjourney 任务状态 -SELECT id, user_id, action, status, progress, fail_reason, created_at FROM midjourneys ORDER BY created_at DESC LIMIT 20; - --- 查系统配置 -SELECT \`key\`, value FROM options WHERE \`key\` IN ('ServerAddress', 'TopUpLink', 'QuotaForNewUser', 'QuotaForInviter', 'QuotaForInvitee'); -``` - -**日志类型 (type 字段)**: -- `1` — 消耗 (consume) -- `2` — 充值 (recharge/topup) -- `3` — 管理员操作 -- `4` — 系统 - -#### 4. Relay 抓包日志(请求体/响应体完整记录) - -对开启了 `capture_relay` 的用户,系统会将完整的请求体和响应体写入容器内文件。适用于需要查看客户端实际发送的请求体内容的场景(如验证字段是否正确、排查请求格式问题)。 - -**文件路径**(容器内):`/data/data/relay-capture/{YYYY-MM-DD}/{requestID}.log` - -```bash -# 列出某天的抓包文件(最新 20 个) -wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME ls -lt /data/data/relay-capture/2026-05-14/ | head -20"' - -# 查看特定请求的抓包内容(requestID 从日志错误行中获取) -wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME cat /data/data/relay-capture/2026-05-14/REQUEST_ID.log"' - -# 文件很大时,只看请求头 + 请求体前 2000 字节 -wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME head -c 2000 /data/data/relay-capture/2026-05-14/REQUEST_ID.log"' -``` - -**抓包文件格式**: -``` -=== REQUEST 2026-05-14T09:09:51.80665026Z === -POST /v1/chat/completions -user_id: 44 -X-Forwarded-For: 184.73.225.134 -User-Agent: Cursor/1.0 -Content-Type: application/json -... - -{"stream":true,"model":"openai/gpt-5.4","messages":[...]} - -=== RESPONSE === -{"error":{"message":"field messages is required",...}} - -=== END duration_ms=6 === -``` - -**使用场景**: -- 客户端发送了错误格式的请求体(如用 `input` 代替 `messages`) -- 需要确认请求头、User-Agent、请求体字段 -- 排查特定 request ID 的完整请求/响应链路 - -**注意**: -- 只有开启了 `capture_relay` 的用户才有抓包文件,未开启的用户查不到 -- 请求体可能很大(100KB+),建议先用 `head -c` 限制输出大小 -- 抓包文件名即 request ID,可从容器的 `[ERR]` 日志行中提取 - -#### 5. 容器内操作 - -```bash -# 进入容器执行命令(如检查网络连通性) -wsl -- bash -c "ssh root@HOST 'docker exec CONTAINER_NAME wget -qO- http://localhost:3000/api/status'" - -# 重启某个服务(谨慎操作,先确认用户意图) -wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose restart new-api'" -``` - ---- - -### 排查流程建议 - -1. **先问清楚问题**:什么现象?什么时候开始的?影响哪些用户? -2. **服务状态** → 检查容器是否正常运行 -3. **应用日志** → 搜索错误关键词、时间范围 -4. **数据库查询** → 根据日志中的线索查相关数据 -5. **Relay 抓包** → 如果日志中只有错误摘要但看不清请求体细节,检查用户是否开启了 `capture_relay`,若有则读取抓包文件查看完整请求/响应 -6. **综合分析** → 给出问题原因和修复建议 - -### 注意事项 - -- **不要执行任何写入操作**(INSERT/UPDATE/DELETE),除非用户明确要求 -- MySQL 查询要加 `LIMIT`,避免返回过多数据 -- 查询时间范围要合理,不要全表扫描 -- 如果发现需要重启服务,先告知用户再操作 -- 所有输出向用户展示时,用中文解释含义 diff --git a/.agents/skills/cmd-deploy-local/SKILL.md b/.agents/skills/cmd-deploy-local/SKILL.md deleted file mode 100644 index 3cba810..0000000 --- a/.agents/skills/cmd-deploy-local/SKILL.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -allowed-tools: Bash -description: 'Command: deploy-local (imported from Claude Code)' -name: cmd-deploy-local ---- - -## 启动本机开发环境 - -在 Windows 上直接运行 `go run main.go`,数据库使用 WSL 中的 MySQL 和 Redis。 - -### 环境信息 - -| 项目 | 连接信息 | -|------|---------| -| MySQL | `localhost:33306` root/Lanqi123456 db:new-api | -| Redis | `localhost:36379` | -| 后端 | `localhost:3000` | -| 前端 | `localhost:5173`(dev server) | -| 管理员 | root / 12345678 | - -### 参数 - -用户可能在 `$ARGUMENTS` 中传入: -- (空) — 启动全部(MySQL/Redis + 前端 + 后端) -- `--backend-only` — 只启动后端(MySQL/Redis + 后端) -- `--frontend-only` — 只启动前端 dev server -- `--stop` — 停止所有服务(后端进程 + 前端进程) - -### 执行步骤 - -**步骤 1:确保 WSL 中 MySQL 和 Redis 运行** - -```bash -wsl -- bash -c "cd /root/new-api-dev && docker compose up -d" -``` - -等待 MySQL 就绪(最多 30 秒): - -```bash -until wsl -- bash -c "mysql -h 127.0.0.1 -P 3306 -u root -pLanqi123456 -e 'SELECT 1'" 2>/dev/null; do sleep 2; done -``` - -**步骤 2:杀掉旧进程(如果端口被占用)** - -检查并杀掉占用 3000 端口的进程: -```bash -netstat -ano | grep ":3000 " | grep LISTENING | awk '{print $5}' | sort -u | while read pid; do taskkill //PID $pid //F 2>/dev/null; done -``` - -检查并杀掉占用 5173 端口的进程(如果需要启动前端): -```bash -netstat -ano | grep ":5173 " | grep LISTENING | awk '{print $5}' | sort -u | while read pid; do taskkill //PID $pid //F 2>/dev/null; done -``` - -**步骤 3:启动服务** - -前端(后台,仅在非 `--backend-only` 时): -```bash -cd web && bun run dev -``` - -后端(后台,仅在非 `--frontend-only` 时),带环境变量: -```bash -export SQL_DSN="root:Lanqi123456@tcp(localhost:33306)/new-api" -export REDIS_CONN_STRING="redis://localhost:36379" -export SESSION_SECRET="dev-secret-do-not-use-in-prod" -export SESSION_NAME="session_dev" -export DEBUG=1 -export ERROR_LOG_ENABLED=true -export BATCH_UPDATE_ENABLED=true -export TZ=Asia/Shanghai -go run main.go -``` - -**步骤 4:等待就绪并验证** - -等待后端就绪: -```bash -until curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/status | grep -q "200"; do sleep 2; done -``` - -**步骤 5:报告状态** - -向用户报告: -- 各服务状态(MySQL/Redis/后端/前端) -- 访问地址 -- 如果有服务启动失败,报告具体错误 - -### 停止服务(`--stop`) - -杀掉 3000 和 5173 端口上的进程即可。MySQL/Redis 容器保持运行(数据持久化)。 - -### 要求 - -- 所有服务使用 `run_in_background` 启动 -- 等待后端就绪后再报告 -- 如果编译失败,报告具体错误 -- 启动完成后提示用户可以使用 `curl` 或浏览器访问 diff --git a/.agents/skills/cmd-deploy-wsl-test/SKILL.md b/.agents/skills/cmd-deploy-wsl-test/SKILL.md deleted file mode 100644 index e9dd6f5..0000000 --- a/.agents/skills/cmd-deploy-wsl-test/SKILL.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -allowed-tools: Bash(wsl -- *) -description: 'Command: deploy-wsl-test (imported from Claude Code)' -name: cmd-deploy-wsl-test ---- - -## 部署到测试环境 - -将镜像构建并部署到 WSL 本地的国内/国外测试节点。 - -### 测试环境信息 - -| 项目 | 国内节点 | 国外节点 | -|------|---------|---------| -| 目录 | /root/new-api-cn | /root/new-api-ov | -| 端口 | 23000:3000 | 13000:3000 | -| MySQL | 23306 | 13306 | -| 容器名 | cn-new-api | ov-new-api | -| SESSION | session_m (Master) | session_slave (Slave) | - -### 参数 - -用户可能在 `$ARGUMENTS` 中传入: -- (空) — 构建镜像 + 推送 + 部署到两个测试节点 -- `cn` — 只部署到国内测试节点 -- `ov` — 只部署到国外测试节点 -- `--no-build` — 跳过构建推送,使用本地最新镜像 -- 可以组合,如 `--no-build cn` - -### 执行 - -使用以下命令在 WSL 中执行部署: - -```bash -wsl -- bash -c "cd /root && bash //mnt/d/code/new-api/scripts/deploy-test.sh $ARGUMENTS" -``` - -**注意**:路径必须使用 `//mnt/d/...`(双斜杠),否则 Git Bash 会将其转换为 Windows 路径导致 WSL 找不到脚本。 - -### 要求 - -- 等待命令完成,实时向用户报告进度 -- 如果失败,报告具体错误信息 -- 完成后向用户总结部署结果(镜像 tag、各节点状态) diff --git a/.agents/skills/cmd-deploy/SKILL.md b/.agents/skills/cmd-deploy/SKILL.md deleted file mode 100644 index f552bcf..0000000 --- a/.agents/skills/cmd-deploy/SKILL.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -allowed-tools: Bash(wsl -- *) -description: 'Command: deploy (imported from Claude Code)' -name: cmd-deploy ---- - -## 部署命令 - -通过 WSL 执行 `scripts/deploy.sh` 完成自动部署。 - -### 参数 - -用户可能在 `$ARGUMENTS` 中传入: -- (空) — 构建镜像 + 推送 + 部署到两台服务器 -- `cn` — 只部署到国内服务器 (123.57.74.135) -- `ov` — 只部署到国外服务器 (139.180.189.205) -- `--no-build` — 跳过构建推送,使用本地最新镜像 -- 可以组合,如 `--no-build cn` - -### 执行 - -使用以下命令调用部署脚本: - -```bash -wsl -- bash -c "bash //mnt/d/code/new-api/scripts/deploy.sh $ARGUMENTS" -``` - -**注意**:路径必须使用 `//mnt/d/...`(双斜杠),否则 Git Bash 会将其转换为 Windows 路径导致 WSL 找不到脚本。 - -### 要求 - -- 等待命令完成,实时向用户报告进度 -- 如果失败,报告具体错误信息 -- 完成后向用户总结部署结果(镜像 tag、各节点状态) diff --git a/.agents/skills/cmd-ob-commit/SKILL.md b/.agents/skills/cmd-ob-commit/SKILL.md deleted file mode 100644 index 6ad632e..0000000 --- a/.agents/skills/cmd-ob-commit/SKILL.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -allowed-tools: >- - Bash(git add:*), Bash(git status:*), Bash(git diff:*), Bash(git log:*), - Bash(git commit:*), Bash(mkdir:*), Read, Write, Edit, Glob, Grep -description: 'Command: ob-commit (imported from Claude Code)' -name: cmd-ob-commit ---- - -## Context - -- Current git status: !`git status` -- Current git diff (staged and unstaged changes): !`git diff HEAD` -- Current branch: !`git branch --show-current` -- Recent commits: !`git log --oneline -10` - -## Task - -Based on the above changes, create a git commit AND write a development log to Obsidian. - -### Step 1: Create the commit - -1. Analyze the changes and draft a commit message following conventional commits format. -2. Stage the relevant files and create the commit. - -### Step 2: Write Obsidian dev log (MANDATORY) - -After the commit succeeds, you MUST write a development log. Follow these rules exactly: - -**Directory**: `D:\markdown\workspace-lanqi\new-api\{YYYY-MM-DD}\` (create if not exists) - -**File naming**: `{YYYY-MM-DD} {commit message short summary}.md` -- If multiple commits on the same day, append a brief distinguishing suffix -- Example: `2026-04-16 fix: 修复支付回调签名验证.md` - -**Log template** — write in Chinese: - -```markdown ---- -created: YYYY-MM-DD -tags: - - dev-log - - new-api -branch: {branch name} -commit: {short hash} ---- - -# {commit message} - -> 分支:`{branch}` | Commit:`{short hash}` | 日期:YYYY-MM-DD - -## 变更概述 - -{1-3 sentences summarizing purpose and impact} - -## 新增文件 - -| 文件 | 说明 | -|------|------| -| `{path}` | {description} | - -## 修改文件 - -| 文件 | 变更内容 | -|------|---------| -| `{path}` | {what changed and why} | - -## 关键代码变更 - -{Detailed description of core logic changes, including function signature changes, new key functions, algorithm logic. Use code blocks for key snippets.} - -## 数据库变更 - -{If table structure changed, list new tables, columns, indexes. Delete this section if none.} - -## 备注 - -{Additional notes, design decisions, known issues. Delete this section if none.} -``` - -### Rules - -- Delete sections with no content (数据库变更, 备注) -- All log content in Chinese -- Frontmatter MUST include: `created`, `tags` (at least `dev-log` and `new-api`), `branch`, `commit` -- Include enough detail for someone unfamiliar with the change to understand it -- You MUST use multiple tools in a single response. Stage, commit, then write the log file. diff --git a/.agents/skills/cmd-set-channel-pricing/SKILL.md b/.agents/skills/cmd-set-channel-pricing/SKILL.md deleted file mode 100644 index 0c73d25..0000000 --- a/.agents/skills/cmd-set-channel-pricing/SKILL.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -allowed-tools: mcp__plugin_chrome-devtools-mcp_chrome-devtools__* -description: 'Command: set-channel-pricing (imported from Claude Code)' -name: cmd-set-channel-pricing ---- - -## 设置渠道定价 - -通过 Chrome DevTools MCP 在指定环境中操作浏览器,为模型配置渠道定价并设置默认通道。 - -### 参数 - -用户在 `$ARGUMENTS` 中传入 JSON 格式的参数(字段均可选,缺失时会询问): - -``` -{ - "target": "http://localhost:23000", - "model_name": "deepseek-ai/DeepSeek-V3-0324", - "default_channel": "AtlasCloud", - "channels": { - "AtlasCloud": { "model_ratio": 1, "completion_ratio": 1 }, - "atlascloud": { "model_ratio": 1, "completion_ratio": 1 } - } -} -``` - -| 字段 | 说明 | 默认值 | -|------|------|--------| -| `target` | 目标环境地址 | 询问用户 | -| `model_name` | 要配置定价的模型名称 | 询问用户 | -| `default_channel` | 设为默认的渠道名称 | 不设置默认 | -| `channels` | 各渠道的定价配置 | 所有渠道统一设置 model_ratio=1, completion_ratio=1 | - -如果 `$ARGUMENTS` 不是 JSON,按顺序解析为 `model_name`,其余使用默认值。 - -### 操作流程 - -1. **导航到渠道定价页面** - - `navigate_page` 到 `{target}/console/setting?tab=ratio` - -2. **切换到渠道定价视图** - - `take_snapshot` 确认页面加载 - - 找到并点击"分组与模型定价设置"标签页(如果 URL 未直接跳转) - - 点击"可视化倍率设置"子标签 - - 点击"渠道定价"单选按钮 - -3. **搜索目标模型** - - 在搜索框中输入 `model_name` - - 等待列表过滤出目标模型 - -4. **展开模型行** - - 点击目标模型行的展开按钮(chevron_right) - -5. **为每个渠道设置定价** - - 对展开后每个未配置的渠道行,点击编辑按钮(edit icon) - - 在弹出的编辑对话框中: - - 确认模型名称正确 - - 选择计费类型(默认"按量计费") - - 填写模型倍率(`model_ratio`) - - 填写补全倍率(`completion_ratio`) - - 点击确认(confirm)保存 - - 如果渠道已有定价但需要修改,同样点击编辑按钮更新 - -6. **设置默认通道** - - 在展开的模型行中,找到 `default_channel` 对应的渠道 - - 点击该渠道行的星标按钮(star icon) - - 验证出现"已设为默认通道"提示和"默认"文字标签 - -7. **验证结果** - - `take_snapshot` 确认: - - 所有渠道都显示正确的倍率 - - 默认渠道旁显示黄色星标 + "默认"标签 - - 非默认渠道的星标为灰色 - - 向用户总结配置结果 - -### 关键 UI 元素识别 - -| 元素 | 识别方式 | -|------|---------| -| 分组与模型定价设置 tab | 文本匹配 "分组与模型定价设置" | -| 可视化倍率设置 tab | 文本匹配 "可视化倍率设置" | -| 渠道定价 radio | 文本匹配 "渠道定价" | -| 模型行展开按钮 | 模型名称旁的 chevron_right 按钮 | -| 渠道编辑按钮 | 渠道行操作列的 edit 按钮 | -| 模型倍率输入框 | spinbutton,label 含 "模型倍率" | -| 补全倍率输入框 | spinbutton,label 含 "补全倍率" | -| 确认按钮 | 对话框底部的 confirm 按钮 | -| 默认星标按钮 | 渠道行"默认"列的 star 按钮 | - -### 测试环境地址 - -| 环境 | 地址 | 说明 | -|------|------|------| -| 国内测试 | http://localhost:23000 | WSL 本地 | -| 国外测试 | http://localhost:13000 | WSL 本地 | -| 生产环境 | https://api.example.com | 按实际填写 | - -### 要求 - -- 每步操作后用 `take_snapshot` 验证页面状态 -- 如果模型不存在于列表中,报告错误并询问用户是否需要先添加渠道 -- 如果渠道未在列表中显示(模型未关联到该渠道),提示用户该渠道不支持此模型 -- 完成后向用户总结配置结果(模型名称、各渠道倍率、默认通道) diff --git a/.gitignore b/.gitignore index 5276e01..900265a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ plans docs/plans/ CLAUDE.md .claude +.agents/ .worktrees/ logs/ docs/superpowers