Skip to content

Releases: Imzl-zl/dsh-models-router

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 15:22

失败默认就动,截断默认续跑。

修复

  • 只要失败就换候选,不再要求"这个错误码我勾过"。 此前八个错误码里有两个默认关着
    (空回复、请求被拒绝),而且表外的一切错误码插件永远不接管;DSH 的 llm-retry
    也只重试它自己那五个码——两层都不管,一轮对话直接死在那儿。实测:网关返回
    402 "Upstream request failed: Endpoint is unavailable."(报文里带
    "type":"invalid_request_error"),pi-ai 适配器按文案把它归成 INVALID_REQUEST,
    链上明明还有候选,一次都没试。
  • 新增「其他 / 未分类错误」开关(switchOn.other):覆盖上表之外的一切码。它永远
    先交给 DSH 自己的恢复插件(压缩历史、图片卸载等),它们放弃后才换候选。
  • 输出被截断(达到输出 token 上限)时自动续跑:以前 DSH 直接结束本轮,只在界面上
    提示你自己发"继续"。现在自动补一句"继续",同一个候选最多续
    maxTokens.continues 次(默认 2);续满还截断就换下一条候选接着写,不会停在一条
    写不完的候选上。
  • 取消(ABORTED)与无适配器(NO_ADAPTER)仍然不切换:这两种情况没有"切换"这个
    动作可言。
  • 默认重试次数从 0 改成 5:原来默认"一次失败就换下一条",等于插件接管重试之后
    反而比 DSH 自己更不耐心(DSH 的 provider 策略默认重试 5 次)。现在开箱行为就是你
    说的那句:选中的模型先自己重试,重试还不行才按链路切,每一条候选都用自己的重试预算。

变更

  • 旧的失败策略一次性升级:没有策略版本标记的配置按新默认读取。旧配置里
    「空回复 / 请求被拒绝」那两个 false、以及重试次数的 0,都是当时的默认值、不是你的
    选择,所以会被改写成新默认(全切 + 5 次重试);第一次保存后带版本标记落盘,之后你自己
    取消的勾选和你填的次数(包括刻意填 0 = 失败即切)都不会再被覆盖。
  • 链路页「故障转移触发策略」网格多一行「其他 / 未分类错误」;「重试与轮次」分区多一组
    「输出被截断时」的开关与次数。

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 10:25

右上角那个「更新日志」按钮改成「检查更新」。

新增

  • 一个按钮回答两件事:有没有新版本,新版本改了什么。 点开先查 npm registry 上的
    最新已发布版本,再拉那个版本的 GitHub Release 说明;已是最新时,下面仍然显示当前
    版本
    的更新日志(它内嵌在产物里,离线也读得到)。
  • 有新版本时给发布日期、发布页链接,并提示到「插件」页一键更新。
  • 检查失败会明说原因(registry 读不到 / 说明读不到),不会假装"已是最新"。

变更

  • 检查在宿主侧执行,浏览器不自己连第三方;新增 checkUpdate 远程方法。
  • 内嵌的版本与更新日志模块从 src/client/ 提到 src/,宿主也能读到运行版本。

v0.3.3

Choose a tag to compare

@github-actions github-actions released this 22 Oct 06:03

行名改用你在「模型」页映射的名字,原始 id 退到 tooltip。

修复

  • 链路、健康、探测下拉与 composer 的行名都写映射名。 之前一律渲染配置里的原始
    provider / model:网关渠道的模型 id 常是 <uuid>:<model>,三行看过去只有前缀
    不同。现在名字来自 DSH 的模型目录——与「添加候选」和 DSH 自己的模型选择器同一份
    来源;读不到目录或目录里没有这条路由时仍显示原始 id,不会借用别的名字。
  • 原始 provider/model 仍在每行 tooltip 里(候选行、健康行、探测覆盖下拉、chip
    重试行、失败历史),排查时照着它就能对上日志与配置。

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 22 Oct 00:47

弹层与链管理的可读性修正。

