@peterwangze/claude-trigger-router 1.1.1 → 1.2.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/README.md CHANGED
@@ -11,6 +11,12 @@ Claude Trigger Router 是给 Claude Code 用的本地路由代理。
11
11
  - 想在 Claude Code 外层增加配置校验、健康检查、治理观测和 UI 工作台
12
12
  - 想从 `claude-code-router` 迁移到更清晰的 `Models + Router` 配置心智
13
13
 
14
+ ## v1.2.0 发布定位
15
+
16
+ `v1.2.0` 是智能路由评测与治理增强版。它重点闭环多模型组合的可验证收益:用 `ctr eval --tasks` 固定任务契约,用 `ctr eval --run --models "sonnet;haiku"` 真实调用 CTR 跑多模型 A/B,再用 deterministic rubric 和质量维度解释不同模型在质量、速度、失败风险上的差异。
17
+
18
+ 这个版本不把 CTR 宣称为完整云端平台或完整自动裁判系统。LLM 裁判、人工校准、UI benchmark 摘要、托管级一键部署、集群编排和更复杂模型池策略仍是后续演进事项。完整发布边界见 [docs/release-notes-v1.2.0.md](docs/release-notes-v1.2.0.md)。
19
+
14
20
  ## 功能概览
15
21
 
16
22
  - **本地代理服务**:默认监听 `127.0.0.1:5678`,接管 Claude Code 上游请求。
@@ -19,8 +25,9 @@ Claude Trigger Router 是给 Claude Code 用的本地路由代理。
19
25
  - **基础路由**:用 `Router.default`、`Router.think`、`Router.longContext` 等槽位指定不同任务的默认模型。
20
26
  - **SmartRouter**:先用显式规则命中高确定性任务,也可以在规则未命中时让路由模型从候选模型中自动选择。
21
27
  - **Governance 观测**:记录 trace、metrics、异常摘要和健康状态,帮助你理解路由选择和运行风险。
22
- - **doctor 诊断**:检查配置、服务可启动性、模型兼容策略和可选模型探测。
23
- - **UI 工作台**:`ctr ui` 打开本地页面,查看服务上下文、远程状态、配置草稿、compiled models、capability warnings、治理 trace、metrics 和 Health 摘要。
28
+ - **路由评测**:`ctr eval --tasks` 查看固定任务契约,`ctr eval --input results.json` 离线评分,`ctr eval --run --models "sonnet;haiku"` 真实调用 CTR 做多模型 A/B。
29
+ - **doctor 诊断**:检查配置、服务可启动性、鉴权安全状态、模型兼容策略和可选模型探测。
30
+ - **UI 工作台**:`ctr ui` 打开本地页面,查看服务上下文、远程状态、鉴权安全状态、配置草稿、compiled models、capability warnings、治理 trace、metrics 和 Health 摘要。
24
31
  - **远程状态基础**:可配置 `Runtime.remote_service`,通过 `/api/remote-status` 查看远程服务健康、compiled model 摘要和治理告警摘要。默认用户不需要配置远程模式。
25
32
 
26
33
  ## 部署模式与边界
@@ -33,12 +40,33 @@ Claude Trigger Router 是给 Claude Code 用的本地路由代理。
33
40
 
34
41
  已落地的远程能力聚焦在“远程服务连接配置、状态查询和注册摘要”。它不会默认替代本地代理主路径,也不会自动启用尚未实现的集群、节点调度或托管控制面。
35
42
 
