Repository navigation
Expand file tree
/
Copy pathconfig.example.json
More file actions
280 lines (248 loc) · 14.1 KB
/
Copy pathconfig.example.json
File metadata and controls
280 lines (248 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
{
// ==========================================================================
// multi2api 配置示例
//
// ⚠ 这个文件支持注释(`//` 与 `/* */`)。
// 程序**只改动 `api_key` 一处**(轮换管理钥匙时),其余内容逐字节保留 ——
// 所以你在这里写的注释、空行、字段顺序都不会被程序弄乱。
//
// ⚠ 「哪些上游启用」**不在这里配**:上游一律全部启用(12 个)。
// 如果你以前写过 `"enabled": false`,它会被忽略,上游照常启动。
// 要停用一个上游,把它的凭证从 auths/ 移走即可。
//
// 复制成 config.json 再改。config.json 不会被提交(见 .gitignore)。
// ==========================================================================
// ---- 基础 ----------------------------------------------------------------
// 监听地址。
// 127.0.0.1:7863 只允许本机访问(默认,最安全)
// :7863 允许局域网访问(注意:本机打开仍用 127.0.0.1)
"listen": "127.0.0.1:7863",
// 管理钥匙:控制台、/admin/*、以及不限量的 API 调用都用它。
// 在控制台「仪表盘 → API 接入信息」里可以查看/复制;用 API 管理页
// 的「轮换管理密钥」按钮可以换一把(旧钥匙立即作废)。
"api_key": "your-api-key-here",
// 管理台门禁令牌(**与上面的 api_key 互相独立**)。
//
// 为什么要有第二个钥匙:api_key 是发给**调用方**(客户端/脚本)的对话凭据。
// 改造前这一把同时是门禁 —— 于是"给客户端配一把 key"等于"交出管理台"。
// 现在:
//
// api_key → 调 /v1/* 用(给调用方)。**不能**进控制台/管理面。
// admin_token → 进 /ui 与 /admin/* 用(给你自己/脚本/CI)。
// 用法:Authorization: Bearer <admin_token>,
// 或浏览器打开 /ui?token=<admin_token>(一次性换 cookie)。
//
// 日常用**账号口令**登录即可(见下面的 "console" 段),这一把是给脚本的。
// 留空 = 不启用(那就只剩账号口令登录一条路);用 API 管理页的
// 「轮换管理令牌」按钮可以免重启换一把(旧令牌立即作废)。
//
// ⚠ 请填一段足够长的随机串。别用你的 api_key(那等于把两把钥匙并成一把,
// 正是上面说的那个问题)。
"admin_token": "your-admin-token-here",
"service_name": "multi2api",
// 凭证根目录。各上游默认用它的同名子目录(auths/workbuddy、auths/loomy …)。
"auth_dir": "./auths",
// 运行状态(账号冷却/熔断等)的落盘位置。删掉它会重置所有账号状态。
"state_file": "./data/state.json",
// ---- 出站请求 ------------------------------------------------------------
//
// 这几项都可不写(缺省值如下)。其余可选键:
//
// user_agent / client_version / cli_version / client_name
// 出站请求的头。留空即用各上游的默认值(通常不需要改)。
//
// device_token / device_token_file
// 全局限流令牌(X-Device-Token)。多数部署不需要,留空即可;
// 个别账号需要时写在那个账号的凭证文件里(优先级更高)。
//
// passthrough_ip
// 是否把调用方 IP 透传给上游(默认 false)。
"upstream": {
// 整次请求超时(秒)。上游偶尔很慢,调小会让长回答被截断。
"timeout_seconds": 120,
// 响应头超时(秒):只等"开始回话",比整体超时更早发现死连接。
"header_timeout_seconds": 120,
// 空闲超时(秒):流式回答时"两段之间"允许的最大停顿。
"idle_timeout_seconds": 300
},
// ---- 账号池 --------------------------------------------------------------
"pool": {
// 同一账号的并发上限。上游对单账号并发敏感(有的只有 3 个会话槽),
// 调大会把"并发请求"变成"账号被限流"。
"max_in_flight": 3,
// 熔断:连续失败几次后冷却多久(指数退避,上限 cooldown_max)。
"breaker_threshold": 3,
"breaker_cooldown": "30m",
"breaker_cooldown_max": "6h",
// 权重里的"闲置加分":闲置越久的账号越容易被选中,避免总是同一批。
"idle_weight_per_hour": 0.5,
"idle_weight_max": 5.0,
// 主动健康检查间隔(秒):探测冷却/熔断中的账号,提前恢复。
// 0 = 关闭(不推荐:关闭后只能等冷却自然到期)。
"health_check_interval_seconds": 600,
// 解封探测间隔(秒):给**被自动禁用**的账号定时发一个便宜请求(模型目录/
// 额度等,不消耗对话额度)探活,通了即解除禁用。
// ⚠ 它与上面那条是**两个量级**的节奏,别合成一个:
// 健康检查 600s(分钟级)—— 冷却是"歇一会儿"(30 分钟量级就回来)
// 解封探测 86400s(天级) —— 被风控/连败禁掉的号,恢复要等天
// 用 10 分钟的节奏去探被禁的号 = 每 10 分钟白打一次上游,既浪费又会在
// 对方风控日志里留下"这个号在反复试"的痕迹。
// 0 = 关闭(被禁的号只能人工恢复)。默认 86400(24 小时)。
// 人工禁用、或凭证死亡导致的禁用不会被探测翻案(那是操作员的明确决定)。
"revive_probe_interval_seconds": 86400
},
// 软限流:上游"没报错但明显在限速"时,让该账号短暂退避。
"cooldown": {
"soft_rate": "60s",
"soft_rate_max": "2h"
},
// 会话粘性:同一会话尽量落在同一账号上(否则多账号轮转会把对话拆散)。
// 对无状态调用方(每次新会话)没有影响。
"session_sticky": {
"enabled": true,
"ttl": "30m",
"gc_interval": "5m"
},
// ---- 调度 ----------------------------------------------------------------
"schedule": {
// 每日签到(各上游统一为 30 分钟被动扫描,这里只给「允许执行的时段」)。
// 小时取本机时区。留空数组 = 不跑。
"checkin_enabled": true,
"checkin_hours": [9, 21],
// Token 保活。凭证快过期时提前续期,避免"空闲两小时后第一个请求慢一拍"。
"keepalive_enabled": true,
"keepalive_hours": [22],
// 活跃上报(成长中心用)。开关默认开,但时点默认空 = 不跑。
"activity_enabled": true,
"activity_hours": [10]
},
// ---- 控制台与服务 --------------------------------------------------------
"server": {
// 请求体上限(MB)。长上下文对话可能很大,太小会 413。
"max_body_mb": 8
},
"login": {
// 「添加账号」时自动用无痕窗口打开授权页(独立 profile,避免串号)。
// 关掉后仍可用「复制链接」手动打开。
"open_browser": true,
"browser": "",
"isolated": true
},
"features": {
// 出站请求的指纹脱敏(去掉本机特征)。关掉会让上游更容易识别成非客户端。
"sanitize_blacklist_fingerprints": true
},
// ---- 控制台账号体系(单账号管理员 / 反批量)------------------------------
//
// # 首次登录怎么做(三步)
//
// ① 启动程序,浏览器打开 http://127.0.0.1:7863/ui
// ② 因为是空库,页面会让你**创建管理员**:填用户名 + 口令(8–128 位)。
// 这一步建出来的是唯一的那个账号(管理员,角色 10),只可能成功一次。
// ③ 之后再打开 /ui 就是登录页;用刚建的那个账号登录。
//
// ⚠ **这个部署只有一个账号,就是 ② 建出来的那个管理员。**
// 成员(角色 1)这个角色已经**取消**,不是"暂时关掉注册":
//
// · 建号只剩一条路(空库时的那次首启),服务端写死管理员角色;
// · 账号库非空之后 POST /admin/auth/register **整体关闭**:
// 403 + 稳定码 register_closed(文案请用管理员账号登录);
// 请求体里塞 role 之类字段在**解码层**就被拒(400 bad_request)。
// · 改造前留在盘上的非管理员记录:加载不崩 + 启动日志点名,
// 登录回 401 member_retired(文案「成员账号已取消,请用管理员账号登录」),
// 旧会话在 SessionStore.Lookup 就被拒并撤销。
//
// 想换口令用控制台顶栏的「改密码」;真忘了口令就备份后删掉
// data/accounts.json 重来(等于重新首启)。
//
// 账号与口令**不在这个文件里**:它们落在 data/accounts.json(bcrypt 哈希,
// 明文口令不落盘),会话落在 data/sessions.json。
// ⚠ 所以这里**没有** `admin_password` 这种字段 —— 有的话就等于一条绕过
// "首个账号建管理员"流程的明文后门,而且会让"改口令"同时有两个事实来源。
// 改口令在控制台顶栏点「改密码」(改完当前浏览器不掉线,其它设备失效)。
//
// ⚠ 若把这个端口映射到公网:**空库时的首启**就是"陌生人在你机器上建账号"的
// 入口,而建出来那个账号还是管理员。下面这四层默认全开(三层就够用,
// 真嫌烦再逐条关),并且建议**先在本机把管理员建好**再映射出去 ——
// 库非空之后那个端点就是 403 register_closed,没有可打的入口。
"console": {
// ⚠ 本版本**已不改变行为**(键保留,只为兼容旧配置文件;启动日志会如实
// 说明,不静默忽略)。它原先是"关闭公开注册"的开关,而单账号口径下
// "能不能建号"只有一个答案 —— 账号库空不空,也就是注册入口是否开放:
// 空库 ⇒ 允许建那一个管理员;非空 ⇒ 403 register_closed。
// 改造前这里是两个来源(一个读配置、一个查库),必然有一天互相矛盾:
// 配置说"开"、库里已有账号 ⇒ 页面给出一个点了必然 403 的入口。
"disables_register": false,
// 关闭登录/注册的人机校验(缺省 false = **开启**)。
// ⚠ 三重否定:`false` ⇒ 人机校验开着。想关就写 `true`。
// 关掉之后剩下的三层仍在,不是"关了验证码就全没了"。
"disable_captcha": false,
// 注册/登录的限速额度(次 / 窗口),缺省 20 次 / 1200 秒(20 分钟)。
// ⚠ 写 0 或负数 = 用缺省值,**不是**"不限速"(不提供"配一下就敞门"的开关)。
"auth_rate_limit": 20,
"auth_rate_window_seconds": 1200,
// 会话 Cookie 的 Secure 策略:auto(缺省)/ always / never。
// auto 请求本身走 TLS 时加 Secure
// always 一律加 —— **反代/隧道场景用这个**(浏览器看到的是 https,
// 但请求到达本进程时已是明文,auto 判不出来)
// never 一律不加(本机 http 调试)
"session_cookie_secure": "auto"
},
"prompt": {
// 系统提示词模式:custom = 用内置默认(改这里通常没必要)。
"mode": "custom",
"file": ""
},
// ---- 上游专项(可选)----------------------------------------------------
//
// 每个上游的段**全部可以省略** —— 缺省值就是你要的样子,且上游一律启用。
// 只有需要覆盖时才写进来。凭证目录缺省是 auths/<上游名>。
//
// 可写的内容(示例,按需打开):
//
// "codearts": { "auth_dir": "./auths/codearts",
// "refresh_interval_seconds": 60 }
// "workbuddy_intl": { "auth_dir": "./auths/workbuddy-intl",
// "oauth_base_url": "https://www.workbuddy.ai" }
// "loomy": { "auth_dir": "./auths/loomy",
// "base_url": "https://loomyad.xunfei.cn/api/v1",
// "login_mode": "sms" }
// "trae": { "auth_dir": "./auths/trae",
// "refresh_interval_seconds": 1800,
// "oauth_callback_port": "18080" }
// "cline": { "auth_dir": "./auths/cline" }
// "raccoon": { "auth_dir": "./auths/raccoon" }
// "lobsterai": { "auth_dir": "./auths/lobsterai" }
// "qoder": { "auth_dir": "./auths/qoder", "cn_enabled": true }
// "zcode": { "auth_dir": "./auths/zcode", "jwt_captcha": false }
// "minimax": { "auth_dir": "./auths/minimax",
// "account_base": "",
// "api_base": "" }
// // MonkeyCode(长亭科技)—— 唯一需要**请求签名**的上游。
// //
// // 模型网关要 X-OhMyAgent-Signature:
// // v1=HMAC-SHA256(signing_secret, instructions)
// // 签名对象是请求里的静态提示词(Responses 的 instructions /
// // Anthropic 的 system),与 input/tools/model 全都无关。
// // 推导过程见 docs/reports/monkeycode/monkeycode-client-reverse.md。
// //
// // ⚠ 两站的网络前提**相反**:
// // 国内站必须**直连**(走代理会 EOF,表现为「账号不健康」)
// // 国际站必须**走代理**(否则连不上)
// // 所以 proxy 只作用于国际站,国内站恒直连。
// //
// // 凭证三把:session / api_key / signing_secret
// // 后两把用 session 调 POST /api/v1/users/ohmyagent/api-keys 换取
// // (可无限重签;管理端点 /admin/monkeycode/issue-key 可代办)。
// "monkeycode": { "auth_dir": "./auths/monkeycode",
// "proxy": "http://127.0.0.1:10808",
// "pool_accounts": true }
// ---- 跨实例共享会话状态(可选)------------------------------------------
//
// 多实例部署才需要 —— 让几个网关实例共享会话粘性状态。
// 单实例部署**留空即可**(默认走进程内存)。
"upstash": {
"url": "",
"token": ""
}
}