ai-agent-router 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/openspec/apply.md +23 -0
- package/.claude/commands/openspec/archive.md +27 -0
- package/.claude/commands/openspec/proposal.md +28 -0
- package/.claude/settings.local.json +12 -0
- package/.claude/skills/ui-ux-pro-max/SKILL.md +228 -0
- package/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.claude/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.claude/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.claude/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/.claude/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-311.pyc +0 -0
- package/.claude/skills/ui-ux-pro-max/scripts/core.py +238 -0
- package/.claude/skills/ui-ux-pro-max/scripts/search.py +61 -0
- package/.cursor/commands/openspec-apply.md +23 -0
- package/.cursor/commands/openspec-archive.md +27 -0
- package/.cursor/commands/openspec-proposal.md +28 -0
- package/.cursor/commands/ui-ux-pro-max.md +226 -0
- package/.eslintrc.json +3 -0
- package/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.shared/ui-ux-pro-max/scripts/core.py +238 -0
- package/.shared/ui-ux-pro-max/scripts/search.py +61 -0
- package/AGENTS.md +18 -0
- package/CLAUDE.md +18 -0
- package/IMPLEMENTATION.md +157 -0
- package/LICENSE +21 -0
- package/README.md +165 -0
- package/dist/.next/types/app/api/config/route.js +52 -0
- package/dist/.next/types/app/api/gateway/[...path]/route.js +52 -0
- package/dist/.next/types/app/api/gateway/route.js +52 -0
- package/dist/.next/types/app/api/logs/route.js +52 -0
- package/dist/.next/types/app/api/models/route.js +52 -0
- package/dist/.next/types/app/api/providers/route.js +52 -0
- package/dist/.next/types/app/api/providers/test/route.js +52 -0
- package/dist/.next/types/app/api/service/start/route.js +52 -0
- package/dist/.next/types/app/api/service/status/route.js +52 -0
- package/dist/.next/types/app/api/service/stop/route.js +52 -0
- package/dist/.next/types/app/layout.js +22 -0
- package/dist/.next/types/app/logs/page.js +22 -0
- package/dist/.next/types/app/models/page.js +22 -0
- package/dist/.next/types/app/page.js +22 -0
- package/dist/.next/types/app/providers/page.js +22 -0
- package/dist/src/app/api/config/route.js +43 -0
- package/dist/src/app/api/gateway/[...path]/route.js +83 -0
- package/dist/src/app/api/gateway/route.js +63 -0
- package/dist/src/app/api/logs/route.js +34 -0
- package/dist/src/app/api/models/route.js +152 -0
- package/dist/src/app/api/providers/route.js +118 -0
- package/dist/src/app/api/providers/test/route.js +154 -0
- package/dist/src/app/api/service/start/route.js +55 -0
- package/dist/src/app/api/service/status/route.js +17 -0
- package/dist/src/app/api/service/stop/route.js +20 -0
- package/dist/src/app/components/ConfirmDialog.jsx +31 -0
- package/dist/src/app/components/Nav.jsx +45 -0
- package/dist/src/app/components/Toast.jsx +37 -0
- package/dist/src/app/components/ToastProvider.jsx +21 -0
- package/dist/src/app/layout.jsx +13 -0
- package/dist/src/app/logs/page.jsx +210 -0
- package/dist/src/app/models/page.jsx +291 -0
- package/dist/src/app/page.jsx +236 -0
- package/dist/src/app/providers/page.jsx +402 -0
- package/dist/src/cli/index.js +90 -0
- package/dist/src/db/database.js +69 -0
- package/dist/src/db/queries.js +261 -0
- package/dist/src/db/schema.js +67 -0
- package/dist/src/server/crypto.js +22 -0
- package/dist/src/server/gateway-server.js +200 -0
- package/dist/src/server/gateway.js +76 -0
- package/dist/src/server/logger.js +72 -0
- package/dist/src/server/providers/anthropic.js +52 -0
- package/dist/src/server/providers/gemini.js +64 -0
- package/dist/src/server/providers/index.js +16 -0
- package/dist/src/server/providers/openai.js +86 -0
- package/dist/src/server/providers/types.js +1 -0
- package/dist/src/server/service-manager.js +286 -0
- package/docs/TODO.md +19 -0
- package/next.config.js +7 -0
- package/openspec/AGENTS.md +456 -0
- package/openspec/changes/add-logging/proposal.md +18 -0
- package/openspec/changes/add-logging/specs/core/spec.md +21 -0
- package/openspec/changes/add-logging/tasks.md +16 -0
- package/openspec/changes/add-provider-test-connection/proposal.md +22 -0
- package/openspec/changes/add-provider-test-connection/specs/model-provider/spec.md +68 -0
- package/openspec/changes/add-provider-test-connection/tasks.md +31 -0
- package/openspec/changes/improve-gateway-startup/design.md +137 -0
- package/openspec/changes/improve-gateway-startup/proposal.md +33 -0
- package/openspec/changes/improve-gateway-startup/specs/api-gateway/spec.md +94 -0
- package/openspec/changes/improve-gateway-startup/specs/web-ui/spec.md +67 -0
- package/openspec/changes/improve-gateway-startup/tasks.md +47 -0
- package/openspec/changes/init-api-gateway/design.md +185 -0
- package/openspec/changes/init-api-gateway/proposal.md +30 -0
- package/openspec/changes/init-api-gateway/specs/api-gateway/spec.md +42 -0
- package/openspec/changes/init-api-gateway/specs/cli-tool/spec.md +40 -0
- package/openspec/changes/init-api-gateway/specs/model-management/spec.md +47 -0
- package/openspec/changes/init-api-gateway/specs/model-provider/spec.md +33 -0
- package/openspec/changes/init-api-gateway/specs/request-logging/spec.md +54 -0
- package/openspec/changes/init-api-gateway/specs/web-ui/spec.md +49 -0
- package/openspec/changes/init-api-gateway/tasks.md +84 -0
- package/openspec/project.md +58 -0
- package/package.json +51 -0
- package/postcss.config.js +6 -0
- package/src/app/api/config/route.ts +62 -0
- package/src/app/api/gateway/[...path]/route.ts +118 -0
- package/src/app/api/gateway/route.ts +77 -0
- package/src/app/api/logs/route.ts +48 -0
- package/src/app/api/models/route.ts +210 -0
- package/src/app/api/providers/route.ts +162 -0
- package/src/app/api/providers/test/route.ts +182 -0
- package/src/app/api/service/start/route.ts +73 -0
- package/src/app/api/service/status/route.ts +22 -0
- package/src/app/api/service/stop/route.ts +27 -0
- package/src/app/components/ConfirmDialog.tsx +63 -0
- package/src/app/components/Nav.tsx +66 -0
- package/src/app/components/Toast.tsx +61 -0
- package/src/app/components/ToastProvider.tsx +43 -0
- package/src/app/globals.css +71 -0
- package/src/app/layout.tsx +22 -0
- package/src/app/logs/page.tsx +261 -0
- package/src/app/models/page.tsx +500 -0
- package/src/app/page.tsx +742 -0
- package/src/app/providers/page.tsx +558 -0
- package/src/cli/index.ts +95 -0
- package/src/db/database.ts +125 -0
- package/src/db/queries.ts +339 -0
- package/src/db/schema.ts +117 -0
- package/src/server/crypto.ts +48 -0
- package/src/server/gateway-server.ts +306 -0
- package/src/server/gateway.ts +163 -0
- package/src/server/logger.ts +96 -0
- package/src/server/providers/anthropic.ts +121 -0
- package/src/server/providers/gemini.ts +112 -0
- package/src/server/providers/index.ts +20 -0
- package/src/server/providers/openai.ts +235 -0
- package/src/server/providers/types.ts +20 -0
- package/src/server/service-manager.ts +321 -0
- package/tailwind.config.js +16 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# 设计文档:完善网关代理服务启动逻辑
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
当前网关服务通过 CLI 工具启动(`ai-agent-router start`),Web UI 中的启动/停止按钮只是改变前端本地状态,没有实际控制服务。用户需要能够通过 Web 界面真正启动和停止服务,并且服务状态需要持久化。
|
|
5
|
+
|
|
6
|
+
## Goals / Non-Goals
|
|
7
|
+
|
|
8
|
+
### Goals
|
|
9
|
+
- 通过 Web UI 启动/停止网关服务
|
|
10
|
+
- 服务状态持久化,刷新页面后仍能正确显示
|
|
11
|
+
- 服务在后台持续运行,不依赖前端会话
|
|
12
|
+
- 支持服务状态实时同步
|
|
13
|
+
|
|
14
|
+
### Non-Goals
|
|
15
|
+
- 不支持通过 Web UI 启动多个服务实例(单实例运行)
|
|
16
|
+
- 不实现服务自动重启功能(本次不涉及)
|
|
17
|
+
- 不实现服务监控和告警(后续可扩展)
|
|
18
|
+
|
|
19
|
+
## Decisions
|
|
20
|
+
|
|
21
|
+
### Decision 1: 服务启动方式
|
|
22
|
+
**选择**: 通过 Node.js `child_process.spawn` 启动 CLI 命令作为子进程
|
|
23
|
+
|
|
24
|
+
**理由**:
|
|
25
|
+
- 复用现有的 CLI 启动逻辑,避免重复代码
|
|
26
|
+
- 子进程独立运行,不阻塞主进程
|
|
27
|
+
- 可以监听进程退出事件,自动更新状态
|
|
28
|
+
|
|
29
|
+
**替代方案考虑**:
|
|
30
|
+
- 直接在主进程中启动服务:会导致 Next.js 开发模式下的热重载问题
|
|
31
|
+
- 使用 PM2 等进程管理器:增加外部依赖,复杂度较高
|
|
32
|
+
|
|
33
|
+
### Decision 2: 服务状态存储
|
|
34
|
+
**选择**: 使用 SQLite 数据库存储服务状态(status, port, pid, started_at)
|
|
35
|
+
|
|
36
|
+
**理由**:
|
|
37
|
+
- 项目已使用 SQLite,无需引入新依赖
|
|
38
|
+
- 状态持久化,支持跨会话查询
|
|
39
|
+
- 可以记录服务启动历史
|
|
40
|
+
|
|
41
|
+
**替代方案考虑**:
|
|
42
|
+
- 仅使用内存存储:刷新页面后状态丢失
|
|
43
|
+
- 使用文件存储:需要处理文件锁和并发问题
|
|
44
|
+
|
|
45
|
+
### Decision 3: 状态同步机制
|
|
46
|
+
**选择**: 前端定期轮询 `/api/service/status` API(每 2-3 秒)
|
|
47
|
+
|
|
48
|
+
**理由**:
|
|
49
|
+
- 实现简单,无需 WebSocket 等复杂机制
|
|
50
|
+
- 对于服务状态这种低频变化足够
|
|
51
|
+
- 兼容性好,无需额外配置
|
|
52
|
+
|
|
53
|
+
**替代方案考虑**:
|
|
54
|
+
- WebSocket 实时推送:增加复杂度,当前场景不需要
|
|
55
|
+
- Server-Sent Events (SSE):需要额外的连接管理
|
|
56
|
+
|
|
57
|
+
### Decision 4: 单实例防护
|
|
58
|
+
**选择**: 在启动前检查数据库中是否有运行中的服务记录,并验证进程是否真实存在
|
|
59
|
+
|
|
60
|
+
**理由**:
|
|
61
|
+
- 防止重复启动导致端口冲突
|
|
62
|
+
- 处理异常退出后数据库状态不一致的情况
|
|
63
|
+
|
|
64
|
+
**实现**:
|
|
65
|
+
1. 启动前查询数据库中的服务状态
|
|
66
|
+
2. 如果状态为运行中,检查进程是否真实存在(通过 pid)
|
|
67
|
+
3. 如果进程不存在,清理数据库状态,允许启动
|
|
68
|
+
4. 如果进程存在,拒绝启动并返回错误
|
|
69
|
+
|
|
70
|
+
### Decision 5: 进程管理
|
|
71
|
+
**选择**: 使用 Node.js 原生 `child_process` 模块,记录子进程 PID
|
|
72
|
+
|
|
73
|
+
**理由**:
|
|
74
|
+
- 无需外部依赖
|
|
75
|
+
- 可以精确控制进程生命周期
|
|
76
|
+
- 可以监听进程退出事件
|
|
77
|
+
|
|
78
|
+
**实现细节**:
|
|
79
|
+
- 使用 `spawn` 而非 `exec`,避免 shell 注入风险
|
|
80
|
+
- 分离 stdout/stderr,便于日志记录
|
|
81
|
+
- 监听 `exit` 事件,自动更新数据库状态
|
|
82
|
+
|
|
83
|
+
## Risks / Trade-offs
|
|
84
|
+
|
|
85
|
+
### Risk 1: 进程异常退出后状态不一致
|
|
86
|
+
**风险**: 如果服务进程异常退出(崩溃、被 kill),数据库状态可能仍显示为运行中
|
|
87
|
+
|
|
88
|
+
**缓解措施**:
|
|
89
|
+
- 启动前检查进程是否存在
|
|
90
|
+
- 定期健康检查(可选,本次不实现)
|
|
91
|
+
- 监听进程退出事件,自动更新状态
|
|
92
|
+
|
|
93
|
+
### Risk 2: 端口冲突
|
|
94
|
+
**风险**: 如果配置的端口已被其他进程占用,启动会失败
|
|
95
|
+
|
|
96
|
+
**缓解措施**:
|
|
97
|
+
- 启动前检测端口是否可用
|
|
98
|
+
- 返回清晰的错误信息
|
|
99
|
+
- 提示用户修改端口配置
|
|
100
|
+
|
|
101
|
+
### Risk 3: 并发启动请求
|
|
102
|
+
**风险**: 用户快速点击启动按钮,可能触发多个启动请求
|
|
103
|
+
|
|
104
|
+
**缓解措施**:
|
|
105
|
+
- 在服务管理器中添加启动锁(flag)
|
|
106
|
+
- 启动过程中禁用启动按钮
|
|
107
|
+
- 返回适当的错误信息
|
|
108
|
+
|
|
109
|
+
### Trade-off: 状态同步延迟
|
|
110
|
+
**权衡**: 轮询方式有 2-3 秒延迟,但实现简单
|
|
111
|
+
|
|
112
|
+
**接受**: 对于服务启动/停止这种低频操作,2-3 秒延迟可接受
|
|
113
|
+
|
|
114
|
+
## Migration Plan
|
|
115
|
+
|
|
116
|
+
### 步骤
|
|
117
|
+
1. 添加数据库 schema 和查询方法(向后兼容,不影响现有功能)
|
|
118
|
+
2. 实现服务管理器(独立模块,不影响现有代码)
|
|
119
|
+
3. 添加服务管理 API(新路由,不影响现有 API)
|
|
120
|
+
4. 修改 Web UI(仅修改启动/停止逻辑,其他功能不变)
|
|
121
|
+
5. 测试验证
|
|
122
|
+
|
|
123
|
+
### 回滚
|
|
124
|
+
- 如果出现问题,可以回退 Web UI 代码,恢复为仅改变本地状态
|
|
125
|
+
- 数据库 schema 可以保留,不影响其他功能
|
|
126
|
+
- 服务管理 API 可以禁用,不影响网关核心功能
|
|
127
|
+
|
|
128
|
+
## Open Questions
|
|
129
|
+
|
|
130
|
+
1. **服务日志输出**: 是否需要将服务进程的 stdout/stderr 输出到某个地方?当前 CLI 直接输出到控制台。
|
|
131
|
+
- **决定**: 本次不实现日志收集,后续可扩展
|
|
132
|
+
|
|
133
|
+
2. **服务配置变更**: 如果用户在服务运行中修改了端口配置,是否需要自动重启服务?
|
|
134
|
+
- **决定**: 本次不实现自动重启,用户需要手动停止后重新启动
|
|
135
|
+
|
|
136
|
+
3. **服务健康检查**: 是否需要定期检查服务是否健康(不仅仅是进程存在)?
|
|
137
|
+
- **决定**: 本次不实现,仅检查进程是否存在
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Change: 完善网关代理服务启动逻辑
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
当前 Web UI 中的启动/停止按钮只是改变前端本地状态,并没有实际启动或停止后台服务。用户点击启动后,如果刷新页面,状态会丢失,服务实际上并没有运行。这导致用户体验不佳,无法通过 Web 界面真正管理网关服务的生命周期。
|
|
5
|
+
|
|
6
|
+
需要实现真正的服务启动/停止功能,使得:
|
|
7
|
+
1. 点击启动按钮时,实际启动后台网关服务进程
|
|
8
|
+
2. 服务状态持久化,刷新页面后仍能正确显示服务状态
|
|
9
|
+
3. 服务在后台持续运行,不依赖于前端页面会话
|
|
10
|
+
|
|
11
|
+
## What Changes
|
|
12
|
+
- **新增服务进程管理 API**:提供启动、停止、查询服务状态的 API 端点
|
|
13
|
+
- **新增服务状态持久化**:将服务运行状态存储到数据库,支持跨会话查询
|
|
14
|
+
- **修改 Web UI 启动/停止逻辑**:从仅改变前端状态改为调用后端 API 实际控制服务
|
|
15
|
+
- **新增服务状态同步机制**:前端定期轮询或使用 WebSocket 同步服务状态
|
|
16
|
+
- **新增进程管理功能**:在 Node.js 中启动和管理子进程,确保服务在后台运行
|
|
17
|
+
|
|
18
|
+
## Impact
|
|
19
|
+
- Affected specs:
|
|
20
|
+
- `web-ui` (修改启动/停止功能,新增状态管理)
|
|
21
|
+
- `api-gateway` (新增服务进程管理能力)
|
|
22
|
+
- Affected code:
|
|
23
|
+
- `src/app/page.tsx` - 修改启动/停止按钮逻辑
|
|
24
|
+
- `src/app/api/gateway/route.ts` - 可能需要调整(如果涉及服务启动)
|
|
25
|
+
- 新增 `src/app/api/service/route.ts` - 服务管理 API
|
|
26
|
+
- 新增 `src/server/service-manager.ts` - 服务进程管理逻辑
|
|
27
|
+
- `src/db/schema.ts` - 可能需要添加服务状态表
|
|
28
|
+
- `src/db/queries.ts` - 添加服务状态查询/更新方法
|
|
29
|
+
- 技术考虑:
|
|
30
|
+
- 需要处理进程启动、停止、状态监控
|
|
31
|
+
- 需要考虑端口冲突检测
|
|
32
|
+
- 需要考虑服务异常退出时的处理
|
|
33
|
+
- 需要考虑多实例启动的防护
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
## MODIFIED Requirements
|
|
2
|
+
|
|
3
|
+
### Requirement: API 网关核心功能
|
|
4
|
+
The system SHALL provide an API gateway that routes requests from clients (Claude, Zcode, Alma) to appropriate AI model providers based on model configuration.
|
|
5
|
+
|
|
6
|
+
#### Scenario: 启动网关服务
|
|
7
|
+
- **WHEN** 用户执行 `api-gateway start` 命令
|
|
8
|
+
- **THEN** 网关服务器启动并监听配置的端口
|
|
9
|
+
- **AND** Web 管理界面同时启动
|
|
10
|
+
- **WHEN** 用户通过 Web UI 点击启动按钮
|
|
11
|
+
- **THEN** 系统启动网关服务进程(通过 CLI 命令)
|
|
12
|
+
- **AND** 服务在后台运行,不依赖前端会话
|
|
13
|
+
- **AND** 服务状态保存到数据库
|
|
14
|
+
- **AND** 服务持续运行直到用户点击停止或进程异常退出
|
|
15
|
+
|
|
16
|
+
#### Scenario: 接收客户端请求
|
|
17
|
+
- **WHEN** 客户端(Claude/Zcode/Alma)向网关发送 API 请求
|
|
18
|
+
- **THEN** 网关接收请求并解析模型标识符
|
|
19
|
+
- **AND** 根据模型配置路由到对应的供应商 API
|
|
20
|
+
|
|
21
|
+
#### Scenario: 转发请求到供应商
|
|
22
|
+
- **WHEN** 网关确定目标供应商和模型
|
|
23
|
+
- **THEN** 使用对应的协议适配器转发请求
|
|
24
|
+
- **AND** 将供应商的响应返回给客户端
|
|
25
|
+
|
|
26
|
+
#### Scenario: 处理请求错误
|
|
27
|
+
- **WHEN** 供应商 API 返回错误或超时
|
|
28
|
+
- **THEN** 网关返回适当的错误响应给客户端
|
|
29
|
+
- **AND** 错误信息记录到日志中
|
|
30
|
+
|
|
31
|
+
## ADDED Requirements
|
|
32
|
+
|
|
33
|
+
### Requirement: 服务进程管理
|
|
34
|
+
The system SHALL provide service management capabilities to start, stop, and query the status of the gateway service through the Web UI.
|
|
35
|
+
|
|
36
|
+
#### Scenario: 启动服务
|
|
37
|
+
- **WHEN** 用户通过 Web UI 点击启动按钮
|
|
38
|
+
- **THEN** 系统检查服务是否已在运行
|
|
39
|
+
- **AND** 如果未运行,启动服务进程
|
|
40
|
+
- **AND** 如果端口已被占用,返回错误信息
|
|
41
|
+
- **AND** 服务状态保存到数据库
|
|
42
|
+
- **AND** 返回启动结果给前端
|
|
43
|
+
|
|
44
|
+
#### Scenario: 停止服务
|
|
45
|
+
- **WHEN** 用户通过 Web UI 点击停止按钮
|
|
46
|
+
- **THEN** 系统查找运行中的服务进程
|
|
47
|
+
- **AND** 终止服务进程
|
|
48
|
+
- **AND** 更新数据库状态为已停止
|
|
49
|
+
- **AND** 返回停止结果给前端
|
|
50
|
+
|
|
51
|
+
#### Scenario: 查询服务状态
|
|
52
|
+
- **WHEN** 前端请求服务状态
|
|
53
|
+
- **THEN** 系统查询数据库中的服务状态
|
|
54
|
+
- **AND** 验证进程是否真实存在(通过 PID)
|
|
55
|
+
- **AND** 如果进程不存在但状态为运行中,更新状态为已停止
|
|
56
|
+
- **AND** 返回当前服务状态(运行中/已停止、端口、启动时间等)
|
|
57
|
+
|
|
58
|
+
#### Scenario: 服务状态持久化
|
|
59
|
+
- **WHEN** 服务启动成功
|
|
60
|
+
- **THEN** 服务状态(运行中、端口、PID、启动时间)保存到数据库
|
|
61
|
+
- **WHEN** 服务停止
|
|
62
|
+
- **THEN** 数据库状态更新为已停止
|
|
63
|
+
- **WHEN** 用户刷新页面
|
|
64
|
+
- **THEN** 系统从数据库查询服务状态并正确显示
|
|
65
|
+
|
|
66
|
+
#### Scenario: 单实例防护
|
|
67
|
+
- **WHEN** 用户尝试启动服务
|
|
68
|
+
- **THEN** 系统检查是否已有服务在运行
|
|
69
|
+
- **AND** 如果已有服务运行,拒绝启动并返回错误
|
|
70
|
+
- **AND** 如果数据库状态为运行中但进程不存在,清理状态并允许启动
|
|
71
|
+
|
|
72
|
+
#### Scenario: 进程异常退出处理
|
|
73
|
+
- **WHEN** 服务进程异常退出(崩溃、被 kill)
|
|
74
|
+
- **THEN** 系统检测到进程退出事件
|
|
75
|
+
- **AND** 自动更新数据库状态为已停止
|
|
76
|
+
- **AND** 前端能够通过状态查询检测到变化
|
|
77
|
+
|
|
78
|
+
### Requirement: 协议支持
|
|
79
|
+
The system SHALL support multiple AI model protocols including Anthropic, OpenAI, and Gemini.
|
|
80
|
+
|
|
81
|
+
#### Scenario: OpenAI 协议请求
|
|
82
|
+
- **WHEN** 客户端请求使用 OpenAI 模型
|
|
83
|
+
- **THEN** 网关使用 OpenAI 协议适配器转发请求
|
|
84
|
+
- **AND** 请求格式符合 OpenAI API 规范
|
|
85
|
+
|
|
86
|
+
#### Scenario: Anthropic 协议请求
|
|
87
|
+
- **WHEN** 客户端请求使用 Anthropic 模型
|
|
88
|
+
- **THEN** 网关使用 Anthropic 协议适配器转发请求
|
|
89
|
+
- **AND** 请求格式符合 Anthropic API 规范
|
|
90
|
+
|
|
91
|
+
#### Scenario: Gemini 协议请求
|
|
92
|
+
- **WHEN** 客户端请求使用 Gemini 模型
|
|
93
|
+
- **THEN** 网关使用 Gemini 协议适配器转发请求
|
|
94
|
+
- **AND** 请求格式符合 Gemini API 规范
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
## MODIFIED Requirements
|
|
2
|
+
|
|
3
|
+
### Requirement: Web 管理界面
|
|
4
|
+
The system SHALL provide a web-based management interface built with Next.js and Tailwind CSS.
|
|
5
|
+
|
|
6
|
+
#### Scenario: 访问管理界面
|
|
7
|
+
- **WHEN** 网关服务启动
|
|
8
|
+
- **THEN** Web 管理界面可通过浏览器访问(默认端口或配置的端口)
|
|
9
|
+
- **AND** 界面使用 Tailwind CSS 样式,美观现代
|
|
10
|
+
|
|
11
|
+
#### Scenario: 网关配置界面
|
|
12
|
+
- **WHEN** 用户访问主页面
|
|
13
|
+
- **THEN** 显示网关配置选项(端口、API_KEY)
|
|
14
|
+
- **AND** 可以修改配置并保存
|
|
15
|
+
- **AND** 配置保存后立即生效或提示重启
|
|
16
|
+
|
|
17
|
+
#### Scenario: 启动/停止网关
|
|
18
|
+
- **WHEN** 用户点击启动按钮
|
|
19
|
+
- **THEN** 系统调用后端 API 启动网关服务进程
|
|
20
|
+
- **AND** 服务在后台启动并持续运行
|
|
21
|
+
- **AND** 按钮状态变为"运行中"
|
|
22
|
+
- **AND** 显示网关运行状态和端口信息
|
|
23
|
+
- **AND** 服务状态持久化到数据库
|
|
24
|
+
- **WHEN** 用户刷新页面
|
|
25
|
+
- **THEN** 系统从数据库查询服务状态并正确显示
|
|
26
|
+
- **AND** 如果服务正在运行,状态显示为"运行中"
|
|
27
|
+
- **WHEN** 用户点击停止按钮
|
|
28
|
+
- **THEN** 系统调用后端 API 停止网关服务进程
|
|
29
|
+
- **AND** 服务进程被终止
|
|
30
|
+
- **AND** 按钮状态变为"已停止"
|
|
31
|
+
- **AND** 数据库状态更新为已停止
|
|
32
|
+
|
|
33
|
+
#### Scenario: 服务状态同步
|
|
34
|
+
- **WHEN** 服务在前台运行(通过 CLI 启动)
|
|
35
|
+
- **THEN** Web UI 能够检测到服务状态并正确显示
|
|
36
|
+
- **WHEN** 服务异常退出(崩溃或被 kill)
|
|
37
|
+
- **THEN** Web UI 能够检测到状态变化并更新显示
|
|
38
|
+
- **WHEN** 用户打开多个浏览器标签页
|
|
39
|
+
- **THEN** 所有标签页都能正确显示服务状态
|
|
40
|
+
|
|
41
|
+
#### Scenario: 供应商管理页面
|
|
42
|
+
- **WHEN** 用户访问供应商管理页面
|
|
43
|
+
- **THEN** 显示供应商列表
|
|
44
|
+
- **AND** 可以添加、编辑、删除供应商
|
|
45
|
+
- **AND** 界面响应式设计,支持移动端
|
|
46
|
+
|
|
47
|
+
#### Scenario: 模型管理页面
|
|
48
|
+
- **WHEN** 用户访问模型管理页面
|
|
49
|
+
- **THEN** 显示模型列表(按供应商分组)
|
|
50
|
+
- **AND** 可以手动添加模型
|
|
51
|
+
- **AND** 可以点击按钮拉取模型列表
|
|
52
|
+
- **AND** 可以启用/禁用、删除模型
|
|
53
|
+
|
|
54
|
+
#### Scenario: UI 优化
|
|
55
|
+
- **WHEN** 界面渲染
|
|
56
|
+
- **THEN** 使用 ui-ux-pro-max 进行 UI 优化
|
|
57
|
+
- **AND** 界面美观、易用、符合现代设计规范
|
|
58
|
+
- **AND** 交互流畅,反馈及时
|
|
59
|
+
|
|
60
|
+
### Requirement: 响应式设计
|
|
61
|
+
The system SHALL provide responsive web interface that works on different screen sizes.
|
|
62
|
+
|
|
63
|
+
#### Scenario: 移动端访问
|
|
64
|
+
- **WHEN** 用户在移动设备上访问管理界面
|
|
65
|
+
- **THEN** 界面自适应屏幕大小
|
|
66
|
+
- **AND** 所有功能可用
|
|
67
|
+
- **AND** 布局合理,易于操作
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## 1. 数据库层
|
|
2
|
+
- [x] 1.1 设计服务状态表 schema(service_status: id, status, port, pid, started_at, updated_at)
|
|
3
|
+
- [x] 1.2 实现服务状态查询方法(getServiceStatus)
|
|
4
|
+
- [x] 1.3 实现服务状态更新方法(updateServiceStatus, setServiceStatus)
|
|
5
|
+
- [x] 1.4 实现服务状态清理方法(清理已停止的进程记录)
|
|
6
|
+
|
|
7
|
+
## 2. 服务进程管理
|
|
8
|
+
- [x] 2.1 实现服务管理器(ServiceManager 类)
|
|
9
|
+
- [x] 2.2 实现启动服务方法(spawn 子进程运行 CLI start 命令)
|
|
10
|
+
- [x] 2.3 实现停止服务方法(kill 进程,更新状态)
|
|
11
|
+
- [x] 2.4 实现查询服务状态方法(检查进程是否存在,同步数据库状态)
|
|
12
|
+
- [x] 2.5 实现端口冲突检测(启动前检查端口是否被占用)
|
|
13
|
+
- [x] 2.6 实现进程异常退出监听(监听子进程退出事件,更新状态)
|
|
14
|
+
- [x] 2.7 实现单实例防护(防止同时启动多个服务实例)
|
|
15
|
+
|
|
16
|
+
## 3. 服务管理 API
|
|
17
|
+
- [x] 3.1 创建 `/api/service` 路由
|
|
18
|
+
- [x] 3.2 实现 GET `/api/service/status` - 查询服务状态
|
|
19
|
+
- [x] 3.3 实现 POST `/api/service/start` - 启动服务
|
|
20
|
+
- [x] 3.4 实现 POST `/api/service/stop` - 停止服务
|
|
21
|
+
- [x] 3.5 实现错误处理和状态码返回
|
|
22
|
+
- [x] 3.6 实现请求参数验证(端口、配置等)
|
|
23
|
+
|
|
24
|
+
## 4. Web UI 修改
|
|
25
|
+
- [x] 4.1 修改启动按钮逻辑,调用 `/api/service/start` API
|
|
26
|
+
- [x] 4.2 修改停止按钮逻辑,调用 `/api/service/stop` API
|
|
27
|
+
- [x] 4.3 实现服务状态轮询(定期调用 `/api/service/status` 同步状态)
|
|
28
|
+
- [x] 4.4 修改状态显示逻辑,从 API 获取真实状态而非本地状态
|
|
29
|
+
- [x] 4.5 添加加载状态和错误提示(启动中、启动失败等)
|
|
30
|
+
- [x] 4.6 实现启动/停止按钮的禁用逻辑(服务运行中禁用启动,已停止禁用停止)
|
|
31
|
+
|
|
32
|
+
## 5. 错误处理和边界情况
|
|
33
|
+
- [x] 5.1 处理端口已被占用的情况
|
|
34
|
+
- [x] 5.2 处理服务启动失败的情况
|
|
35
|
+
- [x] 5.3 处理服务异常退出的情况(自动更新状态)
|
|
36
|
+
- [x] 5.4 处理页面刷新时的状态恢复
|
|
37
|
+
- [x] 5.5 处理并发启动请求(防止重复启动)
|
|
38
|
+
- [x] 5.6 实现优雅关闭(停止时清理资源)
|
|
39
|
+
|
|
40
|
+
## 6. 测试和验证
|
|
41
|
+
- [ ] 6.1 测试启动服务功能
|
|
42
|
+
- [ ] 6.2 测试停止服务功能
|
|
43
|
+
- [ ] 6.3 测试状态查询功能
|
|
44
|
+
- [ ] 6.4 测试页面刷新后状态恢复
|
|
45
|
+
- [ ] 6.5 测试端口冲突处理
|
|
46
|
+
- [ ] 6.6 测试服务异常退出处理
|
|
47
|
+
- [ ] 6.7 测试并发启动防护
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Design: API 网关架构设计
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
需要构建一个类似 NewAPI 的 API 网关,支持多种 AI 模型协议,提供统一的管理界面和请求日志功能。项目将作为 npm CLI 工具发布,需要支持本地部署和配置。
|
|
5
|
+
|
|
6
|
+
## Goals / Non-Goals
|
|
7
|
+
|
|
8
|
+
### Goals
|
|
9
|
+
- 支持多种 AI 模型协议(Anthropic、OpenAI、Gemini)
|
|
10
|
+
- 提供 Web 界面进行配置和管理
|
|
11
|
+
- 记录所有请求日志并提供可视化查看
|
|
12
|
+
- 支持动态添加模型供应商和模型
|
|
13
|
+
- 打包为 CLI 工具,易于安装和使用
|
|
14
|
+
- 使用 SQLite3 作为轻量级数据存储
|
|
15
|
+
|
|
16
|
+
### Non-Goals
|
|
17
|
+
- 不支持多租户或用户认证(单用户本地使用)
|
|
18
|
+
- 不支持分布式部署(单机运行)
|
|
19
|
+
- 不支持请求限流和配额管理(后续可扩展)
|
|
20
|
+
- 不支持请求缓存(后续可扩展)
|
|
21
|
+
|
|
22
|
+
## Decisions
|
|
23
|
+
|
|
24
|
+
### Decision: 使用 Next.js 作为全栈框架
|
|
25
|
+
**Rationale**:
|
|
26
|
+
- Next.js 提供前后端一体化开发,简化项目结构
|
|
27
|
+
- 内置 API Routes 可以处理网关请求转发
|
|
28
|
+
- 支持 SSR/SSG,便于构建管理界面
|
|
29
|
+
- 生态成熟,易于集成 Tailwind CSS
|
|
30
|
+
|
|
31
|
+
**Alternatives considered**:
|
|
32
|
+
- Express + React: 需要分别管理前后端,增加复杂度
|
|
33
|
+
- Fastify + Vue: 团队对 Next.js 更熟悉
|
|
34
|
+
|
|
35
|
+
### Decision: 使用 SQLite3 作为数据库
|
|
36
|
+
**Rationale**:
|
|
37
|
+
- 轻量级,无需额外数据库服务
|
|
38
|
+
- 适合单机部署场景
|
|
39
|
+
- 文件存储,便于备份和迁移
|
|
40
|
+
- Node.js 有成熟的 SQLite3 驱动
|
|
41
|
+
|
|
42
|
+
**Alternatives considered**:
|
|
43
|
+
- PostgreSQL: 对于单机场景过于重量级
|
|
44
|
+
- JSON 文件: 并发写入和查询性能较差
|
|
45
|
+
|
|
46
|
+
### Decision: 网关架构采用代理转发模式
|
|
47
|
+
**Rationale**:
|
|
48
|
+
- 简单直接,易于实现和维护
|
|
49
|
+
- 支持协议转换和请求适配
|
|
50
|
+
- 可以统一添加日志、错误处理等横切关注点
|
|
51
|
+
|
|
52
|
+
**Implementation**:
|
|
53
|
+
- 网关监听配置的端口
|
|
54
|
+
- 接收客户端请求(Claude、Zcode、Alma)
|
|
55
|
+
- 根据模型配置路由到对应的供应商 API
|
|
56
|
+
- 转发请求并返回响应
|
|
57
|
+
|
|
58
|
+
### Decision: CLI 工具使用 Commander.js
|
|
59
|
+
**Rationale**:
|
|
60
|
+
- 成熟的 Node.js CLI 框架
|
|
61
|
+
- 支持子命令、参数解析、帮助信息
|
|
62
|
+
- 易于集成到 npm 包
|
|
63
|
+
|
|
64
|
+
**Commands**:
|
|
65
|
+
- `api-gateway start` - 启动网关服务
|
|
66
|
+
- `api-gateway config` - 配置管理(可选)
|
|
67
|
+
|
|
68
|
+
### Decision: 使用 ui-ux-pro-max 优化 UI
|
|
69
|
+
**Rationale**:
|
|
70
|
+
- 项目已有 ui-ux-pro-max 技能,可以用于生成优化的 UI 设计
|
|
71
|
+
- 确保界面美观和用户体验良好
|
|
72
|
+
|
|
73
|
+
## Architecture
|
|
74
|
+
|
|
75
|
+
### 项目结构
|
|
76
|
+
```
|
|
77
|
+
api-gateway/
|
|
78
|
+
├── src/
|
|
79
|
+
│ ├── server/ # 网关服务器
|
|
80
|
+
│ │ ├── gateway.ts # 核心网关逻辑
|
|
81
|
+
│ │ ├── providers/ # 协议适配器
|
|
82
|
+
│ │ │ ├── anthropic.ts
|
|
83
|
+
│ │ │ ├── openai.ts
|
|
84
|
+
│ │ │ └── gemini.ts
|
|
85
|
+
│ │ └── logger.ts # 请求日志记录
|
|
86
|
+
│ ├── db/ # 数据库层
|
|
87
|
+
│ │ ├── schema.ts # SQLite 表结构
|
|
88
|
+
│ │ └── queries.ts # 数据库查询
|
|
89
|
+
│ ├── app/ # Next.js 应用
|
|
90
|
+
│ │ ├── api/ # API 路由
|
|
91
|
+
│ │ │ ├── providers/ # 供应商管理 API
|
|
92
|
+
│ │ │ ├── models/ # 模型管理 API
|
|
93
|
+
│ │ │ ├── config/ # 配置管理 API
|
|
94
|
+
│ │ │ └── logs/ # 日志查询 API
|
|
95
|
+
│ │ └── (pages)/ # 前端页面
|
|
96
|
+
│ │ ├── page.tsx # 主页面(配置)
|
|
97
|
+
│ │ └── logs/ # 日志查看页面
|
|
98
|
+
│ └── cli/ # CLI 入口
|
|
99
|
+
│ └── index.ts
|
|
100
|
+
├── package.json
|
|
101
|
+
├── tsconfig.json
|
|
102
|
+
└── tailwind.config.js
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 数据模型
|
|
106
|
+
|
|
107
|
+
#### providers 表
|
|
108
|
+
- id: INTEGER PRIMARY KEY
|
|
109
|
+
- name: TEXT (供应商名称,如 "OpenAI")
|
|
110
|
+
- protocol: TEXT (协议类型: "openai", "anthropic", "gemini")
|
|
111
|
+
- base_url: TEXT (API 基础 URL)
|
|
112
|
+
- api_key: TEXT (加密存储)
|
|
113
|
+
- created_at: DATETIME
|
|
114
|
+
- updated_at: DATETIME
|
|
115
|
+
|
|
116
|
+
#### models 表
|
|
117
|
+
- id: INTEGER PRIMARY KEY
|
|
118
|
+
- provider_id: INTEGER (外键到 providers)
|
|
119
|
+
- name: TEXT (模型名称,如 "gpt-4")
|
|
120
|
+
- model_id: TEXT (供应商的模型标识符)
|
|
121
|
+
- enabled: BOOLEAN (是否启用)
|
|
122
|
+
- created_at: DATETIME
|
|
123
|
+
- updated_at: DATETIME
|
|
124
|
+
|
|
125
|
+
#### request_logs 表
|
|
126
|
+
- id: INTEGER PRIMARY KEY
|
|
127
|
+
- model_id: INTEGER (外键到 models)
|
|
128
|
+
- request_method: TEXT (HTTP 方法)
|
|
129
|
+
- request_path: TEXT (请求路径)
|
|
130
|
+
- request_headers: TEXT (JSON 字符串)
|
|
131
|
+
- request_query: TEXT (JSON 字符串)
|
|
132
|
+
- request_body: TEXT (JSON 字符串)
|
|
133
|
+
- response_status: INTEGER (HTTP 状态码)
|
|
134
|
+
- response_body: TEXT (JSON 字符串)
|
|
135
|
+
- response_time_ms: INTEGER (响应时间)
|
|
136
|
+
- created_at: DATETIME
|
|
137
|
+
|
|
138
|
+
#### config 表
|
|
139
|
+
- key: TEXT PRIMARY KEY
|
|
140
|
+
- value: TEXT (JSON 字符串)
|
|
141
|
+
- updated_at: DATETIME
|
|
142
|
+
|
|
143
|
+
### 协议适配
|
|
144
|
+
|
|
145
|
+
每个协议需要实现统一的适配器接口:
|
|
146
|
+
```typescript
|
|
147
|
+
interface ProviderAdapter {
|
|
148
|
+
forwardRequest(model: Model, request: GatewayRequest): Promise<GatewayResponse>
|
|
149
|
+
listModels(provider: Provider): Promise<Model[]>
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 安全考虑
|
|
154
|
+
- API Key 加密存储(使用简单的加密或环境变量)
|
|
155
|
+
- 网关 API_KEY 验证(可选)
|
|
156
|
+
- 请求日志中的敏感信息脱敏(API Key、Token 等)
|
|
157
|
+
|
|
158
|
+
## Risks / Trade-offs
|
|
159
|
+
|
|
160
|
+
### Risk: 协议差异导致适配复杂
|
|
161
|
+
**Mitigation**: 先实现核心协议(OpenAI、Anthropic),其他协议逐步添加
|
|
162
|
+
|
|
163
|
+
### Risk: SQLite 并发写入性能
|
|
164
|
+
**Mitigation**:
|
|
165
|
+
- 日志写入使用批量插入
|
|
166
|
+
- 考虑使用 WAL 模式提升并发性能
|
|
167
|
+
- 如果性能不足,后续可迁移到 PostgreSQL
|
|
168
|
+
|
|
169
|
+
### Risk: CLI 工具打包体积
|
|
170
|
+
**Mitigation**:
|
|
171
|
+
- 使用 Next.js standalone 输出
|
|
172
|
+
- 排除不必要的依赖
|
|
173
|
+
- 考虑使用 pkg 或类似工具打包为单文件
|
|
174
|
+
|
|
175
|
+
### Trade-off: 单机部署 vs 分布式
|
|
176
|
+
**Decision**: 先实现单机部署,满足 MVP 需求,后续可扩展
|
|
177
|
+
|
|
178
|
+
## Migration Plan
|
|
179
|
+
N/A - 全新项目,无需迁移
|
|
180
|
+
|
|
181
|
+
## Open Questions
|
|
182
|
+
1. API Key 加密方案:使用环境变量还是数据库加密?
|
|
183
|
+
2. 日志保留策略:是否需要自动清理旧日志?
|
|
184
|
+
3. 模型列表自动拉取:是否需要定时刷新?
|
|
185
|
+
4. 网关启动时的端口冲突处理?
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Change: 初始化 API 网关项目
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
需要一个统一的 API 网关来管理和路由多个 AI 模型供应商(Anthropic、OpenAI、Gemini 等),为 Claude、Zcode、Alma 等客户端软件提供统一的接口。该网关需要支持灵活的模型配置、请求日志记录和可视化管理界面,最终发布为 npm CLI 工具以便于部署和使用。
|
|
5
|
+
|
|
6
|
+
## What Changes
|
|
7
|
+
- **新增 API 网关核心功能**:支持多种协议(Anthropic、OpenAI、Gemini),统一路由和转发请求
|
|
8
|
+
- **新增模型供应商管理**:支持添加、配置多个模型供应商(baseUrl、API Key)
|
|
9
|
+
- **新增模型管理功能**:支持手动添加模型和自动拉取模型列表
|
|
10
|
+
- **新增 Web 管理界面**:基于 Next.js + Tailwind CSS 的前端界面,用于配置网关、管理供应商和模型
|
|
11
|
+
- **新增请求日志系统**:记录所有 API 请求,提供可视化的日志查看界面(请求头、query、body、response)
|
|
12
|
+
- **新增 CLI 工具**:将网关打包为 Node.js CLI 工具,支持通过 npm 发布和安装
|
|
13
|
+
- **新增数据库存储**:使用 SQLite3 存储配置和日志数据
|
|
14
|
+
|
|
15
|
+
## Impact
|
|
16
|
+
- Affected specs:
|
|
17
|
+
- `api-gateway` (新增核心网关功能)
|
|
18
|
+
- `model-provider` (新增供应商管理)
|
|
19
|
+
- `model-management` (新增模型管理)
|
|
20
|
+
- `web-ui` (新增 Web 管理界面)
|
|
21
|
+
- `request-logging` (新增请求日志)
|
|
22
|
+
- `cli-tool` (新增 CLI 工具)
|
|
23
|
+
- Affected code:
|
|
24
|
+
- 全新项目,无现有代码影响
|
|
25
|
+
- 技术栈:
|
|
26
|
+
- Next.js (前端框架)
|
|
27
|
+
- Tailwind CSS (样式)
|
|
28
|
+
- SQLite3 (数据库)
|
|
29
|
+
- Node.js (后端运行时)
|
|
30
|
+
- npm (包管理)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## ADDED Requirements
|
|
2
|
+
|
|
3
|
+
### Requirement: API 网关核心功能
|
|
4
|
+
The system SHALL provide an API gateway that routes requests from clients (Claude, Zcode, Alma) to appropriate AI model providers based on model configuration.
|
|
5
|
+
|
|
6
|
+
#### Scenario: 启动网关服务
|
|
7
|
+
- **WHEN** 用户执行 `api-gateway start` 命令
|
|
8
|
+
- **THEN** 网关服务器启动并监听配置的端口
|
|
9
|
+
- **AND** Web 管理界面同时启动
|
|
10
|
+
|
|
11
|
+
#### Scenario: 接收客户端请求
|
|
12
|
+
- **WHEN** 客户端(Claude/Zcode/Alma)向网关发送 API 请求
|
|
13
|
+
- **THEN** 网关接收请求并解析模型标识符
|
|
14
|
+
- **AND** 根据模型配置路由到对应的供应商 API
|
|
15
|
+
|
|
16
|
+
#### Scenario: 转发请求到供应商
|
|
17
|
+
- **WHEN** 网关确定目标供应商和模型
|
|
18
|
+
- **THEN** 使用对应的协议适配器转发请求
|
|
19
|
+
- **AND** 将供应商的响应返回给客户端
|
|
20
|
+
|
|
21
|
+
#### Scenario: 处理请求错误
|
|
22
|
+
- **WHEN** 供应商 API 返回错误或超时
|
|
23
|
+
- **THEN** 网关返回适当的错误响应给客户端
|
|
24
|
+
- **AND** 错误信息记录到日志中
|
|
25
|
+
|
|
26
|
+
### Requirement: 协议支持
|
|
27
|
+
The system SHALL support multiple AI model protocols including Anthropic, OpenAI, and Gemini.
|
|
28
|
+
|
|
29
|
+
#### Scenario: OpenAI 协议请求
|
|
30
|
+
- **WHEN** 客户端请求使用 OpenAI 模型
|
|
31
|
+
- **THEN** 网关使用 OpenAI 协议适配器转发请求
|
|
32
|
+
- **AND** 请求格式符合 OpenAI API 规范
|
|
33
|
+
|
|
34
|
+
#### Scenario: Anthropic 协议请求
|
|
35
|
+
- **WHEN** 客户端请求使用 Anthropic 模型
|
|
36
|
+
- **THEN** 网关使用 Anthropic 协议适配器转发请求
|
|
37
|
+
- **AND** 请求格式符合 Anthropic API 规范
|
|
38
|
+
|
|
39
|
+
#### Scenario: Gemini 协议请求
|
|
40
|
+
- **WHEN** 客户端请求使用 Gemini 模型
|
|
41
|
+
- **THEN** 网关使用 Gemini 协议适配器转发请求
|
|
42
|
+
- **AND** 请求格式符合 Gemini API 规范
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## ADDED Requirements
|
|
2
|
+
|
|
3
|
+
### Requirement: CLI 工具
|
|
4
|
+
The system SHALL be packaged as a Node.js CLI tool that can be installed via npm.
|
|
5
|
+
|
|
6
|
+
#### Scenario: 安装 CLI 工具
|
|
7
|
+
- **WHEN** 用户执行 `npm install -g api-gateway`(或包名)
|
|
8
|
+
- **THEN** CLI 工具安装到全局
|
|
9
|
+
- **AND** 可以通过命令行执行 `api-gateway` 命令
|
|
10
|
+
|
|
11
|
+
#### Scenario: 启动网关
|
|
12
|
+
- **WHEN** 用户执行 `api-gateway start`
|
|
13
|
+
- **THEN** 网关服务器启动
|
|
14
|
+
- **AND** Web 管理界面启动
|
|
15
|
+
- **AND** 显示启动信息和访问地址
|
|
16
|
+
|
|
17
|
+
#### Scenario: 查看帮助信息
|
|
18
|
+
- **WHEN** 用户执行 `api-gateway --help` 或 `api-gateway -h`
|
|
19
|
+
- **THEN** 显示命令使用说明
|
|
20
|
+
- **AND** 列出所有可用命令和选项
|
|
21
|
+
|
|
22
|
+
#### Scenario: 配置命令(可选)
|
|
23
|
+
- **WHEN** 用户执行 `api-gateway config set port 3000`
|
|
24
|
+
- **THEN** 配置项保存
|
|
25
|
+
- **AND** 下次启动时使用新配置
|
|
26
|
+
|
|
27
|
+
### Requirement: npm 发布
|
|
28
|
+
The system SHALL be published to npmjs registry.
|
|
29
|
+
|
|
30
|
+
#### Scenario: 发布到 npm
|
|
31
|
+
- **WHEN** 开发者执行 `npm publish`
|
|
32
|
+
- **THEN** 包发布到 npmjs
|
|
33
|
+
- **AND** 其他用户可以通过 npm 安装
|
|
34
|
+
- **AND** package.json 配置正确(bin 字段、版本号等)
|
|
35
|
+
|
|
36
|
+
#### Scenario: 包信息配置
|
|
37
|
+
- **WHEN** 用户查看 npm 包信息
|
|
38
|
+
- **THEN** 显示正确的包名、版本、描述
|
|
39
|
+
- **AND** 包含 README.md 说明文档
|
|
40
|
+
- **AND** 包含必要的元数据(author、license 等)
|