Skip to content

v0.10.1

Latest

Choose a tag to compare

@RobbsLuo RobbsLuo released this 30 Oct 17:21
· 13 commits to main since this release

v0.10.1:备份/恢复与批量导入、月度账单与飞书/Slack 告警、用户级策略收口 Playground,外加单实例锁与出口粘性。SCHEMA_VERSION 29 → 30(users 补 allowed_models / quota,幂等补列),升级必须重启后端。

v0.10.0 之后的 46 个提交。按维护期口径发 patch,但含新端点与新能力。

新增能力

  • 备份 / 恢复管理(端点 + 管理台 /backups 页):下载只认 backups/ 内的普通 *.sqlite3,拒绝路径分隔符与符号链接;运维脚本写库前自动备份,只留最近 5 份。
  • 批量凭证导入(POST /api/credentials/batch-import):一次 ≤100 条,逐条校验并隔离失败,返回带 index 的 created / skipped / failed;同渠道解密后内容完全一致去重。前端支持 JSON 数组 / JSONL / 选文件,失败行回填 JSONL 重试。
  • 月度账单(GET /api/billing,operator):按人读小时汇总、按 Key 读明细并补归属用户与 Key 名;json / csv(带 BOM)/ jsonl(逐条明细),两种导出都写 ACTION_DATA_EXPORT 审计。
  • 三类新告警:预算分层(ALERT_BUDGET_CNY / ALERT_BUDGET_LEVELS,按本地自然月可定价成本打 50/80/95/100% 档,只报当前最高档,升级时旧档由迟滞状态机写成已恢复,100% 为 critical)、单 Key 用量暴涨、非工作时段请求(后两者默认阈值 0 = 关闭)。
  • 告警出口扩到飞书 / Slack:飞书按 msg_type=text、Slack 按 {text} 组包,多渠道并发,单个失败不影响其它渠道。
  • 用户级策略(SCHEMA_VERSION 30):users 新增 allowed_models / quota,空串 = 不限制。会话 Cookie 只回答「你是谁」,不回答「你能用哪些模型、一天用多少」——viewer 用 Playground 直调任意模型可整体绕过 Key 的模型白名单与配额,现 Playground 与 /v1 共用同一套校验,配额按 username 聚合(Playground 的 api_key_id 为 NULL 也计入)。用户管理页可直接编辑,写操作落 ACTION_USER_POLICY 审计。
  • 全局 kill switch(gateway_paused,热更):所有 Key 鉴权的 /v1 立即 503,管理面保留;开与关两个方向都落审计,原因只进日志不回显。
  • 凭证出口池(CREDENTIAL_PROXY_POOL):按 sha256(credential_id) 取模分配,重启不漂移;LazyClients 按(流/短,代理)分池,因为 httpx 的代理是连接池级参数。优先级:凭证池 → PROVIDER_PROXIES[渠道] → 直连;未配池时行为逐字节不变。
  • 冷却到期半开探测:到期先进 HALF_OPEN,只放行 1 个探测请求,成功才全量回池。
  • Zen 门禁配置化 + 渠道 ToS 风险登记:ZEN_USER_AGENT / ZEN_API_ROOT / ZEN_GATE_TOOLS 全部可配,默认值保持实测通过的形态;ToS 按 green / gray / red 登记理由,导入凭证响应与列表透出、审计写等级,新增渠道漏登记启动即失败。