36
- 如果要把当前机器作为远程 `server` 暴露给其他客户端,最小配置仍然是普通的 `Models + Router.default`,再加上服务端监听和鉴权:
43
+ 如果要把当前机器作为远程 `server` 暴露给其他客户端,先生成安全默认的服务端配置:
44
+
45
+ ```bash
46
+ ctr deploy init --target server
47
+ ```
48
+
49
+ 该命令会写入 `HOST: "0.0.0.0"`、随机 bootstrap `APIKEY`、`Runtime.mode: "server"`、日志开关、健康检查所需端口和一份可编辑的 `Models + Router.default` 起步模板。它不会覆盖已有配置;如需重建模板,显式追加 `--force`。
50
+
51
+ npm 包也随附可复制部署模板:
52
+
53
+ - `config/deploy/docker-compose.server.yaml`
54
+ - `config/deploy/systemd/claude-trigger-router.service`
55
+
56
+ 角色化手册:
57
+
58
+ - 配置角色总览:[docs/configuration-roles.md](docs/configuration-roles.md)
59
+ - 服务提供者/维护者:[docs/server-maintainer-guide.md](docs/server-maintainer-guide.md)
60
+ - 远程服务使用者:[docs/remote-client-guide.md](docs/remote-client-guide.md)
61
+
62
+ 这些模板仍以 `ctr deploy init --target server` 生成的配置为起点。首次暴露给其他机器前,请先确认 `APIKEY` 或 active managed key 存在,并优先放在 HTTPS 反向代理或内网之后。
63
+
64
+ 生成后确认或调整的最小结构如下:
37
65
 
38
66
  ```yaml
39
67
  HOST: "0.0.0.0"
40
68
  PORT: 5678
41
- APIKEY: "change-me"
69
+ APIKEY: "ctr_bootstrap_..."
42
70
 
43
71
  Runtime:
44
72
  mode: "server"
@@ -57,10 +85,20 @@ Router:
57
85
  启动方式:
58
86
 
59
87
  ```bash
88
+ ctr doctor
60
89
  ctr start --daemon