修复

  • 弹层标题像标题了。 「本会话的路由」与「各路由的重试次数」改为 11px 加粗、
    主文字色;之前它们和说明文字同字重,读起来只是两行正文。
  • 弹层不再跟着长路由变宽。 卡片固定 280px,长 provider/model 在行内省略
    (悬停 title 看全名),三行输入框固定右对齐。之前不同长度的路由会把卡片撑成
    不同宽度,输入框位置也跟着跳。
  • 链行输入框等长。 「编辑/编辑中」固定 68px,「默认」徽标与「设为默认」按钮
    共用 92px 槽位,改名输入框因此左右对齐;「添加链」改成带加号的 outline 按钮,
    不再像一行普通文字。
  • 会话重试覆盖上限从 9 改成 99。 与链预算共用同一个 sanity bound;10 现在
    是合法值,100 仍原样拒绝(不夹值)。上限只是防呆,真实重试次数仍由 provider
    策略决定。

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 17:04

文档修正,无运行时变化。0.3.0 的 README 还挂着已删除的「会话路由」页签截图,npm 页面
会因此展示一个已经不存在的入口;这一版把它换成更新日志弹窗的截图。

文档

  • 截图区把「会话绑定列表」换成「更新后弹一次更新日志」。
  • npm 包内 README 重新从根 README 生成,和仓库首页保持一致。

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 21 Oct 16:56

更新提示与更新日志版本:DSH 的插件市场负责发现和安装新版本,插件负责在新版本
跑起来后告诉用户改了什么。

新增

  • 更新后弹一次更新日志。 工作台在版本变化后(以及全新安装后)自动打开当前
    版本的更新说明,页头保留「更新日志」按钮,随时可以重看。说明在构建时从本文件
    生成,所以弹窗描述的永远是实际安装的产物,而不是手抄的旧文案。
  • 更新仍走 DSH 原生路径。 插件不启动包管理器,也不复制安装算法:DSH Market
    的更新行(npm 版本检查、一键更新、「更新了什么」)负责安装,插件只负责更新后的
    那一步说明。

修复

  • 点弹层外部现在会提交重试草稿。 DSH 的 Menu 在 pointerdown 就关闭,输入框
    的 blur 来不及跑,之前会把用户输入的重试次数丢掉;现在关闭回调先写入待提交的
    按路由重试次数,宿主接受后才关闭。Escape 仍是取消路径,不写任何东西。
  • README 弹层截图改为 3 倍设备像素(696×555),两列画廊不再把旧的 348×278
    元素截图放大发糊。

移除

  • 设置页的「会话路由」页签。 日常选链就在 composer 的 chip 里;这个页签只是
    事后总览,用户明确说不会用。绑定仍按 sessionId 保存,chip 与路由行为不变。
    只为它存在的 sessionBindings / deleteSessionBinding 两个 Remote 一并删除。

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 07:55

Packaging and process only; no runtime behaviour changed. The first release
published by CI through the npm trusted publisher (OIDC) rather than a manual
npm publish.

Changed

  • Releases are tag-driven. Pushing v*.*.* runs
    .github/workflows/release.yml: it refuses a tag that differs from the package
    version, builds, publishes with provenance, and opens the GitHub release from
    this file's matching section.
  • CI runs on every push to master and every pull request: the build, the
    host type-check, and each of the four suites as its own step.
  • npm metadata (keywords, homepage, bugs, author, engines) and the
    README badges; dsh-models-router replaces dsh-model-router everywhere,
    including the repository name.

Fixed

  • The client bundle no longer leaves its own ./remote artifact as an external
    require on a clean checkout (the host face now builds first).
  • The legacy-config composition scenario generates its overlay at run time
    instead of shipping Windows absolute paths.

v0.2.0 — named chains and per-session routing

Choose a tag to compare

@Imzl-zl Imzl-zl released this 21 Oct 07:37

The release that makes routing per-conversation: several named chains, a session
that can pick one, and retry counts that can be overridden per session. Published
under the name dsh-models-router (dsh-model-router on npm belongs to another
publisher).

