Skip to content

Releases: Walvez/dsh-search-failover

v0.3.23 — reset 零写入 + 写回不再有空字符串噪音

Choose a tag to compare

@Walvez Walvez released this 21 Oct 06:03

dsh-search-failover 0.3.23 — three real-host fixes on top of 0.3.22

0.3.22 made the search-pool settings page work again on DSH 0.2.1. Rolling it out on a real
profile surfaced three more defects, all fixed here.

Fixed

  1. "Restore inline config" wrote apiKey: "" / apiKeyEnv: "" / baseURL: "" back into the
    profile document for every backend that never had them (reproduced: 7 backends × 3 empty
    fields). The save path was already cleaned; the reset path now goes through the same
    cleanBackend().
  2. Clicking reset when nothing had changed still rewrote the entry, and DSH re-serialises the
    node it edits — losing the hand-written comments and the compact - { id: … } style in the
    profile document. Reset now compares the live values with the apply-time snapshot
    (defaults filled, keys sorted, empty strings ignored) and performs zero writes when they
    already match. The panel says "当前已是行内配置,未改写文档" in that case.
  3. cleanBackend lived in lib/routes.js and was therefore invisible to the reset path; it now
    lives in lib/settings-host.js and is shared.

Verification (isolated instance, real web-profile document)

  • Reset on an untouched document: cordis.patch.yml hash unchanged.
  • Switch strategy to rotate → save: strategy updated, 7 backends, 6 apiKeyEnv kept, zero empty
    fields.
  • Reset afterwards: back to failover, 7 backends, no empty fields, apiKeyEnv intact.
  • npm test: 90/90.

🇨🇳 中文说明

0.3.22 让搜索池设置页在 DSH 0.2.1 上重新可用;在真实 profile 上跑起来后又暴露了三个问题,
本次一并修掉。

修复

  1. 「恢复行内配置」会把 apiKey: "" / apiKeyEnv: "" / baseURL: "" 写回 profile 文档里
    本来没有这些字段的后端(实测 7 个后端 × 3 个空字段)。保存路径原本已清洗,重置路径现在
    也走同一个 cleanBackend()。
  2. 什么都没改时点重置,仍会重写该 entry,而 DSH 会对被编辑的节点重新序列化 —— 手写注释和
    紧凑的 - { id: … } 写法就此丢失。现在重置先和启动快照比对(补默认值、键排序、忽略空
    字符串),相等时零写入,面板提示「当前已是行内配置,未改写文档」。
  3. cleanBackend 原来在 lib/routes.js 里,重置路径用不到;已移到 lib/settings-host.js
    共用。

验证(隔离实例,使用真实 web profile 文档)

  • 未改动状态下重置:cordis.patch.yml 哈希不变。
  • 策略改 rotate → 保存:strategy 更新、7 个后端、6 条 apiKeyEnv 保留、零空字段。
  • 再点重置:回到 failover、7 个后端、无空字段、apiKeyEnv 完整。
  • npm test:90/90。

v0.3.22 — DSH 0.2.1 settings-API compatibility / 适配 0.2.1 设置 API

Choose a tag to compare

@Walvez Walvez released this 21 Oct 05:27

dsh-search-failover 0.3.22 — DSH 0.2.1 settings-API compatibility (search pool settings page works again)

DSH 0.2.1-rc.2 removed the dsh-settings register() namespace API. Until now the search
pool settings page silently degraded: the host logged
[search-pool] settings register failed: sctx.settings.register is not a function and the
panel could not persist anything.

What changed

  • lib/settings-host.js rewritten as a two-generation adapter: describe()/mutate() (0.2.1,
    Config volatile fields + path ops) with the 0.2.0 register()/scope path kept as fallback,
    and a read-only inline-config mode when neither exists. The public shape stays
    source()-callable, so existing call sites keep working.
  • lib/index.js now exports Config = SearchPoolSettings (0.2.1 derives the settings page from
    entry.fiber.runtime.Config), reads live values through the Config refs, and disables the
    auto-generated generic form via settings.configure({ auto: false }) because the plugin ships
    its own panel.
  • lib/routes.js writes through the new store (update()/reset()) and reads only
    store.raw() — the entry's declared values, not the env-resolved ones.

Bugs found and fixed while porting

  1. "Reset to inline config" used unset, which on 0.2.1 also deletes the inline backends
    written by hand in the profile patch document (reproduced: 7 backends vanished). It now writes
    the apply-time snapshot back explicitly, and refuses when no snapshot is available.
  2. describe() strips role('secret') fields to placeholders — key reading goes through Config
    refs instead.
  3. The write path read the merged live config, whose apiKey values are already resolved from
    .env; one save would have written every plaintext key into the git-tracked profile document.
    It now reads store.raw() only.
  4. normalizeConfig() rebuilt backends from a fixed field list and dropped apiKeyEnv, so any
    save made the .env keys stop resolving on the next boot. Unknown fields are preserved.
  5. Empty-string fields (apiKey: "", apiKeyEnv: "") are no longer written back into the document.

Tests: 87/87 (node --test), including new test/settings-host.test.js and test/routes.test.js
plus the 0.3.16 abort-not-a-circuit-failure case.

Upgrade: dsh plugin --profile web add dsh-search-failover@0.3.22 (peer @deepseek-ai/schemastery
is now ^3.18.5, which ships .volatile()).


🇨🇳 中文说明

DSH 0.2.1-rc.2 删掉了 dsh-settings 的 register() 命名空间 API,搜索池设置页从那时起一直
静默降级:宿主只打印 [search-pool] settings register failed: sctx.settings.register is not a function,面板存不了任何东西。

改动

  • lib/settings-host.js 重写为两代适配层:0.2.1 走 describe()/mutate()(Config 的 volatile
    字段 + 路径操作),0.2.0 的 register()/scope 分支保留,两者都没有时降级为只读行内配置。
    对外仍是可调用的 source(),老调用点不用改。
  • lib/index.js 导出 Config = SearchPoolSettings(0.2.1 靠 entry.fiber.runtime.Config 生成
    设置页),通过 Config 引用读实时值;插件自带面板,所以用 settings.configure({ auto: false })
    关掉自动生成的通用表单。
  • lib/routes.js 写入走新 store(update()/reset()),读值只用 store.raw()(入口声明值,
    不是被 env 解析后的值)。

移植过程中发现并修掉的坑

  1. 「恢复行内配置」原用 unset,在 0.2.1 下会连 profile 补丁文档里手写的 backends 一起删掉
    (实测 7 个后端消失)。现在改为把 apply 时的快照显式写回,取不到快照时直接报错。
  2. describe() 会把 role('secret') 字段剥成占位符 —— 读 key 改走 Config 引用。
  3. 写路径原先读「合并后的生效配置」,那里的 apiKey 已被 .env 解析成明文,保存一次就会把
    所有明文 key 写进 git 跟踪的 profile 文档。现在只读 store.raw()。
  4. normalizeConfig() 按固定字段重建 backend,把 apiKeyEnv 抹掉了 —— 保存一次,下次启动
    .env 里的 key 全部失效。现在保留未声明字段。
  5. 写回文档时不再刷入 apiKey: "" / apiKeyEnv: "" 这类空字符串。

测试 87/87(node --test),新增 test/settings-host.test.js、test/routes.test.js,并回补
0.3.16 的 abort 不计熔断用例。

升级:dsh plugin --profile web add dsh-search-failover@0.3.22(peer @deepseek-ai/schemastery
现在是 ^3.18.5,才有 .volatile())。