61
90
  ```
62
91
 
63
- 注意:如果配置了 `HOST: "0.0.0.0"` 但没有设置 `APIKEY`,运行时会为了安全强制只监听 `127.0.0.1`。远程客户端里的 `Runtime.remote_service.auth_token` 应该填写服务端的 `APIKEY`,并建议把公网入口放在 HTTPS 反向代理之后。启用 `APIKEY` 后 `/ui` 也会受认证保护;远程浏览器访问 UI 时建议使用本地隧道、内网访问,或由反向代理处理认证。
92
+ 安全边界:
93
+
94
+ - 如果配置了 `HOST: "0.0.0.0"` 但没有设置 `APIKEY` 或 active managed key,运行时会为了安全强制只监听 `127.0.0.1`。
95
+ - `APIKEY` 定位为 bootstrap/admin key;服务端启动后用它调用 `POST /api/auth/keys` 生成给远程使用者的 managed key。
96
+ - 远程日常 token 推荐同时授予 `client + read-only`:`client` 用于模型调用,`read-only` 用于 ready/status、compiled models 和 governance 观测接口。
97
+ - `admin` key 才能访问 `/ui`、配置保存和 auth 管理。列表接口只返回 key 前后缀,secret 只在创建时返回一次。
98
+ - `operator` key 用于日常运维写操作,例如重启、治理指标快照/定时快照、异常阈值和归档删除;它不能读取配置、保存配置或管理 auth key。
99
+ - managed key 支持过期、撤销和 `quota.request_limit` / `quota.token_limit` / `quota.window_seconds`;窗口配额会持久化到本地状态文件,超限时 429 会返回 `quota.windowResetAt` 和 `Retry-After`。
100
+ - `GET /api/service-info` 会返回脱敏的 `auth` / `security` 摘要和 quota 用量;`GET /api/auth/audit` 可用 admin key 查看最近鉴权允许/拒绝记录。
101
+ - 公网入口仍建议放在 HTTPS 反向代理之后;远程浏览器访问 UI 时建议使用本地隧道、内网访问,或由反向代理处理认证。
64
102
 
65
103
  ## 安装
66
104
 
@@ -87,12 +125,13 @@ ctr setup
87
125
 
88
126
  - 复用已有 `~/.claude-trigger-router/config.yaml`
89
127
  - 探测并迁移旧 `claude-code-router` 配置
90
- - 在没有可用配置时询问“本地使用”还是“连接远程服务”
128
+ - 在没有可用配置时询问“本地使用”、“连接远程服务”还是“部署为远程服务端”
91
129
  - 本地使用时创建最小可用配置
92
130
  - 连接远程服务时写入 `Runtime.remote_service`,不要求你先填写本地 provider/model
131
+ - 部署为远程服务端时生成 server profile 和 bootstrap admin `APIKEY`,但不会自动启动服务
93
132
  - 本地使用时,引导填写默认模型 ID、接口地址、API Key 和模型名
94
133
  - 本地使用时,可选追加复杂任务模型,并生成 SmartRouter 起步模板
95
- - 保存配置后启动本地服务
134
+ - 保存配置后按角色输出下一步:本地路径提示 `ctr code` 和路由模板,远程客户端路径提示 `ctr status` / 远端 ready 检查,服务端路径提示 `ctr doctor` / `ctr start --daemon`
96
135
 
97
136
  本地使用路径完成后按这个顺序使用:
98
137
 
@@ -103,7 +142,7 @@ ctr code
103
142
 
104
143
  `ctr code` 会带着本地代理环境启动 Claude Code。之后你在 Claude Code 里的请求会经过本地 Trigger Router。
105
144
 
106
- 如果 setup 选择的是“连接远程服务”,当前主要用于生成远程服务连接配置并检查远程状态;首次日常使用仍建议先跑通本地 `Models + Router.default` 主路径。
145
+ 如果 setup 选择的是“连接远程服务”,当前主要用于生成远程服务连接配置并通过 `ctr status` 检查远端 ready 状态;日常直连远程服务时,请按服务维护者提供的 `ANTHROPIC_BASE_URL` 和 `ANTHROPIC_AUTH_TOKEN` 配置 Claude Code。首次日常使用仍建议先跑通本地 `Models + Router.default` 主路径。如果选择“部署为远程服务端”,setup 只生成配置,不会自动启动;请先编辑 `Models[].key` / `Models[].model`,再运行 `ctr doctor` 和 `ctr start --daemon`。
107
146
 
108
147
  ## 手动配置
109
148
 
@@ -264,6 +303,15 @@ Models:
264
303
  supports_reasoning: false
265
304
  supports_tools: false
266
305
  supports_images: false
306
+
307
+ - id: long_context
308
+ api: "https://api.example.com/v1/messages"
309
+ key: "sk-xxx"
310
+ interface: "anthropic"
311
+ model: "vendor/long-context"
312
+ metadata:
313
+ context_window_tokens: 200000
314
+ safe_input_tokens: 180000
267
315
  ```
268
316
 
269
317
  当前行为:
@@ -271,8 +319,10 @@ Models:
271
319
  - `supports_reasoning: false`:忽略 `thinking`
272
320
  - `supports_tools: false`:工具调用退化为文本表达
273
321
  - `supports_images: false`:图片输入退化为文本描述
322
+ - `context_window_tokens`:模型总上下文窗口;路由会用 `input + max_tokens + thinking budget` 做容量保护
323
+ - `safe_input_tokens`:建议输入上限;当前请求超过已选模型上限时,会优先切到 `Router.longContext`
274
324
 
275
- 不确定时可以先不配,等主路径跑通后再补。
325
+ 多模型上下文大小不一致时,建议给小窗口模型和长上下文模型都补上这两个字段,并配置 `Router.longContext`。不确定时可以先不配,等主路径跑通后再补;未声明上下文窗口的模型会保持原有兼容行为。
276
326
 
277
327
  ## UI 工作台
278
328
 
@@ -297,8 +347,10 @@ http://127.0.0.1:5678/ui
297
347
 
298
348
  - 本地服务 ready 状态、端口、模型数和 `Router.default`
299
349
  - `Runtime.mode` 与当前服务角色
