@peterwangze/claude-trigger-router 1.1.0 → 1.1.2
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/README.md +122 -14
- package/config/deploy/README.md +36 -0
- package/config/deploy/docker-compose.server.yaml +29 -0
- package/config/deploy/systemd/claude-trigger-router.service +33 -0
- package/dist/cli.js +2003 -183
- package/dist/cli.js.map +4 -4
- package/docs/cli-test-matrix.md +175 -0
- package/docs/configuration-guide.md +390 -0
- package/docs/configuration-roles.md +42 -0
- package/docs/models-migration-guide.md +266 -0
- package/docs/releasing.md +311 -0
- package/docs/remote-client-guide.md +68 -0
- package/docs/server-maintainer-guide.md +81 -0
- package/package.json +2 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# CLI 测试矩阵
|
|
2
|
+
|
|
3
|
+
这份文档只关注用户可见命令和真实使用路径,目标是把“不会异常退出、不会误改文件、不会误导用户、行为符合命令语义”变成发布前可核对的门禁。
|
|
4
|
+
|
|
5
|
+
## 1. 测试分层
|
|
6
|
+
|
|
7
|
+
当前 CLI 测试分成 3 层:
|
|
8
|
+
|
|
9
|
+
- `src/setup/index.test.ts`
|
|
10
|
+
- 关注 setup 向导内部编排、分支决策、提示文案与错误处理
|
|
11
|
+
- `src/e2e/cli-e2e.test.ts`
|
|
12
|
+
- 关注打包后 CLI 的主要命令与选择路径
|
|
13
|
+
- 重点校验隔离 HOME、副作用白名单、主流程行为
|
|
14
|
+
- `src/e2e/cli-acceptance.test.ts`
|
|
15
|
+
- 关注更贴近真实人工验证的 shell / wrapper / staged 包路径
|
|
16
|
+
- 重点校验 Windows 终端输出、wrapper、daemon 生命周期、release stage 验收链路
|
|
17
|
+
|
|
18
|
+
## 2. 当前自动覆盖范围
|
|
19
|
+
|
|
20
|
+
### 基础命令
|
|
21
|
+
|
|
22
|
+
- `help` / `--help` / `-h` / 空命令
|
|
23
|
+
- `version`
|
|
24
|
+
- `upgrade`
|
|
25
|
+
- `doctor`
|
|
26
|
+
- `ui`(跳过打开浏览器)
|
|
27
|
+
- `ui` 在服务未就绪时的明确提示
|
|
28
|
+
- `init --force`
|
|
29
|
+
- `deploy init --target server --force`
|
|
30
|
+
- `init --force -> start --daemon -> status -> stop` 的最小模板可启动性
|
|
31
|
+
- 非法 `--port` 参数的安全失败
|
|
32
|
+
- 未知命令
|
|
33
|
+
|
|
34
|
+
### 服务生命周期
|
|
35
|
+
|
|
36
|
+
- `start` 前台启动
|
|
37
|
+
- `start --daemon`
|
|
38
|
+
- `start --daemon` 启动失败时不再输出误导性成功提示
|
|
39
|
+
- `status`
|
|
40
|
+
- `stop`
|
|
41
|
+
- 前台 `start` 在服务已运行时的清晰提示
|
|
42
|
+
- `restart`
|
|
43
|
+
- `restart --daemon`
|
|
44
|
+
- `restart` 与 `restart --daemon` 当前等价,且 CLI 会明确提示默认走后台模式
|
|
45
|
+
- 端口被非本服务占用时的安全提示
|
|
46
|
+
- stale PID 文件的安全清理
|
|
47
|
+
|
|
48
|
+
### Claude 入口
|
|
49
|
+
|
|
50
|
+
- 服务未运行时执行 `code` 的安全失败
|
|
51
|
+
- 服务未运行时,即使设置 `CTR_AUTO_START=1`,`code` 仍会明确失败而不是误导性继续执行
|
|
52
|
+
- 服务运行时执行 `code`,并验证传给 Claude 的 `ANTHROPIC_BASE_URL`
|
|
53
|
+
- 服务运行但本机未安装 Claude Code CLI 时,`code` 的明确失败提示
|
|
54
|
+
- `setup -> status -> code` 的真实 shell/wrapper 主路径
|
|
55
|
+
|
|
56
|
+
### 配置诊断
|
|
57
|
+
|
|
58
|
+
- `doctor` 对低风险格式问题的自动修复
|
|
59
|
+
- `doctor` 在用户拒绝时不会执行模型探测
|
|
60
|
+
- `doctor` 在用户同意后会对模型发送最小探测请求
|
|
61
|
+
- `doctor` 会用用户可理解的兼容策略说明替代内部兼容 profile 字符串
|
|
62
|
+
- `doctor` 会预览 capability 降级导致的运行时兼容提示,而不是只展示编译期 code
|
|
63
|
+
- `doctor` 探测失败时会输出中文失败解释、处理建议和原始远端错误
|
|
64
|
+
- `doctor` 在 server/cloud 模式下输出监听地址、远程客户端 `ANTHROPIC_BASE_URL`、维护入口和 managed `client + read-only` key 指引
|
|
65
|
+
|
|
66
|
+
### 部署入口
|
|
67
|
+
|
|
68
|
+
- `deploy init --target server --force` 会生成带随机 bootstrap `APIKEY`、`HOST: 0.0.0.0`、`Runtime.mode: server`、`Models` 和 `Router.default` 的自托管 server 起步配置
|
|
69
|
+
- `deploy init --target server` 在已有配置时不会覆盖文件,会提示显式追加 `--force`
|
|
70
|
+
- deploy 入口不会自动启动服务;后续仍要求维护者运行 `ctr doctor` 和 `ctr start --daemon`
|
|
71
|
+
- `ctr status` 在 server/cloud 模式下输出 role、listener、auth 摘要、维护入口和远程客户端连接说明;服务已 ready 时优先使用 live `/api/service-info`,PID 元数据缺失时也不能误报停止
|
|
72
|
+
- `ctr setup` 在本地使用和连接远程服务两条 fresh 路径中输出统一角色说明,避免把 remote service、server deploy 和 managed key 混成同一条用户路径
|
|
73
|
+
- `ctr setup` fresh 路径支持“部署为远程服务端”,生成 server profile / bootstrap admin `APIKEY` / `Runtime.mode: server`,并且不自动启动服务
|
|
74
|
+
- `ctr setup` 保存后按角色输出状态反馈:本地路径说明本地代理已 start/reuse/reload/restart 并提示 `ctr code`,远程客户端路径只承诺 ready/status 检查和直连远端所需环境变量,服务端路径不启动服务
|
|
75
|
+
- `ctr setup` 复用已有 `Runtime.mode: server/cloud` 配置时不能自动启动服务或进入 Claude Code,本地代理 next steps 只适用于 `Runtime.mode: local`
|
|
76
|
+
|
|
77
|
+
### UI / 服务状态
|
|
78
|
+
|
|
79
|
+
- `/ui` 首屏展示服务 ready、端口、模型数、`Router.default`、`Runtime.mode`、listener、远程状态和 Registration 摘要
|
|
80
|
+
- 维护者工作台展示 role / listener / remote client connection guide,和 `/api/service-info` 的 listener / clientConnection contract 对齐
|
|
81
|
+
- 维护者工作台展示 Governance trace、metrics、Health 摘要、异常阈值、快照和归档入口
|
|
82
|
+
- Compiled Models 区展示 `Registration.models` 编译出的 model pools、active endpoint、priority endpoint 列表和 upstream warning,覆盖同模型多源池化的编译期契约
|
|
83
|
+
- `GET /api/governance/metrics` 返回 `health` 摘要和 routing `outcome` scorecard,覆盖 `idle / healthy / watch / critical`、模型切换率、切换后 alignment、Top model switches,以及 route reason / final model / semantic intent 分组 outcome
|
|
84
|
+
- `GET /api/governance/health` 返回维护者健康摘要、关键指标、模型切换 signals、routing outcome、异常列表和建议 action
|
|
85
|
+
- Health action 可联动 trace 过滤:cascade action 对应 `cascadeTriggered=true`,shadow action 对应 `shadowChecked=true`
|
|
86
|
+
- UI HTML 渲染测试覆盖 `/api/governance/health` 数据源、Health 状态占位、routing outcome 指标、分组 outcome 面板和健康摘要说明入口
|
|
87
|
+
|
|
88
|
+
### setup 主要选择路径
|
|
89
|
+
|
|
90
|
+
- 首次 fresh setup
|
|
91
|
+
- 使用 provider preset 的 fresh setup
|
|
92
|
+
- 跳过 legacy 迁移,转 fresh setup
|
|
93
|
+
- 读取 legacy 失败后转 fresh setup
|
|
94
|
+
- 当前配置可复用
|
|
95
|
+
- 当前配置放弃后重新 fresh setup
|
|
96
|
+
- 当前配置放弃后迁移 `claude-code-router`
|
|
97
|
+
- 当前配置非法后的 repair
|
|
98
|
+
- 当前配置非法后 cancel
|
|
99
|
+
- 当前配置不可解析后的 rebuild
|
|
100
|
+
- 当前配置不可解析后 cancel
|
|
101
|
+
|
|
102
|
+
### 路由功能
|
|
103
|
+
|
|
104
|
+
- SmartRouter.rules 命中后切到目标模型
|
|
105
|
+
- SmartRouter 在候选模型间做选择
|
|
106
|
+
|
|
107
|
+
### 发布前 staged 包路径
|
|
108
|
+
|
|
109
|
+
- `release:stage` 能生成 `.release-stage`
|
|
110
|
+
- wrapper 能指向隔离 `.release-home`
|
|
111
|
+
- `release:stage` 会额外生成 `.release-server-home` server profile,并通过 staged wrapper 执行 `deploy init --target server --force`
|
|
112
|
+
- npm 包随附 `config/deploy/docker-compose.server.yaml` 与 `config/deploy/systemd/claude-trigger-router.service`
|
|
113
|
+
- staged wrapper 启动后的服务能返回 `/ui` HTML 与 `GET /api/governance/health`
|
|
114
|
+
- wrapper 下可执行:
|
|
115
|
+
- `--help`
|
|
116
|
+
- `version`
|
|
117
|
+
- `upgrade`
|
|
118
|
+
- `ui`
|
|
119
|
+
- `setup`
|
|
120
|
+
- `status`
|
|
121
|
+
- `stop`
|
|
122
|
+
|
|
123
|
+
## 3. 每层重点防护目标
|
|
124
|
+
|
|
125
|
+
### `cli-e2e`
|
|
126
|
+
|
|
127
|
+
- 打包后的 npm 包真实可安装、可执行
|
|
128
|
+
- 主命令不会异常退出
|
|
129
|
+
- 命令只修改允许的隔离文件
|
|
130
|
+
- setup 与路由主流程可走通
|
|
131
|
+
|
|
132
|
+
### `cli-acceptance`
|
|
133
|
+
|
|
134
|
+
- 真实 shell / wrapper 行为与人工使用一致
|
|
135
|
+
- Windows 终端输出中不出现异常控制字符、乱码占位符、不可见污染
|
|
136
|
+
- daemon / restart / stale pid 这类“人工最容易踩坑”的状态场景可被提前拦住
|
|
137
|
+
- `release:stage` 产物本身可作为手工验收入口使用
|
|
138
|
+
- staged 包路径会直接 smoke `/ui` 和 `/api/governance/health`,避免维护者工作台只在源码测试中可用
|
|
139
|
+
|
|
140
|
+
## 4. 当前发布门禁
|
|
141
|
+
|
|
142
|
+
发布前建议至少通过:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npm run build
|
|
146
|
+
npm test -- --run
|
|
147
|
+
npm run test:e2e:cli
|
|
148
|
+
npm run test:e2e:acceptance
|
|
149
|
+
npm run release:verify
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
其中:
|
|
153
|
+
|
|
154
|
+
- `release:verify` 已包含 `test:e2e:cli`
|
|
155
|
+
- `release:verify` 已包含 `test:e2e:acceptance`
|
|
156
|
+
- `test:e2e:acceptance` 已包含 release-stage wrapper 的 `/ui` HTML 与治理健康 API smoke
|
|
157
|
+
|
|
158
|
+
## 5. 仍建议保留的人工验收重点
|
|
159
|
+
|
|
160
|
+
自动化已经尽量接近真实路径,但发布前仍建议人工快速确认:
|
|
161
|
+
|
|
162
|
+
- `ctr setup` 的输入体验是否自然,是否存在误导性文案
|
|
163
|
+
- `ctr code` 连接真实 Claude Code 时的交互是否正常
|
|
164
|
+
- `ui` 页面在真实浏览器中的打开与交互是否符合预期
|
|
165
|
+
- 维护者工作台 Health 摘要是否能根据真实 trace 显示可理解的状态和建议 action
|
|
166
|
+
- 新增配置模板和 README 的指引是否和实现一致
|
|
167
|
+
- server 部署入口生成的 bootstrap key 是否只用于维护者管理,远程客户端是否改用 managed `client + read-only` key
|
|
168
|
+
|
|
169
|
+
## 6. 后续增补原则
|
|
170
|
+
|
|
171
|
+
后续新增用户可见命令、选项、setup 分支或发布脚本行为时,优先补到这 3 层之一:
|
|
172
|
+
|
|
173
|
+
- 能只测流程编排的,补单元/集成
|
|
174
|
+
- 涉及打包后用户行为的,补 `cli-e2e`
|
|
175
|
+
- 涉及 shell、wrapper、stage、终端体验、残留状态的,补 `cli-acceptance`
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# 配置指南
|
|
2
|
+
|
|
3
|
+
这份文档只回答 4 个问题:
|
|
4
|
+
|
|
5
|
+
- 一个模型最少怎么配
|
|
6
|
+
- 路由字段应该怎么引用模型
|
|
7
|
+
- 什么时候用 `setup`,什么时候手动改配置
|
|
8
|
+
- 如果接入远程服务,`Runtime` 和 `Registration` 当前能表达什么
|
|
9
|
+
|
|
10
|
+
如果你是新用户,优先看 `README.md` 并先跑一次:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
ctr setup
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
如果你不确定自己属于哪种部署角色,先看 `docs/configuration-roles.md`。当前三条路径是:
|
|
17
|
+
|
|
18
|
+
- 本地使用者:配置 `Models + Router.default`,运行 `ctr start / ctr status / ctr code`。
|
|
19
|
+
- 服务维护者:用 `ctr deploy init --target server` 生成 server 配置,并用 admin/bootstrap key 管理服务。
|
|
20
|
+
- 远程使用者:拿到服务地址和 managed `client + read-only` key,再配置 `Runtime.remote_service` 或直接设置 Claude Code 的 `ANTHROPIC_BASE_URL`。
|
|
21
|
+
|
|
22
|
+
## 1. 推荐配置心智
|
|
23
|
+
|
|
24
|
+
当前推荐始终以 `Models` 为主。
|
|
25
|
+
|
|
26
|
+
每个 `Models[]` 项都表示一个“可直接使用的模型接入项”,路由层统一负责消息格式转换。
|
|
27
|
+
|
|
28
|
+
默认部署模式是 `Runtime.mode: local`,也就是本机运行本地代理服务。只有当你明确要连接已经存在的远程 Trigger Router 服务时,才需要配置 `Runtime.remote_service`。
|
|
29
|
+
|
|
30
|
+
最小可用示例:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
HOST: "127.0.0.1"
|
|
34
|
+
PORT: 5678
|
|
35
|
+
|
|
36
|
+
Models:
|
|
37
|
+
- id: sonnet
|
|
38
|
+
api: "https://openrouter.ai/api/v1/chat/completions"
|
|
39
|
+
key: "sk-xxx"
|
|
40
|
+
interface: "openai"
|
|
41
|
+
model: "anthropic/claude-sonnet-4"
|
|
42
|
+
thinking: "auto"
|
|
43
|
+
|
|
44
|
+
Router:
|
|
45
|
+
default: "sonnet"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
一个模型接入项当前真正的最小必填集合是:
|
|
49
|
+
|
|
50
|
+
- `id`
|
|
51
|
+
- `api`
|
|
52
|
+
- `key`
|
|
53
|
+
- `interface`
|
|
54
|
+
- `model`
|
|
55
|
+
|
|
56
|
+
可选字段:
|
|
57
|
+
|
|
58
|
+
- `thinking`
|
|
59
|
+
- `metadata.vendor_hint`
|
|
60
|
+
- `metadata.supports_reasoning`
|
|
61
|
+
- `metadata.supports_tools`
|
|
62
|
+
- `metadata.supports_images`
|
|
63
|
+
|
|
64
|
+
## 2. 部署模式与 `Runtime`
|
|
65
|
+
|
|
66
|
+
`Runtime.mode` 用来表达当前服务形态:
|
|
67
|
+
|
|
68
|
+
- `local`:默认形态,本机运行代理服务并使用本地 `Models + Router` 配置。
|
|
69
|
+
- `server`:把当前进程作为远程路由服务运行,提供 service info、remote status、registration 和 UI 等服务端入口。
|
|
70
|
+
- `cloud`:为云端/托管形态保留的配置语义;当前包不包含托管控制面或集群编排。
|
|
71
|
+
|
|
72
|
+
服务端最小形态仍然需要一份可用的本地模型配置:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
HOST: "0.0.0.0"
|
|
76
|
+
PORT: 5678
|
|
77
|
+
APIKEY: "change-me"
|
|
78
|
+
|
|
79
|
+
Runtime:
|
|
80
|
+
mode: "server"
|
|
81
|
+
|
|
82
|
+
Models:
|
|
83
|
+
- id: sonnet
|
|
84
|
+
api: "https://openrouter.ai/api/v1/chat/completions"
|
|
85
|
+
key: "sk-xxx"
|
|
86
|
+
interface: "openai"
|
|
87
|
+
model: "anthropic/claude-sonnet-4"
|
|
88
|
+
|
|
89
|
+
Router:
|
|
90
|
+
default: "sonnet"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
然后启动服务:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ctr start --daemon
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
如果配置了非本机 `HOST` 但没有配置 `APIKEY` 或 active managed key,运行时会强制回退到 `127.0.0.1`。远程客户端访问该服务时,`Runtime.remote_service.auth_token` 应填写服务端生成的 managed `client + read-only` key;bootstrap `APIKEY` 只建议维护者使用。公网部署建议放在 HTTPS 反向代理后面。启用 `APIKEY` 或 managed key 后 `/ui` 也会受认证保护;远程浏览器访问 UI 时建议使用本地隧道、内网访问,或由反向代理处理认证。
|
|
100
|
+
|
|
101
|
+
远程客户端配置是可选路径,不是默认路径。最小写法:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
Runtime:
|
|
105
|
+
mode: "local"
|
|
106
|
+
remote_service:
|
|
107
|
+
enabled: true
|
|
108
|
+
base_url: "https://router.example.com"
|
|
109
|
+
auth_token: "${CTR_REMOTE_AUTH_TOKEN}" # 远程服务端生成的 managed client + read-only key
|
|
110
|
+
|
|
111
|
+
Router: {}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
这个配置允许本机没有 `Models`,用于连接远程服务并查看远程状态摘要。当前已落地的是远程服务连接配置、状态查询和注册摘要,不要把它理解成已经有自动远端请求转发、集群节点调度或托管控制面。
|
|
115
|
+
|
|
116
|
+
相关状态接口:
|
|
117
|
+
|
|
118
|
+
- `GET /api/service-info`
|
|
119
|
+
- `GET /api/remote-status`
|
|
120
|
+
- `GET /api/registration`
|
|
121
|
+
- `GET /api/governance/health`
|
|
122
|
+
|
|
123
|
+
## 3. `interface` 怎么选
|
|
124
|
+
|
|
125
|
+
`interface` 表示目标上游协议,不是厂商名。
|
|
126
|
+
|
|
127
|
+
常见映射:
|
|
128
|
+
|
|
129
|
+
- OpenAI 官方:`openai`
|
|
130
|
+
- Anthropic 官方:`anthropic`
|
|
131
|
+
- OpenRouter:`openai`
|
|
132
|
+
- DeepSeek 兼容接口:`openai`
|
|
133
|
+
- 其他 OpenAI-compatible 服务:`openai`
|
|
134
|
+
|
|
135
|
+
当前主路径只要求你配置:
|
|
136
|
+
|
|
137
|
+
- `api`
|
|
138
|
+
- `key`
|
|
139
|
+
- `interface`
|
|
140
|
+
- `model`
|
|
141
|
+
|
|
142
|
+
请求体转换由路由统一完成,不需要你自己按供应方手写消息格式。
|
|
143
|
+
|
|
144
|
+
## 4. `thinking` 怎么理解
|
|
145
|
+
|
|
146
|
+
`thinking` 是可选增强项,不是模型接入的必填项。
|
|
147
|
+
|
|
148
|
+
推荐优先用字符串写法:
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
thinking: "auto"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
当前常用写法:
|
|
155
|
+
|
|
156
|
+
- `off`
|
|
157
|
+
- `auto`
|
|
158
|
+
- `on`
|
|
159
|
+
- `low`
|
|
160
|
+
- `medium`
|
|
161
|
+
- `high`
|
|
162
|
+
|
|
163
|
+
如果需要更细控制,仍可使用对象:
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
thinking:
|
|
167
|
+
mode: "on"
|
|
168
|
+
effort: "high"
|
|
169
|
+
budget_tokens: 2048
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## 5. 路由字段怎么引用模型
|
|
173
|
+
|
|
174
|
+
当前推荐所有路由模块都直接引用 `Models[].id`。
|
|
175
|
+
|
|
176
|
+
基础路由:
|
|
177
|
+
|
|
178
|
+
```yaml
|
|
179
|
+
Router:
|
|
180
|
+
default: "sonnet"
|
|
181
|
+
think: "reasoner"
|
|
182
|
+
longContext: "opus"
|
|
183
|
+
background: "cheap_fast"
|
|
184
|
+
webSearch: "sonnet"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
规则路由:
|
|
188
|
+
|
|
189
|
+
```yaml
|
|
190
|
+
SmartRouter:
|
|
191
|
+
enabled: true
|
|
192
|
+
analysis_scope: "last_message"
|
|
193
|
+
rules:
|
|
194
|
+
- name: "architecture"
|
|
195
|
+
priority: 90
|
|
196
|
+
enabled: true
|
|
197
|
+
patterns:
|
|
198
|
+
- type: exact
|
|
199
|
+
keywords: ["架构设计", "system design"]
|
|
200
|
+
model: "opus"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
智能兜底:
|
|
204
|
+
|
|
205
|
+
```yaml
|
|
206
|
+
SmartRouter:
|
|
207
|
+
enabled: true
|
|
208
|
+
router_model: "sonnet"
|
|
209
|
+
candidates:
|
|
210
|
+
- model: "sonnet"
|
|
211
|
+
description: "通用编程与调试"
|
|
212
|
+
- model: "reasoner"
|
|
213
|
+
description: "复杂推理"
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
治理模块:
|
|
217
|
+
|
|
218
|
+
```yaml
|
|
219
|
+
Governance:
|
|
220
|
+
enabled: true
|
|
221
|
+
cascade:
|
|
222
|
+
enabled: true
|
|
223
|
+
levels:
|
|
224
|
+
- from: "sonnet"
|
|
225
|
+
to: "opus"
|
|
226
|
+
|
|
227
|
+
shadow:
|
|
228
|
+
enabled: true
|
|
229
|
+
verifier_model: "sonnet"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 6. 什么时候用 `ctr setup`
|
|
233
|
+
|
|
234
|
+
优先用 `ctr setup` 的场景:
|
|
235
|
+
|
|
236
|
+
- 首次使用
|
|
237
|
+
- 想在本地使用、连接远程服务和部署远程服务端之间选择
|
|
238
|
+
- 不确定现有配置是否还能复用
|
|
239
|
+
- 之前用过 `claude-code-router`,希望迁移
|
|
240
|
+
- 当前配置损坏、缺字段或需要 repair / rebuild
|
|
241
|
+
|
|
242
|
+
优先手动改配置的场景:
|
|
243
|
+
|
|
244
|
+
- 你已经稳定使用当前配置
|
|
245
|
+
- 只是想新增一个模型或微调路由字段
|
|
246
|
+
- 你明确知道自己要改哪几个字段
|
|
247
|
+
|
|
248
|
+
## 7. `ctr setup` 当前会做什么
|
|
249
|
+
|
|
250
|
+
`ctr setup` 当前主线路径:
|
|
251
|
+
|
|
252
|
+
- 复用当前可用配置
|
|
253
|
+
- 迁移旧 `claude-code-router` 配置
|
|
254
|
+
- 在没有可用配置时先询问“本地使用”、“连接远程服务”或“部署为远程服务端”
|
|
255
|
+
- 本地使用时新建最小配置
|
|
256
|
+
- 连接远程服务时写入 `Runtime.remote_service`,不要求先填写本地 provider/model
|
|
257
|
+
- 部署为远程服务端时写入 `HOST: "0.0.0.0"`、bootstrap admin `APIKEY`、`Runtime.mode: "server"` 和可编辑的 `Models + Router.default` 起步模板,并且不会自动启动服务
|
|
258
|
+
- 保存后按角色输出下一步:本地路径提示本地代理状态、`ctr code` 和路由模板;远程客户端路径提示 `ctr status`、远端 ready/status 和 `ANTHROPIC_BASE_URL` / `ANTHROPIC_API_KEY`;服务端路径提示 `ctr doctor` 与 `ctr start --daemon`
|
|
259
|
+
- 在当前配置损坏时 repair / rebuild
|
|
260
|
+
|
|
261
|
+
当前对用户主流程已经补了打包态 E2E,覆盖:
|
|
262
|
+
|
|
263
|
+
- 复用
|
|
264
|
+
- 迁移
|
|
265
|
+
- 跳过迁移后新建
|
|
266
|
+
- invalid repair
|
|
267
|
+
- parse error rebuild
|
|
268
|
+
- cancel
|
|
269
|
+
|
|
270
|
+
## 8. `doctor` 和 `/ui` 怎么看服务上下文
|
|
271
|
+
|
|
272
|
+
`ctr doctor` 会先诊断本地配置和服务可启动性,然后输出当前服务上下文:
|
|
273
|
+
|
|
274
|
+
- `Runtime.mode`
|
|
275
|
+
- 当前角色:本地代理或远程路由服务
|
|
276
|
+
- 当前监听地址,以及 server/cloud 模式下远程客户端应使用的 `ANTHROPIC_BASE_URL`
|
|
277
|
+
- 当前鉴权状态、bootstrap key 和 active managed key 摘要
|
|
278
|
+
- 如果启用了 `Runtime.remote_service`,会探测远程服务是否 reachable / ready
|
|
279
|
+
|
|
280
|
+
如果远程客户端配置没有本地 `Models`,doctor 会跳过本地模型探测,不会再询问是否探测 `0` 个模型。
|
|
281
|
+
|
|
282
|
+
`ctr ui` 首屏会显示:
|
|
283
|
+
|
|
284
|
+
- 本地服务 ready 状态和端口
|
|
285
|
+
- `Runtime.mode` 与服务角色
|
|
286
|
+
- 监听地址、维护入口和远程客户端连接建议
|
|
287
|
+
- 远程服务状态摘要
|
|
288
|
+
- Registration 模型和上游服务摘要
|
|
289
|
+
|
|
290
|
+
这些信息来自现有 `/api/service-info` 和 `/api/remote-status`,不会引入新的平行运行时。
|
|
291
|
+
|
|
292
|
+
维护者工作台还会展示治理 Health 摘要。它来自 `/api/governance/health`,同样也包含在 `/api/governance/metrics` 的 `health` 字段里:
|
|
293
|
+
|
|
294
|
+
- `idle`:当前窗口没有 trace 样本
|
|
295
|
+
- `healthy`:有样本且没有治理告警
|
|
296
|
+
- `watch`:存在 warning,建议查看 anomaly 列表、trace 和近期趋势
|
|
297
|
+
- `critical`:存在 critical 告警,应优先检查级联、影子监督、延迟或上游稳定性
|
|
298
|
+
|
|
299
|
+
Health 摘要只解释已有 trace / metrics / anomaly 数据,不会改变路由行为,也不会主动修复配置。
|
|
300
|
+
|
|
301
|
+
在 `/ui` 里点击 Health action 会联动 trace 表:cascade action 自动筛选 `cascadeTriggered=true`,shadow action 自动筛选 `shadowChecked=true`,其他 action 回到当前窗口的近期 trace,便于从健康摘要直接进入排查。
|
|
302
|
+
|
|
303
|
+
## 9. `Registration` 当前支持什么
|
|
304
|
+
|
|
305
|
+
`Registration` 当前支持最小注册语义和编译期 model pool:
|
|
306
|
+
|
|
307
|
+
- `models`:可注册模型列表,字段复用 `Models[]` 的最小模型配置语义;多个相同 `id` 会编译成同一个 logical model pool。
|
|
308
|
+
- `upstream_services`:上游服务引用列表,只保存服务 ID、base URL 和可选 token。
|
|
309
|
+
- `metadata.pool_endpoint_id`:可选,给某个 pool endpoint 一个稳定 ID。
|
|
310
|
+
- `metadata.pool_priority`:可选,数值越小优先级越高;当前 pool 策略固定为 `priority`。
|
|
311
|
+
- `metadata.pool_enabled`:可选,设为 `false` 时该 endpoint 会保留在 pool 中但不会成为 active endpoint。
|
|
312
|
+
- `metadata.upstream_service_id`:可选,将 endpoint 关联到 `upstream_services[].id`,用于维护者观测和后续调度。
|
|
313
|
+
|
|
314
|
+
示例:
|
|
315
|
+
|
|
316
|
+
```yaml
|
|
317
|
+
Registration:
|
|
318
|
+
enabled: true
|
|
319
|
+
upstream_services:
|
|
320
|
+
- id: "edge-router"
|
|
321
|
+
base_url: "https://edge.example.com"
|
|
322
|
+
auth_token: "${CTR_EDGE_TOKEN}"
|
|
323
|
+
models:
|
|
324
|
+
- id: sonnet
|
|
325
|
+
api: "https://edge-a.example.com/v1"
|
|
326
|
+
key: "${EDGE_A_MODEL_KEY}"
|
|
327
|
+
interface: "anthropic"
|
|
328
|
+
model: "claude-sonnet-4-5"
|
|
329
|
+
metadata:
|
|
330
|
+
pool_endpoint_id: "sonnet-edge-a"
|
|
331
|
+
pool_priority: 10
|
|
332
|
+
upstream_service_id: "edge-router"
|
|
333
|
+
- id: sonnet
|
|
334
|
+
api: "https://edge-b.example.com/v1"
|
|
335
|
+
key: "${EDGE_B_MODEL_KEY}"
|
|
336
|
+
interface: "anthropic"
|
|
337
|
+
model: "claude-sonnet-4-5"
|
|
338
|
+
metadata:
|
|
339
|
+
pool_endpoint_id: "sonnet-edge-b"
|
|
340
|
+
pool_priority: 20
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
编译结果可以通过 `GET /api/models/compiled`、`POST /api/models/compiled/preview` 或 `/ui` 的 Compiled Models 区查看。当前阶段 pool 会把 priority active endpoint 编译成真实内部 provider;如果没有同名顶层 `Models[]` 覆盖,`Router.default: sonnet` 这类 logical model id 会解析到 active pool endpoint,并在治理 trace 中记录 `model_pool:<modelId>:<endpointId>`。运行时失败重试、health-aware routing、熔断和延迟窗口仍在后续 P2-4 中推进。
|
|
344
|
+
|
|
345
|
+
当前明确不支持 `nodes`、`node_id`、`cluster` 这类集群/节点编排字段。
|
|
346
|
+
|
|
347
|
+
## 10. capability hint 什么时候配
|
|
348
|
+
|
|
349
|
+
如果你明确知道某个模型能力受限,可以补 `metadata`:
|
|
350
|
+
|
|
351
|
+
```yaml
|
|
352
|
+
Models:
|
|
353
|
+
- id: restricted
|
|
354
|
+
api: "https://api.example.com/v1/chat/completions"
|
|
355
|
+
key: "sk-xxx"
|
|
356
|
+
interface: "openai"
|
|
357
|
+
model: "vendor/text-only"
|
|
358
|
+
metadata:
|
|
359
|
+
supports_reasoning: false
|
|
360
|
+
supports_tools: false
|
|
361
|
+
supports_images: false
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
当前行为:
|
|
365
|
+
|
|
366
|
+
- `supports_reasoning: false`:忽略 `thinking`
|
|
367
|
+
- `supports_tools: false`:工具能力退化为文本
|
|
368
|
+
- `supports_images: false`:图片输入退化为文本说明
|
|
369
|
+
|
|
370
|
+
如果你不确定,不建议一开始就配太多 capability hint,先让模型跑通主路径。
|
|
371
|
+
|
|
372
|
+
## 11. 建议的配置演进顺序
|
|
373
|
+
|
|
374
|
+
最稳的顺序是:
|
|
375
|
+
|
|
376
|
+
1. 先保证 `Models + Router.default` 可用
|
|
377
|
+
2. 再增加 `Router.think / longContext / background`
|
|
378
|
+
3. 再加 `SmartRouter.rules`
|
|
379
|
+
4. 再加 `SmartRouter.router_model / candidates`
|
|
380
|
+
5. 最后再加 `Governance` 的 cascade / shadow / observability
|
|
381
|
+
|
|
382
|
+
这样排查问题最简单,也最符合当前文档和测试覆盖的主路径。
|
|
383
|
+
|
|
384
|
+
## 12. 参考文件
|
|
385
|
+
|
|
386
|
+
- 主入口:`README.md`
|
|
387
|
+
- 最小示例:`config/trigger.example.yaml`
|
|
388
|
+
- 完整高级示例:`config/trigger.advanced.yaml`
|
|
389
|
+
- 旧配置迁移:`docs/models-migration-guide.md`
|
|
390
|
+
- 发布验证:`docs/releasing.md`
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# 配置角色总览
|
|
2
|
+
|
|
3
|
+
这份文档帮你先判断自己应该走哪条配置路径。
|
|
4
|
+
|
|
5
|
+
## 本地使用者
|
|
6
|
+
|
|
7
|
+
当 Claude Code 和 `ctr` 运行在同一台机器上时,选择这条路径。
|
|
8
|
+
|
|
9
|
+
- 从 `ctr setup` 开始。
|
|
10
|
+
- 配置 `Models + Router.default`。
|
|
11
|
+
- 运行 `ctr start` 或 `ctr start --daemon`。
|
|
12
|
+
- 用 `ctr status` 确认服务状态,然后运行 `ctr code`。
|
|
13
|
+
|
|
14
|
+
这是默认路径,也是首次使用时最稳的路径。
|
|
15
|
+
|
|
16
|
+
## 服务维护者
|
|
17
|
+
|
|
18
|
+
当你要把 `ctr` 作为共享的远程路由服务运行时,选择这条路径。
|
|
19
|
+
|
|
20
|
+
- 用 `ctr deploy init --target server` 生成 server 配置。
|
|
21
|
+
- 也可以在 fresh 环境里运行 `ctr setup` 并选择“部署为远程服务端”;setup 会生成 server profile,但不会自动启动服务。
|
|
22
|
+
- 保留 bootstrap `APIKEY` 或 admin managed key 用于维护。
|
|
23
|
+
- 给远程使用者发放 managed `client + read-only` key,不要发 admin/bootstrap key。
|
|
24
|
+
- 公网部署建议放在 HTTPS 反向代理或内网访问之后。
|
|
25
|
+
- 用 `ctr status`、`ctr doctor` 和 `ctr ui` 检查角色、监听地址、鉴权、配额和健康状态。
|
|
26
|
+
|
|
27
|
+
详细维护步骤见 `docs/server-maintainer-guide.md`。
|
|
28
|
+
|
|
29
|
+
## 远程服务使用者
|
|
30
|
+
|
|
31
|
+
当别人已经提供了一个可用的 Trigger Router 服务时,选择这条路径。
|
|
32
|
+
|
|
33
|
+
- 向服务维护者获取服务 base URL。
|
|
34
|
+
- 获取同时带 `client` 和 `read-only` scope 的 managed key。
|
|
35
|
+
- 使用 `Runtime.remote_service` 保存连接配置,并做 ready/status 检查。
|
|
36
|
+
- 如果直接让 Claude Code 连接远程服务,把 `ANTHROPIC_BASE_URL` 设置为服务地址,把 `ANTHROPIC_API_KEY` 设置为 managed key。
|
|
37
|
+
|
|
38
|
+
详细客户端步骤见 `docs/remote-client-guide.md`。
|
|
39
|
+
|
|
40
|
+
## 当前边界
|
|
41
|
+
|
|
42
|
+
`Runtime.remote_service` 当前是连接配置、ready/status 检查和注册摘要 contract。它还不表示本地 `ctr code` 会自动把所有请求转发到远程 router。首次日常使用仍建议优先走本地 `Models + Router.default` 路径,除非你已经有一个由维护者提供的远程服务。
|