Repository navigation
znaide v1.0.8
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。我们采用其需求、按自己的分层重新实现,
未合并其代码。