350
+ - 当前监听地址和远程客户端接入建议
300
351
  - 远程服务状态摘要
301
352
  - Registration 模型和上游服务摘要
353
+ - Auth 与 Security 摘要,用于发现 server/cloud 或公网监听无鉴权风险
302
354
 
303
355
  维护者工作台里的 Health 摘要来自 `GET /api/governance/health`,用于快速判断近期治理状态:
304
356
 
@@ -311,6 +363,37 @@ http://127.0.0.1:5678/ui
311
363
 
312
364
  Health 摘要下方的 action 可以直接把 trace 表切到对应排查视图:cascade action 会筛选 `cascadeTriggered=true`,shadow action 会筛选 `shadowChecked=true`,其他 action 会回到近期 trace。
313
365
 
366
+ 如果你想比较不同模型组合在固定任务上的质量和速度,可以先把多模型输出整理成 JSON,再运行离线评测:
367
+
368
+ ```bash
369
+ ctr eval --tasks
370
+ ctr eval --input results.json
371
+ ctr eval --run --models "sonnet;haiku"
372
+ ```
373
+
374
+ 输入文件可以是数组,也可以是 `{ "results": [...] }`:
375
+
376
+ ```json
377
+ [
378
+ {
379
+ "taskId": "coding_fix",
380
+ "model": "provider,model",
381
+ "output": "模型输出文本",
382
+ "latencyMs": 1200
383
+ }
384
+ ]
385
+ ```
386
+
387
+ `ctr eval --tasks` 会列出固定任务的 prompt、expected output、关键词、字符数、延迟预算、质量维度和 result template;加 `--json` 可导出给后续自动执行器或外部脚本。当前内置任务覆盖 quick reply、coding、architecture、long context、server auth/deployment 和 model pool incident。评测会输出按模型和任务聚合的 pass rate、quality、speed、latency、best run、维度均分和失败 findings;它是离线 deterministic rubric,不等同于完整人工或 LLM 裁判评测。
388
+
389
+ 如果本机或远端 CTR 已启动,也可以显式自动跑固定任务集:
390
+
391
+ ```bash
392
+ ctr eval --run --models "sonnet;haiku" --base-url http://127.0.0.1:5678 --api-key <client-or-bootstrap-key>
393
+ ```
394
+
395
+ `--run` 会对每个模型逐个调用 `POST /v1/messages`,默认 `--concurrency 2`、`--timeout-ms 30000`、`--max-tokens 768`。多个模型用分号 `;` 分隔,因为 legacy 模型引用本身可能包含逗号。该模式会真实调用模型服务并消耗上游额度。
396
+
314
397
  如果服务没有启动,`ctr ui` 会提示先运行:
315
398
 
316
399
  ```bash
@@ -338,6 +421,8 @@ ctr doctor
338
421
  - 配置是否能通过本地校验
339
422
  - 服务是否可启动
340
423
  - 当前服务上下文:`local` / `server` / `cloud`
424
+ - 当前监听地址;server/cloud 会提示远程客户端应设置的 `ANTHROPIC_BASE_URL`
425
+ - 当前鉴权状态;如果 server/cloud 或公网监听没有配置 `APIKEY` / managed key,会提示安全风险
341
426
  - 如果启用了 `Runtime.remote_service`,会单独检查远程服务可达和 ready 状态
342
427
  - 模型兼容策略和请求编译方式
343
428
  - capability hint 可能触发的运行时降级
@@ -357,7 +442,7 @@ Runtime:
357
442
  remote_service:
358
443
  enabled: true
359
444
  base_url: "https://router.example.com"
360
- auth_token: "${CTR_REMOTE_AUTH_TOKEN}" # 对应远程服务端 APIKEY
445
+ auth_token: "${CTR_REMOTE_AUTH_TOKEN}" # 推荐使用远程服务端生成的 managed key;如需 ready/status 探测,同时授予 client 与 read-only scope
361
446
 
362
447
  Router: {}
363
448
  ```