Added

  • Named chains. chains[] + defaultChainId; a chain carries its own
    candidates, switch-on rules, first-hop budget, sticky window and start
    strategy. The settings page can add, rename, copy (candidates and budgets come
    along), make default and remove chains; the last one cannot be removed.
  • Per-session chain binding. A chip in the composer tool row (after the Plan
    and permission controls, before the model selector) picks the chain for the
    current conversation, and a "session routing" tab lists every session so
    several can be assigned without opening them. Bindings live in the
    model_router_sessions storageDomain sidecar, keyed by sessionId; without
    the storage domain they fall back to process memory and the UI says so.
  • Per-route retry overrides in the session popover and the session tab:
    session override ?? candidate maxRetries, keyed by provider/model, 0..9.
    Empty follows the chain; 0 means "do not retry this route".
  • Batch binding read/write Remotes (sessionBindings,
    deleteSessionBinding) for the session list and its cleanup of deleted
    sessions.

Changed

  • Retries on a routed step are executed by this plugin. For a code listed in
    switchOn, the configured maxRetries is the real number, with no
    provider-policy ceiling on top; the wait copies DSH's curve. Codes outside
    switchOn still go to llm-retry.
  • A chain's needs gates the fallbacks; the first hop is the user's selection
    and is never gated (README documents the consequence for image routing).

Fixed

  • Legacy configs are actually adopted. The shape is now read from the raw
    config (chains → chain → profiles → default), so a user whose config
    predates the named chains keeps routing instead of silently being read as an
    empty chain.
  • A reloading or disabled plugin no longer breaks turns. The per-agent seams
    are owned by the plugin fiber and take the agent from the payload, so they are
    removed on unload and replaced on reload; a closed storage domain now answers
    "no binding" on reads and a plain retryable error on writes instead of leaking
    DomainError('closed'), and a restart retries a transiently already-open
    domain.

v0.1.0 — first tagged release

Choose a tag to compare

@Imzl-zl Imzl-zl released this 18 Oct 17:34

First tagged release. The plugin has been feature-complete since 2026-10-16; this tag publishes one verified baseline rather than a replay of the pre-release history.

What it does

Select a model in DSH's selector as usual. When it fails, the request moves along your ordered chain of physical provider/model candidates, and the conversation reports the failure code, the candidate that answered, and why the switch was allowed.

  • Two-layer attempt budget. Same-route retries and backoff stay owned by DSH's llm-retry; cross-candidate failover and the hard total cap belong to this plugin.
  • Pre-fire validation. Each candidate is resolved through ctx.llm.resolveCallConfig() before any real call, so an unservable candidate is skipped rather than burned.
  • Conditional routing. Per-candidate images / minContextTokens gates, plus per-code switchOn.
  • Channel health workspace. Zero-token passive latency and throughput, opt-in 1-token probes, route- and channel-scoped circuit breakers, and a failover-history drawer that rebuilds through session forks.
  • Bilingual UI. Chinese and English, with an unsaved-changes bar.

Installation

Requires DSH 0.2.0-rc.2. Distributed as source from this repository — not on npm (the public registry's dsh-model-router is an unrelated package).

git clone https://github.com/Imzl-zl/dsh-model-router.git
cd dsh-model-router
npm install
npm run bundle --prefix packages/dsh-model-router
dsh plugin --profile web add packages/dsh-model-router

Verified at this tag

Suite Result
Composition (real headless Loader, stub adapter, durable-log assertions) 21 scenarios, 0 failures
Unit (pure decision logic) 121 passed
Client controller 48 passed
Remote service 14 passed
npm run bundle (incl. tsc -p tsconfig.json) clean
tsc --noEmit strict clean

The DSH reference checkout was strictly read-only across the entire history (git status --porcelain → 0 lines).

Known limitations

  • Agent main requests only. Compaction and session-title calls keep their own DSH configuration and are not routed.
  • Tool capability is not pre-checked. DSH exposes no machine-readable "supports function calling" metadata.
  • Notices are trajectory-first. Failover notices ride the durable log; this DSH build does not surface context rows in the chat conversation.

See CHANGELOG.md for the full list.