Skip to content

znaide v1.0.4

Choose a tag to compare

@twowb twowb released this 10 Sep 07:54

znaide v1.0.4(2026-09-10)

两条线:轮次不再被硬砍(可配 + 撞上限可续跑 + 打转刹车),配置语义修订(多 provider 真正可切换)。

一、轮次预算:从"硬砍 40 轮"到"可配 + 续跑 + 刹车"

旧实现是 max_turns: 40 硬编码、撞上限即停——不总结、不续跑,长任务直接被腰斩,且没有任何配置入口。

1. 上限可配、默认抬高 —— DEFAULT_MAX_TURNS 40 → 200;新增 --max-turns <N> 与 config 的 max_turns(0 = 不限)。优先级:命令行 > config > 200。0 在引擎里映射为无限预算。

2. 撞上限不再丢任务 —— 新增 SessionEvent::RoundsExhausted,交互模式弹"继续执行"确认框(y 再放一批 / n·Esc 停在当前进度);无头模式在结果里说明"已达 N 轮"以及怎么调大(--max-turns N,0 = 不限),不再只丢一句"任务没干完就停了"。

3. "原地打转"刹车(替代靠轮数硬砍) —— 以 (工具名, 原始参数) 完全相同为签名计数:重复到 3 次在工具结果尾部插一句提醒,劝模型换方法(给一次自救机会);重复到 6 次判定"原地打转",中止本轮并点名工具与次数。换参数不触发计数,所以"挨个读 30 个文件"这类正常长任务不会被误杀。

4. 状态栏显示轮次 —— 底部状态栏新增 轮 本轮已用/上限(不限时显示 ∞),数据由引擎每轮发的 SessionEvent::RoundStarted { used, limit } 驱动,不靠 UI 估算;/config 改完上限立即反映。

二、配置面板:轮数上限成为独立一步,并带出当前配置

  • 配置向导由 4 步变 5 步:1 服务商 → 2 模型 → 3 API Key → 4 轮数上限 → 5 验证。第 4 步直接敲数字即可改(0 = 不限,留空 = 默认 200),Enter/s 验证;第 3 步按 Enter 进入该步(老习惯直接按 s 仍可跳过)。
  • 重开 /config 带出当前已配置的值:服务商/模型/端点/Key/轮数上限,并在顶部显示"当前配置"摘要行;服务商列表游标落在当前那个上;模型列表自动选中当前模型;查询失败转手输时预填当前模型名。
  • 两个细节:走 api_key_env 的 Key 不会被预填成明文(否则保存会把 Key 落进配置文件),界面标注"来自环境变量,留空即保持";重选同一个服务商不再清空已配的 Key。

三、配置语义修订(v2):多 provider 真正可切换

旧语义有个自相矛盾的死结:顶层 model/base_url 覆盖预设,而 api_key 反过来由预设优先;并且面板每次保存都写顶层三件套——于是用过一次面板后,顶层永久遮蔽所有预设,改 provider 只换 Key 不换端点/模型。

  • 面板保存改写进 provider 条目 —— save() 把 model/base_url/api_key 写进 providers[当前服务商],不再写顶层三件套,并清空顶层。此后改 "provider": "xxx"(或 --provider xxx)= 换整套(端点 + 模型 + Key)。
  • 三个字段口径统一 —— model/base_url/api_key 一律"顶层 > 预设",不再出现"新 Key 配老端点"的错配。优先级:CLI > 环境变量 > 顶层(手动覆盖)> provider 条目。
  • context_window 下沉到 provider —— 各服务商可各配各的窗口(内置表仍作最后兜底);在 40k 的 ollama 与 1M 的云端模型之间切换时,ctx 占用条不再算错。
  • 预设按字段合并 —— 内置预设做底,你在 providers 里只写要改的字段即可,不再因为写了 base_url 就顺手丢掉内置的 model/api_key_env。
  • 老配置自动迁移 —— 启动时把顶层 model/base_url/api_key/context_window 搬进当前 provider 条目并清空顶层(一次性自愈,控制台提示"检测到配置由其他版本写入,格式标记已升级")。迁移前后生效配置完全一致,有单测与真配置干跑双重验证。