@@ -374,6 +459,7 @@ GET /api/remote-status
374
459
  GET /api/service-info
375
460
  GET /api/remote-status
376
461
  GET /api/registration
462
+ GET /api/auth/audit
377
463
  ```
378
464
 
379
465
  这条能力当前作为远程接入基础 contract 提供,用于服务发现、状态检查和注册摘要;它不表示已经自动把 Claude Code 请求转发到远端。首次使用仍建议从本地 `ctr setup -> ctr start -> ctr code` 开始。
@@ -384,6 +470,7 @@ GET /api/registration
384
470
  |---|---|
385
471
  | `ctr setup` | 首次配置、复用、迁移、修复配置 |
386
472
  | `ctr init --force` | 生成最小配置模板 |
473
+ | `ctr deploy init --target server` | 生成安全默认的自托管 server 配置 |
387
474
  | `ctr start` | 前台启动本地服务 |
388
475
  | `ctr start --daemon` | 后台启动本地服务 |
389
476
  | `ctr status` | 查看服务状态 |
@@ -391,6 +478,9 @@ GET /api/registration
391
478
  | `ctr stop` | 停止服务 |
392
479
  | `ctr code` | 带 Trigger Router 环境启动 Claude Code |
393
480
  | `ctr doctor` | 配置和服务诊断 |
481
+ | `ctr eval --tasks` | 查看固定评测任务、prompt 和 rubric |
482
+ | `ctr eval --input results.json` | 离线固定任务集评测 |
483
+ | `ctr eval --run --models "sonnet;haiku"` | 自动调用 CTR 后评测固定任务集 |
394
484
  | `ctr ui` | 打开本地 UI 工作台 |
395
485
  | `ctr version` | 查看版本 |
396
486
  | `ctr upgrade` | 升级 |
@@ -0,0 +1,36 @@
1
+ # Claude Trigger Router server deployment templates
2
+
3
+ These templates are included in the npm package under `config/deploy`.
4
+
5
+ Role-specific guides live in:
6
+
7
+ - `docs/server-maintainer-guide.md`
8
+ - `docs/remote-client-guide.md`
9
+
10
+ Recommended flow:
11
+
12
+ ```bash
13
+ ctr deploy init --target server
14
+ ctr doctor
15
+ ctr start --daemon
16
+ ```
17
+
18
+ Use `docker-compose.server.yaml` when you want a minimal container profile. Prepare `./ctr-home/.claude-trigger-router/config.yaml` with `ctr deploy init --target server`, edit `Models[].key` and `Models[].model`, then run:
19
+
20
+ ```bash
21
+ docker compose -f docker-compose.server.yaml up -d
22
+ ```
23
+
24
+ Use `systemd/claude-trigger-router.service` when you want a Linux service unit. Copy it to `/etc/systemd/system/`, edit the service user and paths, prepare the service user's config, then run:
25
+
26
+ ```bash
27
+ systemctl daemon-reload
28
+ systemctl enable --now claude-trigger-router
29
+ ```
30
+
31
+ Security notes:
32
+
33
+ - Keep the generated bootstrap `APIKEY` for maintainers only.
34
+ - Generate managed `client + read-only` keys for remote clients.
35
+ - Put public deployments behind HTTPS reverse proxy or private network access.
36
+ - Use `ctr status`, `ctr doctor`, and `/ui` to confirm role, listener, auth state, and remote client connection guidance after deployment.
@@ -0,0 +1,29 @@
1
+ # Claude Trigger Router self-hosted server profile.
2
+ # Prepare ./ctr-home/.claude-trigger-router/config.yaml with:
3
+ # HOME=./ctr-home ctr deploy init --target server
4
+ #
5
+ # The config file must contain a bootstrap APIKEY or active managed key before
6
+ # exposing HOST: 0.0.0.0 to other machines.
7
+ services:
8
+ claude-trigger-router:
9
+ image: node:24-alpine
10
+ container_name: claude-trigger-router
11
+ working_dir: /srv/ctr
12
+ command: >
13
+ sh -lc "npm install -g @peterwangze/claude-trigger-router@latest
14
+ && ctr start --port 5678"
15
+ environment:
16
+ HOME: /srv/ctr
17
+ USERPROFILE: /srv/ctr
18
+ NODE_ENV: production
19
+ volumes:
20
+ - ./ctr-home:/srv/ctr
21
+ ports:
22
+ - "5678:5678"
23
+ restart: unless-stopped
24
+ healthcheck:
25
+ test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:5678/health | grep claude-trigger-router"]
26
+ interval: 30s
27
+ timeout: 5s
28
+ retries: 3
29
+ start_period: 20s
@@ -0,0 +1,33 @@
1
+ # Claude Trigger Router self-hosted server unit.
2
+ # Copy to /etc/systemd/system/claude-trigger-router.service, then edit User,
3
+ # WorkingDirectory, Environment, and ExecStart paths for your host.
4
+ #
5
+ # Prepare the service user's config first:
6
+ # sudo -u ctr env HOME=/var/lib/claude-trigger-router ctr deploy init --target server
7
+ #
8
+ # The generated config must keep APIKEY or an active managed key before
9
+ # exposing HOST: 0.0.0.0.
10
+ [Unit]
11
+ Description=Claude Trigger Router
12
+ After=network-online.target
13
+ Wants=network-online.target
14
+
15
+ [Service]
16
+ Type=simple
17
+ User=ctr
18
+ Group=ctr
19
+ WorkingDirectory=/var/lib/claude-trigger-router
20
+ Environment=HOME=/var/lib/claude-trigger-router
21
+ Environment=USERPROFILE=/var/lib/claude-trigger-router
22
+ Environment=NODE_ENV=production
23
+ ExecStart=/usr/bin/env ctr start --port 5678
24
+ Restart=on-failure
25
+ RestartSec=5
26
+ NoNewPrivileges=true
27
+ PrivateTmp=true
28
+ ProtectSystem=full
29
+ ProtectHome=false
30
+ ReadWritePaths=/var/lib/claude-trigger-router
31
+
32
+ [Install]
33
+ WantedBy=multi-user.target
@@ -25,12 +25,18 @@ Models:
25
25
  interface: "openai"
26
26
  model: "anthropic/claude-sonnet-4"
27
27
  thinking: "auto"
28
+ metadata:
29
+ context_window_tokens: 200000
30
+ safe_input_tokens: 180000
28
31
 
29
32
  - id: opus
30
33
  api: "https://openrouter.ai/api/v1/chat/completions"
31
34
  key: "sk-xxx"
32
35
  interface: "openai"
33
36
  model: "anthropic/claude-opus-4"
37
+ metadata:
38
+ context_window_tokens: 200000
39
+ safe_input_tokens: 180000
34
40
 
35
41
  - id: deepseek_reasoner
36
42
  api: "https://api.deepseek.com/chat/completions"
@@ -38,6 +44,9 @@ Models:
38
44
  interface: "openai"
39
45
  model: "deepseek-reasoner"
40
46
  thinking: "high"
47
+ metadata:
48
+ context_window_tokens: 64000
49
+ safe_input_tokens: 56000
41
50
 
42
51
  - id: ollama_qwen
43
52
  api: "http://localhost:11434/v1/chat/completions"
@@ -140,6 +149,8 @@ SmartRouter:
140
149
  session_ttl_ms: 3600000
141
150
  fingerprint_similarity_threshold: 0.82
142
151
  break_on_explicit_route: true
152
+ # Alignment 为显式开启项:Claude Code 已经携带会话上下文。
153
+ # 只有跨模型交接摘要值得额外一次调用成本时再开启。
143
154
  alignment:
144
155
  enabled: true
145
156
  summarizer_model: "sonnet"