dsh-sidebar-session-provider-icon
Verifieddsh-sidebar-session-provider-icon · v0.1.11 · MIT · Web UI
DeepSeek Harness plugin: show a provider + model icon in the sidebar for every session, updated live from the composer selector with a last-request fallback
Install
dsh plugin add dsh-sidebar-session-provider-icon Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
dsh-sidebar-session-provider-icon
English · 简体中文
左:隔离 DSH 实例中的真实侧边栏(演示会话);右:单一与复合角标的显示规则。
DeepSeek Harness(DSH)的侧边栏里每个会话行看起来都一样,不打开会话就分不清它用的是哪个 provider 和 model。这个插件在每个会话标题前显示 provider + model 图标,取值于输入框当前选中的模型,切换后立刻更新。provider 和 model 不是同一家时(例如 opencode-go/deepseek-v4-flash),在 provider logo 的右下角叠一个缩小的 model logo。
安装。 需要 DeepSeek Harness 0.2.0-rc.2、Node.js >=22.19。
# 从 npm 安装:预构建,无需构建授权
dsh plugin --profile web add dsh-sidebar-session-provider-icon
# 或直接从源码安装:本地构建,dsh 请求授权时确认即可
dsh plugin --profile web add prgrmrwy/dsh-sidebar-session-provider-icon
重启 DSH 并刷新 Web 页面。除此之外不需要任何东西:无配置项、不访问网络、除安装它的 DSH profile 外不写任何文件。
在 ohmydsh 仓库里,本插件通过 dsh.yaml 的条目 sidebar-session-provider-icon(source: local)接入,因此在该仓库改源码只需 dsh build 再重启。当前行为见规范 openspec/specs/sidebar-session-provider-icon;设计演进见归档的 change sidebar-session-provider-icon 和 sidebar-provider-icon-composite-model-badge。
行为
会话显示哪个 logo,按以下顺序取数据:
- 即时选择(优先,且须可核验)。 官方
dsh-client-ui-model-selection的 store,读作ctx.modelDirectories.directoryFor(sessionId).store.current。它是输入框选择器与/model命令共享的唯一 per-session 状态,session.selectModel成功后立即发布{ provider, model }。因此当前打开的会话(包括还没发过消息的空白会话)按输入框的选择显示。该 store 属于客户端 Session scope:每次会话列表 / DOM 信号都会重新解析,运行体给同一个 session 换了新 store(离开会话再回来就会发生)时立即重订阅并重读,身份未变时也重读快照。观测值只在其 session 仍是当前打开会话、且该目录仍可解析期间保留;视图离开或目录不再可解析时即丢弃——不再让客户端无法核验的旧值决定某一行的 logo。 - 已选模型(持久)。 官方
modelSelection投影的next,即该 session 下一次请求将使用的选择。它由 Host 维护,也覆盖"已选但尚未发送"的选择,因此离开会话之后该行仍然正确。 - 最近一次请求(冷历史 fallback)。 Host 的
providersession projection 折叠会话日志中的request/header事件,所以尚未在本浏览器加载选择器的历史会话,仍会显示它最近一次真实请求的 provider。重启不丢,不使用localStorage。
品牌判断分两个独立维度:provider route 决定主图,model id 决定右下角小图标。
| 选择 | 显示 |
|---|---|
claude/claude-opus-5、codex/gpt-6-luna、deepseek-official/deepseek-v4-pro(同品牌) |
单一 Anthropic / OpenAI / DeepSeek logo |
opencode-go/deepseek-v4-flash、opencode-go/qwen3.8-flash、opencode-go/kimi-k2.7-code |
OpenCode 主图,右下角 DeepSeek / Qwen / Kimi |
traex/GPT-5.6-Sol[1m]、traex/DeepSeek-V4-Flash、traex/Gemini-3.1-Pro-Preview |
Trae 主图,右下角 OpenAI / DeepSeek / Gemini |
traex/openrouter-3o[1m]、traex/Seed-2.1-Pro-0915 |
Trae 主图,右下角 OpenRouter / ByteDance |
dsh-magpie-connect + opencode-go/deepseek-v4.1-flash、opencode-go/glm-5.3-flash(Magpie 网关,经平台中转) |
Magpie 主图,左下角 OpenCode(中转平台)+ 右下角 DeepSeek / GLM(模型厂商) |
dsh-magpie-connect + claude/claude-haiku-5-5、codex/gpt-6-luna(Magpie 网关,直连厂商) |
Magpie 主图,右下角 Anthropic / OpenAI,左下角为空 |
已知 route + 认不出的 model(如 opencode-go/omen-alpha) |
只显示 route 品牌,不叠小图标 |
| 未知或通用 route | 按 model 名显示单一 logo;仍匹配不上时显示中性的单字母徽标 |
- route 优先。
opencode-go/deepseek-v4.1-flash的主图是 OpenCode;DeepSeek 只会出现在右下角。 - 网关最多三层。 主图是网关,右下角是模型厂商,左下角是中转平台——
dsh-magpie-connect / opencode-go/deepseek-v4.1-flash同时表达 Magpie、OpenCode、DeepSeek 三层身份。中转层只在上游段是可识别品牌且与模型厂商不同时出现,所以claude/*、codex/*、opencode-go/private-model、auto|group|custom仍是两层或单层。 - 认不出不冒充。 查不到厂商的模型不加小图标,也不会用单字母徽标充当小图标。
- 尺寸。 复合图标的外框和单一 logo 一样是 14×14,行布局不变。两个小图标都是 10px 的品牌图形本身,各自向所在下角溢出 4px,没有圆底、描边或内边距——在这个尺度下任何装饰都会挤掉图形需要的像素。左下角图标落在 badge 与官方状态点之间的空隙里,不覆盖
StateDot。 - 悬停提示。 始终显示精确的
provider · model。
| 层 | 实现 |
|---|---|
| Host | src/provider.ts 注册 provider projection(依赖 sessionProjections 服务),折叠 request/header;只承担冷历史 fallback |
| Client 数据 | selection-binding.ts 观测当前打开会话的 ctx.modelDirectories store(每次信号重新解析);provider-map.ts 依次取:可核验的即时观测 → 官方 modelSelection 选择 → provider fallback |
| Client DOM | row-locator.ts 收拢全部官方行 DOM 知识:每行按官方 data-row-key="session:<id>" 精确定位(标题反查仅作为没有该属性时的 fallback),因此同名会话不会互相串用徽标;MutationObserver 在标题前维护独立的 badge <span> |
| 品牌图 | src/client/assets/*.svg,一次下载并随包打入;logos.ts 分别判定 provider 品牌与 model 品牌,不同时渲染复合图标 |
徽标内容只由 (provider, model) 决定;index.ts 只在这两个值或悬停提示变化时重建徽标。
配置
无。插件行没有任何 config 字段,也不读取环境变量。
Provider / model → 图标对应关系
下表列出可识别的 provider route 别名与 model 名称示例,不是固定的模型目录。匹配不区分大小写,并去掉 npm scope 和开头的 dsh- / dsh_。已知 provider 决定主图;model 品牌已知且不同时决定右下角小图标。— 表示该品牌不支持这一维度。精确规则见 logos.ts。
| 图标 | 品牌 | Provider route / 别名 | Model 名称 / 系列 |
|---|---|---|---|
| DeepSeek | deepseek、deepseek-official |
deepseek-* |
|
| OpenAI | openai、codex |
gpt-*、codex-* |
|
| Anthropic | anthropic、claude |
claude-*、名称含 anthropic |
|
| Grok / xAI | grok、xai |
grok-* |
|
| Kimi / Moonshot | kimi、moonshot |
kimi-*、moonshot-* |
|
| GLM / 智谱 | glm、z-ai、zai、zhipu |
glm-* |
|
| MiniMax | minimax |
minimax-* |
|
| Pi | pi、pi-ai |
pi、pi-* |
|
| OpenClaw | 名称含 openclaw |
名称含 openclaw |
|
| Hermes Agent | hermes、hermas、nousresearch、nous |
名称含 hermes、hermas、nousresearch |
|
| OpenCode | opencode、opencode-go、opencode-zen |
名称含 opencode |
|
| Trae | trae、trae-ai、traex* |
— | |
| Magpie | magpie、magpie-*、dsh-magpie-connect |
—(按下文网关规则) | |
| Qwen | qwen、dashscope、bailian |
qwen*、qwq* |
|
| 腾讯混元 | hunyuan、tencent |
hunyuan*、hy<数字>*(如 hy3、hy4-preview) |
|
| 美团 LongCat | longcat、meituan |
longcat-* |
|
| 小米 MiMo | xiaomi、mimo |
mimo-* |
|
| Google Gemini | gemini、google、google-* |
gemini-*、gemma* |
|
| NVIDIA | 名称含 nvidia |
名称含 nemotron |
|
| Meta | meta、meta-ai、meta-llama* |
muse-spark*、名称含 llama |
|
| 蚂蚁集团 | ant-ling、inclusionai、antgroup |
ling-*、ring-* |
|
| OpenRouter | — | openrouter-*(如 TraeX 的 openrouter-3o[1m]) |
|
| 字节跳动 | — | seed-* |
Trae、Magpie 的 route 按完整名 / 前缀匹配,不按任意子串匹配。OpenRouter、ByteDance 仅支持 model 维度:provider route 单独叫 openrouter 不会因此显示 OpenRouter 图标。
model 维度覆盖 OpenCode Go / Zen 模型目录里所有能确认厂商的模型族,并覆盖当前 TraeX 目录中的 GPT、DeepSeek、Gemini、OpenRouter 与 ByteDance Seed 系列。
网关型 route(Magpie)下,model id 形如 <上游 provider>/<model>,两个段各管一个角:右下角取模型厂商(/ 后的模型名优先,认不出才退回上游段:opencode-go/private-model → OpenCode);左下角取中转平台(/ 前的上游段,仅当它是可识别品牌、且与右下角品牌不同时才画:opencode-go → OpenCode)。auto、group、custom 这类非品牌上游段不产生中转角。两段都认不出只显示 Magpie。其它 route 仍按整个 model id 识别。详细取舍见 openspec/changes/archive/2026-10-25-sidebar-provider-icon-gateway-transit-tier/design.md。
品牌图是固定版本并随包落盘的,不手绘,运行时也不访问 CDN:
- 除 OpenCode、Magpie 外的所有品牌:
@lobehub/[email protected],MIT;有彩色版时用彩色版; - OpenCode:
anomalyco/opencodecommit5e75e5e9901f0d178f425bfb47f1bd46cbe78a59中的官方 provider SVG,MIT; - Magpie:
yetone/magpiecommitba1dc7f975666e50308ef7bf8173c8a8e91c553b中的官方标志internal/provider/magpie.svg,MIT。
逐个文件的来源 URL 与 SHA-256 校验值见 src/client/assets/README.md。部分彩色 SVG 内含渐变/裁剪 id;右下角实例会给它们加 -sub 后缀,避免同一页面的多份 SVG 串用定义。
新增品牌:把 SVG 放进 src/client/assets/,在 assets README 记录来源、版本、许可和 SHA-256,再在 logos.ts 的 providerBrandOf / modelBrandOf 里补规则和测试。
边界与安全
- 官方
StateDot不会被替换、移动或隐藏;时间、行菜单和拖拽行为保持官方原样。 - badge 是标题前的独立
<span>。DOM 无法可靠定位时,插件静默不显示,不破坏页面。 - 自身不发起网络请求:logo 随 bundle 提供,数据来自 DSH 自己的 store 与会话日志。
- 代码为 MIT 许可(LICENSE)。品牌图标来自 MIT 许可的上游;其版权声明、渲染时的确切改动与商标立场见 THIRD-PARTY-NOTICES.md。品牌方保留其商标权利;这些标识只用于标明所选的 provider route 和 model,不暗示任何背书。
开发
lib/ 是被 git 忽略的构建产物。独立检出时:
npm install
npm run typecheck
npm test
npm run build
在 ohmydsh monorepo 里本包是 workspace 成员:在仓库根目录安装一次,后三条命令加上 --workspace dsh-sidebar-session-provider-icon。dsh build / sync 也会在安装本 local package 之前按需生成 lib/;刷新 Web 页面即可加载新的 client bundle。
vitest 下小 SVG 会被内联成 data URL,属性引号会被改成 '。改写 SVG 属性的正则要同时兼容 " 和 '。