引擎与兼容层

  • DSML 回读:DeepSeek V3.2/V4 偶发把工具调用写成 DSML 文本,解析单/双竖线两种方言、V4「自闭合 invoke 带 string」与缺外层包装的裸 invoke 块;流式增量过滤,普通正文零缓冲、跨 chunk 分片不断、未闭合标记收尾原样放行。回读出调用时 finish_reason 由 stop 改写为 tool_calls(否则客户端不执行),tool_calls 缺 id 按 index 补并记忆。
  • 坏参数 fail-closed:非流式下坏 arguments 判 InvalidToolArguments(kind=INVALID) → 换上游重试、最终 400,不冷却凭证、不把坏 JSON 递给客户端。
  • 用量对账:成功请求正文体量与上报 output_tokens 明显不符时 WARNING(上游吞 usage / 静默替换模型的间接信号),只告警不改响应。
  • 截断流留痕:error_type=truncated_stream,凭证照常 save_success(上游没报错);档位降级与 tool 输出压缩(默认关,不破坏前缀缓存);上游 model 观测,Qoder 回 auto 视为占位名忽略。
  • 会话粘性接受 session_id 请求体键。
  • TRAE 从元数据帧补回真实模型名;CodeBuddy 国际站指纹对齐官方 CLI、11158 归 model_not_found、探活结果落盘。

信道判死语义修正

  • 11140 账号受限不再永久禁用:新增 ErrKind.RESTRICTED,先于 DEAD 判定,落 2h 冷却(采用上游 Retry-After,夹 24h),当前请求跳该渠道其余凭证继续试其它渠道;窗口内(10 分钟)第二次命中升级为渠道级 24h 暂停,只冷却不禁用。统计新增 account_restricted(前端「账号被上游限制」)。保留 DEAD + disabled_reason:真 session 失效仍按原语义硬禁用。
  • 硬禁用写入可操作原因:ErrorOutcome 新增 disabled_reason,CodeBuddy 11140 写受控文案「账号存在异常行为,已被限制使用」,不再一律 session dead——重登无效,只能申诉或换号。
  • 探活判死即隐藏、复探恢复:判死隐藏不再要求「同时仍挂 blocked 负缓存」,人工「立即探活」判死时也会隐藏;failed_rows() 每轮把判死行一起复探,用上游原名;恢复入口收敛为「复探成功」。
  • Qoder 流内信封与 HTTP 错误同一判据:classify_error_code 增加 401/403 分支,有会话失效标记 → DEAD,否则 → QUEUE/RESTRICTED,403 不再一律判死。

运维

  • 单实例锁:SQLite 允许多进程并发写(WAL + 忙等),起两个实例不报错只会安静互相覆盖——同一凭证被探两次、同一小时汇总写两遍。src/instance_lock.py 对 DATA_DIR 取 flock,run() 在 build_app 之前调用(后者会建库/迁移/应用待恢复备份)。锁文件常驻不删,进程被 SIGKILL 时内核自动释放。取锁失败以退出码 0 返回并打印持有者 PID:launchd KeepAlive.SuccessfulExit=false、systemd Restart=on-failure、compose restart 都只在非零退出时重拉,非零会变回崩溃循环。launchd 改条件 KeepAlive,systemd ExecStart 从 uvicorn CLI 改为 src.main(否则绕过锁),TimeoutStopSec 与 launchd ExitTimeOut 补到 95s。
  • 日志轮转改截断式 + scripts/rotate-logs.sh(拷贝 → 压缩成功 → 截断,任一步失败都不动原文件);去掉 BSD 专用 stat,Linux CI 才能真跑;tool 输出压缩日志降 DEBUG。

前端

全局错误边界(顶层兜住登录/路由/chunk 失败,Layout 内再兜一层保留侧栏)+ 首启向导;任务与配置两级 tab、配置分组细化;明细表排序改列头下拉,渠道/凭证合并一列;额度包明细只展示剩余 > 0 的包;模型趋势 Y 轴上限取全部在画线的公共最大值;告警规则数量与文案对齐七类。

文档

新增四张图(请求主链路 / 账号流 / 数据模型 / 权限矩阵);33 篇 md 逐篇对照 src/、web/src/、scripts/、compose 校正:schema 30、表清单 13 张(补 model_probes)、可热更配置 77 项、管理台 15 页、告警七类。

升级

SCHEMA_VERSION 29 → 30:users 补 allowed_models / quota(默认 '' = 不限制,老库幂等补列,补列后 Playground 行为与补列前一致)。升级必须重启后端。