dsh-search-model
Verifieddsh-search-model · v0.1.5 · MIT · Web UI
DeepSeek Harness Web 客户端插件:接管 composer 的【模型与推理等级】座位,在「模型」子列表首位插入一个大小写不敏感的连续子串模糊搜索框(div>input),实时过滤已配置模型;弹框宽度锁定防抖动。
Install
dsh plugin add dsh-search-model Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
dsh-search-model
dsh-search-model 是 DeepSeek Harness(DSH)的 Web 客户端插件。它接管输入框旁的 【模型与推理等级】菜单,在「模型」列表首位加入一个即输即滤的模糊搜索框, 实时过滤当前已配置的全部模型。
- 零侵入 —— 只通过插槽系统渲染;卸载插件即完整还原原生 UI
- 大小写不敏感的连续子串搜索 —— 多关键词 AND;
glm命中GLM-4.6,不会误中google - 弹框不抖动 —— 菜单宽度按真实内容测量一次后锁定,过滤过程中纹丝不动
- 状态同源 —— 本菜单、composer 触发器与
/model命令面板三处选择互为回显
功能特性
- 接管座位而不改宿主一行代码:向
conversation.input.model单座位以更低的遮蔽 优先级注册(priority: -1,lowest renders),用同一套两级菜单(模型/推理等级两行 → 子列表)的增强版替换内置选择器。 - 面板内搜索框:输入框只出现在「模型」子列表内(根级两行界面保持原样); 进入面板自动聚焦;Esc 先清词、再退面板、最后关菜单。
- 连续子串匹配:小写化后按 token AND;每个关键词必须是 provider 显示名/provider
id/模型名/模型 id/描述的连续子串——不做跨字符跳跃匹配,乱序输入如
glm绝不会带出google。 - 实时过滤:命中为零的分组整组隐藏;清空关键词恢复全量目录;无任何命中时 展示「未找到匹配的模型」空态。
- 弹框宽度锁:进入「模型」面板、目录加载落定且搜索词为空时,测量一次菜单的 自然内容宽度并固定为 px——输入过滤不再改变卡片宽度;离开面板/关闭/重进都会 复位重测。同时去掉原生 420px 装饰性硬上限(保留视口安全边界),长模型名与描述 不会被卡片自身裁断。
- 与宿主数据同源:优先复用核心
ctx.modelDirectories服务——正是/model弹窗使用的那个 per-session 目录实例,加载态、失败重试条、推理等级切换、当前 选择回显等语义完全一致。若该服务缺失(宿主版本漂移),自动降级为内置轻量目录, 走同一套session.models/session.selectModelwire。
安装
需要已安装 DSH 并使用 web profile。
# 从 npm 安装(发布后)
dsh plugin --profile web add dsh-search-model
# 从 GitHub Release 的 tarball 安装
dsh plugin --profile web add ./dsh-search-model-0.1.2.tgz
# 从本地 checkout 安装(开发)
dsh plugin --profile web add ./
确认组合包层已落地,然后启动 / 重启宿主:
dsh --profile web --dump-config # 可见 "# == dsh-search-model" 一层
dsh --profile web # 需重启宿主才会加载新的 lib/client.js
不支持
github:源码直装(本包有意不带prepare脚本):git 安装拉取的是源码, 没有构建产物lib/。请改用 Release 页下载的 tarball,或直接从 npm 安装。
使用
- 在 DSH Web 界面打开任意会话。
- 点击 composer 工具行右端的模型胶囊按钮(发送键左侧)。
- 在【模型与推理等级】菜单中进入「模型」。
- 在顶部搜索框输入——列表即时过滤(忽略大小写,多关键词 AND)。
- 点击命中项即选中;选择会同步到所有界面(触发器标签、
/model、推理等级列表)。
卸载:
dsh plugin --profile web remove dsh-search-model
开发
pnpm install
pnpm check # 类型检查(tsc -b --pretty false)
pnpm build # rm lib && tsc -b && tsdown → lib/index.js(宿主 ESM)+ lib/client.js(浏览器工厂)
pnpm watch # 监听重建 client bundle
pnpm verify # 用模拟宿主 __ModuleLoader__ 引导校验 lib/client.js
发布流程(维护者):
pnpm release # check → build → verify → npm version patch → 推送 tag
# v* tag 触发 .github/workflows/publish.yml:
# 构建 → pack → GitHub Release → npm Trusted Publishing
pnpm publish:npm # 手动本地发布通道(含完整前置链)
结构
├── src/host/index.ts # 宿主半边极简锚点(Loader entry + dsh.client 扫描依据)
├── src/client/
│ ├── index.ts # 插件模块:注入样式 + 接管 conversation.input.model 座位
│ ├── face.ts # 座位注入面解析(shared ctx.modelDirectories / 回退自建目录)
│ ├── SearchModelSelect.tsx # 座位组件:两级菜单 + 面板内搜索 + 宽度锁
│ ├── fuzzy.ts # 大小写不敏感的连续子串匹配(token AND,无跳跃)
│ ├── store.ts # 回退路径的轻量快照 store
│ ├── styles.ts # 样式注入(dsm-* 类名,基于宿主 --dsw-* 设计令牌)
│ └── types.ts # wire 契约的本地类型镜像(零运行时依赖)
├── lib/ # 构建产物(index.js、client.js、types/)——见 files[]
├── scripts/verify-client.mjs # 浏览器 bundle 的宿主 seed 模拟校验
├── tsdown.config.ts # 构建配置(node 半边 + __ModuleLoader__ banner 包装)
├── tsconfig{,.host,.client}.json # solution + 两个隔离 aggregate
├── cordis.patch.yml # 组合包 patch 行(按包名引用插件)
└── package.json # dsh.bundle + dsh.client(web) manifest
兼容性
- 基于
@deepseek-ai/*0.1.0-rc系列构建;peer 范围接受^0.1.0-rc.6。 - 所有
@deepseek-ai/*导入均为纯类型导入——运行时 external 全部落在宿主 seed 模块表内(react、react/jsx-runtime、react-dom、@deepseek-ai/dsh-client-ui-primitives),由verify强制约束。
许可证
MIT © jsoncode