顶层三件套仍可用作手动临时覆盖(优先级高于预设),只是面板不会再写它们。

验证

  • cargo test --workspace:core 100 / mock-e2e 17 / tui 80,全绿。
  • 新增覆盖:轮上限用尽的无头提示、max_turns=0 真不限(连跑 9 轮不被截断)、重复相同调用被中止(≤6 次)、RoundStarted 逐轮上报 (used, limit)、config 的字段级合并 / provider 窗口优先 / 保存写进条目 / 迁移前后生效一致 / max_turns 落盘往返。
  • 真配置干跑:迁移后顶层清空、值进 providers.deepseek,启动解析出的模型不变。
  • cargo build --release 通过,--version 输出 1.0.4。

兼容性提示

  • 老配置会被自动迁移一次(会改写 config.json,建议先备份)。
  • 顶层 context_window 现在只作兜底:建议把它挪进对应的 provider 条目(迁移会自动做)。
  • 之前依赖"预设 Key 盖过顶层 Key"的行为已统一为顶层优先(仅影响同时手写了两处 Key 的配置)。

发布后补入的修复(同一版本号替换)

以下几处在 1.0.4 首次发布后随即修复,随本版本资产一并替换(未升版本号):

  • 配置面板输入框支持粘贴 —— 此前向导一打开,粘贴就被整段丢弃,长 API Key / 端点只能手敲。现在文本输入态(API Key / 端点 / 模型名 / 轮数上限)可直接粘贴:只填入、不提交(回车才算),换行会被丢掉(单行输入);权限确认与破坏性确认弹窗(y/n)仍不接收粘贴。
  • 修掉"切回旧服务商时,面板里还是另一家的模型/Key" —— 切服务商时只更新了名字与端点,model 仍沿用上一家的,api_key 又只查环境变量而不读该条目的明文(面板保存的 Key 就存在条目里),于是切过去 Key 显示未设置、验证必然失败。现在切换会带出目标服务商自己的模型与 Key(Key 顺序:该条目明文 > 该条目的 api_key_env 环境变量 > 空);模型列表里没有当前模型时置顶保留并选中,避免"只是切回这家、回车一下模型被换成列表第一项"。另外 Key 来自环境变量时保存不会写成明文,手输明文后该标记自动清除。
  • 修掉 ctx 占用条把模型窗口算错(误报"快满了"、劝人做没必要的压缩) —— 分子没错(最近一次请求的真实 prompt_tokens),错在分母:窗口靠模型名查内置表,认不出就回默认 32768,而 deepseek-flash(不含 deepseek-v4)、qwen3.8-max(被 ollama 的 qwen3 兜底吞成 40960)这类真实模型 ID 都命中不了 → 占用条成倍虚高、变红,并弹出 ⚠ 上下文已用约 N%,可以 /compact 的提示。压缩是真的会切历史的,这条误报比显示不准更严重。现在:
    • 内置表查不到就按"未知"处理(不再拿默认值假装知道):状态栏显示 ctx ~21.4k 窗口未知,只报真实绝对量、不给百分比、不触发 90% 压缩提示,也就不会劝你做没必要的压缩;
    • 表内补齐真实 ID:deepseek-flash / deepseek-pro 归入 deepseek v4 代(1M);新增云端 qwen3-max / qwen3.8-max 档,不再被本地 qwen3 的 40k 规则吞掉;
    • /config 向导新增第 4 步「上下文窗口」(5 步 → 6 步):直接填数字即固定该窗口,留空 = 按模型名自动;模型不在表里时,这里是唯一能把它填准的地方。窗口与轮数一样按服务商各记各的(切服务商带出那家自己的值、保存写进该 provider 条目),重开面板会带出当前已配的窗口。
    • 涉及面:model_context_window() / Resolved::effective_context_window() 返回 Option,Config::save() 增加 context_window 参数(写进 provider 条目,None/0 = 清除固定值)。README.md / README.en.md / docs/使用说明.md 同步删掉"未命中默认 32k"的旧口径说明。