Skip to content

znaide v1.0.8

Choose a tag to compare

@twowb twowb released this 29 Sep 02:11

znaide v1.0.8(2026-09-29)

这一版是"网络环境"相关:给所有联网出口加了一个统一的代理开关,给模型调用加了弱网重试;
另修一个可能把配置文件读坏后整份写空的问题。

一、新增:代理统一出口

以前:模型请求、网页抓取、更新下载三处各建各的 HTTP 客户端,只有更新那处看了环境变量
—— 而且是手写的探测,地址写错时会静默跳过(等于"代理配错了就悄悄直连",最难排查的一种)。
也没有"一次配好、所有出口都走它"的入口,只能靠每个进程自己 export。

现在:配置文件顶层一个 proxy,三档 —— 跟随环境变量(默认,与旧版一致)/ 强制直连 /
手动指定地址,三处出口统一走这一份;命令行 --proxy <URL>、--no-proxy 当次生效、不写盘。

  • 优先级:命令行 > ZNAIDE_PROXY/ZNAIDE_NO_PROXY > 配置文件 > 标准环境变量;
    标准环境变量只在"跟随环境变量"档生效 —— 配置文件里显式写了直连,就不会被 shell 里残留的
    HTTPS_PROXY 盖掉(否则"我明明配了直连排查,怎么还在走代理"没法查)。
  • 手动档仍尊重 NO_PROXY:"国内服务商直连、国外走代理"直接配就行。
  • 档位或地址写错不会让程序起不来:回落默认档并提示一句。
  • 连接失败时的报错会带上当前生效的代理(用户名密码脱敏),从此能分清"代理没起"和"端点不对"。

二、新增:弱网重试

以前:一次 429、一个 5xx、连接抖一下,整个回合就失败了,只能手动重发;偶发的空回复一样。

现在:--retry N / 配置里的 retry,对一次模型调用重发(空回复 / 429 / 500 / 502 /
503 / 504 / 连接中断与超时),800ms 起指数退避、单次封顶 8s。默认关闭,不传就是旧行为。

  • 只重试这一次调用:不会重复执行工具(有副作用的命令只跑一次),不占轮数预算,
    失败那次的输出既不写历史也不计 token。
  • 退避期间按 Esc 照样中断这一回合。
  • 界面上会把失败那次已经吐出来的半截正文撤掉,换成一条 ↻ 弱网重试 1/3(原因) 的提示
    —— 不撤的话会拼成"半截 + 完整"两段。
  • --no-retry 可临时关掉;次数上限 0..=8。

三、修:一份读不懂的配置不再被整份写空

场景:保存配置是"读全量 → 改一项 → 整份写回",而读取失败时会退化成默认值;写盘又是
"先截断再写"。于是同一份 config.json 被两个实例或编辑器同时动过时,可能读到半截文件 →
把一份近乎空的配置写回去 → provider 条目、Key、人格、轮数全部丢失(不可逆)。

现在:写盘改成"同目录临时文件 + fsync + rename"的原子替换 —— 读者只会看到完整的旧文件
或完整的新文件;所有"读全量只为写回"的入口在读不懂时拒绝保存并给出可读的报错,
不再退化成默认值。

四、验证

  • 测试 245 项全绿(core 119 / 端到端 19 + 5 + 6 / tui 96),编译零警告。
  • 代理:用一个"记账"假代理验证请求到底走了哪条出口(手动档经过它、直连档无视环境变量、
    默认档跟随环境变量、网页抓取与更新客户端同一个出口);真机验过死端口 / 非法地址 / 档位写错 /
    --no-proxy / 环境变量跟随等情形,并确认没配代理时配置里不会多出这个键。
  • 重试:脚本化假端点验证真实请求次数(500 后成功 = 2 次、400 = 1 次、空回复会重试、
    重试用尽 = 1+N 次);真机上默认一次请求即失败,--retry 2 发两次拿到回复且 token 只记一次。
  • 配置加固:损坏的 config.json 下保存被拒且原文件一字未动;正常保存后目录里无临时文件残留。

五、说明

  • 已有 v1.0.7 的:输入 /update 或跑 znaide --update 升级到 1.0.8。
  • 默认行为不变:不配代理、不开重试 = 与 1.0.7 一致;配置文件无需迁移(不设置就不会写入这两个键)。
  • 这一版的三个方向来自一位外部贡献者提的 PR。我们采用其需求、按自己的分层重新实现,
    未合并其代码。