dsh-model-flatmap 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -12
- package/README.zh.md +33 -11
- package/client.js +1537 -102
- package/docs/DETAIL.md +201 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,6 +31,13 @@ levels, and the agent-teamwork switch on one surface:
|
|
|
31
31
|
|
|
32
32
|
- **One surface.** The trigger opens one panel capped at 320 px. The header, the
|
|
33
33
|
reasoning row, and the teamwork row stay fixed; only the model grid scrolls.
|
|
34
|
+
- **The trigger shows what the native one shows.** Its name is not a string: the
|
|
35
|
+
shipped picker renders the `conversation.input.model.label` slot there, and
|
|
36
|
+
connection plugins use it for a promotion chip (`夜间折扣`), a rate, or a load
|
|
37
|
+
mark (queued people / a rocket when idle). This plugin renders that slot's
|
|
38
|
+
winning component on its own trigger — with the seats it needs — so the two
|
|
39
|
+
modes show the same content. A missing or crashing occupant falls back to the
|
|
40
|
+
catalog name plus the model's own `model.badge`.
|
|
34
41
|
- **Global search.** Filters across every provider and every family. Groups that
|
|
35
42
|
end up empty are dropped, so no stray headings remain. Prefix matches rank
|
|
36
43
|
first, then substring matches, then ordered character matches.
|
|
@@ -48,31 +55,59 @@ levels, and the agent-teamwork switch on one surface:
|
|
|
48
55
|
`hy3` → `HY3`, `hy4free` / `hy4std` / `hy4-preview` → `HY4`, and a bare `hy`
|
|
49
56
|
→ `HY`. Unregistered brands still collapse their version tail; dictionary
|
|
50
57
|
families (GPT, Qwen…) are never split.
|
|
51
|
-
- **Rows are provider-primary.** Under *By family* the
|
|
52
|
-
the models are, so the family name is not repeated
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
- **Rows are provider-primary, with a model tail.** Under *By family* the
|
|
59
|
+
heading already says what the models are, so the family name is not repeated
|
|
60
|
+
in a row: the primary text is the provider name. What neither the heading nor
|
|
61
|
+
the provider can say — which model of the family the row is, and the
|
|
62
|
+
catalog's rate multiplier — is drawn as a quieter tail at the end of the row,
|
|
63
|
+
with the family name and the provider label stripped off: `Qwen3.8-27B` under
|
|
64
|
+
*Qwen* reads `3.8-27B`, and `Deepseek-V4.1-Flash · x0.01` under *DeepSeek*
|
|
65
|
+
reads `V4.1-Flash · x0.01` with the multiplier drawn smaller and bold. The
|
|
66
|
+
full model name and description stay in the tooltip.
|
|
67
|
+
- **Long names and long headings scroll on hover.** A clipped model name or
|
|
68
|
+
group heading runs one eased leftward pass after the pointer rests on it for
|
|
69
|
+
0.5 s, then stops; leaving resets it instantly. Only the text moves — the
|
|
70
|
+
trailing badge and the title's band never do.
|
|
56
71
|
- **Reasoning effort.** The current model's reasoning levels render as an
|
|
57
72
|
exclusive, keyboard-operable group ("推理等级" / "Reasoning effort") driven by
|
|
58
73
|
radio semantics.
|
|
59
74
|
- **Adaptive footer.** The reasoning group and the agent-teamwork switch share
|
|
60
75
|
one line when both fit with a 30 px gap, and fall back to one row each when
|
|
61
76
|
they do not — the break is CSS flex wrapping, not a measured pixel threshold.
|
|
62
|
-
- **Out-of-balance models are struck through — everywhere.** A model
|
|
63
|
-
call failed on insufficient balance, credit, or quota keeps a
|
|
64
|
-
on its row text until a later call for that same model returns
|
|
65
|
-
|
|
77
|
+
- **Out-of-balance models are struck through — everywhere, for a day.** A model
|
|
78
|
+
whose last call failed on insufficient balance, credit, or quota keeps a
|
|
79
|
+
`line-through` on its row text until a later call for that same model returns
|
|
80
|
+
anything else, and until the mark has gone 24 hours without a new attempt —
|
|
81
|
+
whichever comes first. A balance is topped up and a quota resets daily, so a
|
|
82
|
+
strike nobody refreshed is stale information, not a warning. The strike
|
|
83
|
+
follows the model the failing request actually used, and covers the
|
|
66
84
|
Host's `QUOTA` / `ACCOUNT_QUOTA` codes, a provider `402`, and a `429` whose
|
|
67
85
|
body reports an empty balance — a plain rate limit never strikes. Because a
|
|
68
86
|
balance is a property of the model route and its account, **not of one
|
|
69
87
|
conversation**, the marks are global: a failure seen in any Session strikes
|
|
70
88
|
the model in every Session and workspace, and the state is persisted to
|
|
71
|
-
`localStorage` so it survives a reload.
|
|
72
|
-
|
|
73
|
-
|
|
89
|
+
`localStorage` so it survives a reload. Every mark keeps the time of the
|
|
90
|
+
observation that made it, so opening the list a day later draws that row
|
|
91
|
+
plain. Observations are ordered by that same time, so the newest one wins and
|
|
92
|
+
replaying older history cannot resurrect a strike that has already ended —
|
|
93
|
+
by a later call or by age.
|
|
74
94
|
- **Theme-aware.** Styled with host theme tokens only; looks correct in both
|
|
75
95
|
light and dark themes.
|
|
96
|
+
- **Native mode.** The panel's bottom-right `Default style` button hands the
|
|
97
|
+
composer's model seat back to the **host's own** picker — the real shipped
|
|
98
|
+
`ModelSelect`, not a reproduction of it. The plugin does this by *stepping
|
|
99
|
+
aside*: it disposes its own `conversation.input.model` registration, so the
|
|
100
|
+
host's entry underneath wins the slot and renders itself. Nothing is
|
|
101
|
+
imported, copied, or re-mounted, which means an upgraded DSH shows its own
|
|
102
|
+
newest picker and this mode can never drift out of date. The way back is a
|
|
103
|
+
separated action band at the bottom of that picker's own menu — it reuses the
|
|
104
|
+
`conversation.input.model.options` child slot the shipped `ModelSelect`
|
|
105
|
+
declares, so it belongs to the panel it acts on and renders nothing at all
|
|
106
|
+
while the flat panel is shown. It is drawn as an outlined button, not as one
|
|
107
|
+
more menu row: the rows above it pick a value, this one performs an action.
|
|
108
|
+
The choice is remembered across reloads. If the host ships no picker to hand
|
|
109
|
+
over to, the button stays disabled and the panel stays — the composer never
|
|
110
|
+
ends up without a model control.
|
|
76
111
|
|
|
77
112
|
See [`docs/DETAIL.md`](./docs/DETAIL.md) for the full behaviour spec and
|
|
78
113
|
[`DECISIONS.md`](./DECISIONS.md) for the decision log behind the design.
|
package/README.zh.md
CHANGED
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
|
|
28
28
|
- **一块平面。** 触发器打开一个高度上限 320 px 的面板。头部、推理等级行与协作行
|
|
29
29
|
固定常驻,只有模型网格可滚动。
|
|
30
|
+
- **触发器显示的内容与原生一致。** 触发器上的模型名不是一个字符串:出厂 picker 在那里
|
|
31
|
+
渲染 `conversation.input.model.label` 插槽,连接器插件用它在名字旁放促销 chip
|
|
32
|
+
(如 `夜间折扣`)、倍率,或负载标记(排队人数的小人图标 / 空闲时的火箭)。本插件
|
|
33
|
+
在自己的触发器上渲染该插槽的胜出组件(并补齐它需要的座位),因此两种模式显示同样的
|
|
34
|
+
内容。占用者缺失或崩溃时回退到目录名 + 模型自带的 `model.badge`。
|
|
30
35
|
- **全局搜索。** 跨所有 provider 与 family 过滤。过滤后为空的组会被丢弃,不会留下
|
|
31
36
|
空标题。命中排序:前缀优先,其次子串,最后有序字符匹配。
|
|
32
37
|
- **分词搜索。** 空白把查询拆成多个 token,每个 token 都要在名称中命中;一次命中的
|
|
@@ -41,22 +46,39 @@
|
|
|
41
46
|
- **generation 要区分开。** 已注册品牌按 generation 分节:`hy3` 归 `HY3`、`hy4free` /
|
|
42
47
|
`hy4std` / `hy4-preview` 归 `HY4`,裸 `hy` 仍是 `HY`;未注册品牌仍折叠版本后缀。
|
|
43
48
|
词典家族(GPT、Qwen…)不拆 generation。
|
|
44
|
-
- **row content 以 provider
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
- **row content 以 provider 为主,末尾补型号尾标。** *按 family* 下标题已经说明模型
|
|
50
|
+
是什么,所以行里不再重复家族名,主文本改为 provider name。标题和 provider 都说不出
|
|
51
|
+
的信息——这一行究竟是家族里的哪个型号、以及目录给的倍数——放在行**末尾**一个更安静的
|
|
52
|
+
尾标里:把家族名和 provider label 从模型名里剥掉,`Qwen` 下的 `Qwen3.8-27B` 显示为
|
|
53
|
+
`3.8-27B`,`DeepSeek` 下的 `Deepseek-V4.1-Flash · x0.01` 显示为
|
|
54
|
+
`V4.1-Flash · x0.01`,其中倍数照旧用更小更粗的字重。完整模型名/描述保留在 tooltip。
|
|
55
|
+
- **长名称与长标题 hover 跑马灯。** 显示不全的模型名或分组标题,在鼠标停留 0.5 s 后
|
|
56
|
+
向左跑**一趟**(ease-in-out)即停,移开立刻复位。只有文字在动——右侧的 badge 和
|
|
57
|
+
标题所在的色带本身都不动。
|
|
47
58
|
- **推理等级。** 当前模型的推理等级渲染为一个互斥、可键盘操作的分组("推理等级",
|
|
48
59
|
基于 radio 语义)。
|
|
49
60
|
- **自适应底栏。** 推理等级组与智能体协作开关在放得下(中间至少 30 px)时共用一行,
|
|
50
61
|
放不下时各自占一行回到原来的两行布局——换行由 CSS flex 换行决定,不靠 JS 量像素。
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
- **额度不足的模型加删除线,全局生效,且只生效一天。** 某个模型的调用因额度/余额/信用不足
|
|
63
|
+
而失败后,该模型的行文字会带 `line-through` 删除线,直到同一个模型的下一次调用返回非额度
|
|
64
|
+
不足的结果,或者这条标记已经 24 小时没有新尝试——以先到者为准。余额会被充值、额度会按日
|
|
65
|
+
重置,所以一条没人更新的划线是**过时的信息**,不是警告。标记跟随失败那次请求实际使用的
|
|
66
|
+
模型;覆盖宿主的 `QUOTA` / `ACCOUNT_QUOTA` 代码、provider 的 `402`,以及**正文说明余额
|
|
67
|
+
不足的 `429`**——纯限流的 429 不会划线。因为「还有没有额度」是模型路由(及其账号)的属性、
|
|
68
|
+
**与单个会话无关**,所以标记是全局的:在任意会话里观察到的失败,会在所有会话与工作区里
|
|
69
|
+
同样划线;状态持久化在 `localStorage` 中,重载后仍然保留。每条标记都记下「这次判定发生的
|
|
70
|
+
时间」,因此一天之后再打开列表,那一行就是干净的。观察按同一个时间排序,最新的一条说了算,
|
|
71
|
+
所以回放更早的历史既不能让一条已被后续调用清除的划线复活,也不能让一条已经过期的复活。
|
|
59
72
|
- **跟随主题。** 仅使用宿主主题令牌着色,在浅色与深色主题下都正确。
|
|
73
|
+
- **原生模式。** 面板右下角的 `默认样式` 按钮把输入框的模型座位交还给**宿主自己的**选择器——真正
|
|
74
|
+
出厂的 `ModelSelect`,不是它的复制品。做法是**让位**:本插件 dispose 掉自己在
|
|
75
|
+
`conversation.input.model` 的注册,槽于是选中下方那条出厂条目,由宿主渲染它自己的组件。没有
|
|
76
|
+
import、没有拷贝、没有 re-mount,所以 DSH 升级后出现的自然是它最新的 picker,这个模式**结构上
|
|
77
|
+
不可能过期**。切回面板的入口长在**原生选择器自己的菜单底部**(复用出厂 `ModelSelect` 声明的
|
|
78
|
+
`conversation.input.model.options` 子插槽),所以它属于那个面板、而不是输入框工具栏;平铺模式下
|
|
79
|
+
它渲染 `null`,原生菜单与出厂状态完全一致。它**不模仿菜单行**:上方一条分隔线,下面是一个带描边
|
|
80
|
+
的整宽按钮——上面的行是「选一个值」,这个是「执行一个动作」。选择跨重载保留。若宿主没有可交出的选择器,按钮会
|
|
81
|
+
置灰、面板保持显示——composer 永远不会失去模型控件。
|
|
60
82
|
|
|
61
83
|
完整行为规格见 [`docs/DETAIL.md`](./docs/DETAIL.md),设计决策见
|
|
62
84
|
[`DECISIONS.md`](./DECISIONS.md)。
|