@fonlan/dsh-model-parameters 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 fonlan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,140 @@
1
+ # dsh-model-parameters
2
+
3
+ [中文](README.md) | **English**
4
+
5
+ DSH plugin: when a provider's model sync (or any settings write) leaves model
6
+ entries with missing capability fields, automatically fill them from the
7
+ [models.dev](https://models.dev) catalog — display name, context window, max
8
+ output tokens, reasoning efforts, and input modalities.
9
+
10
+ Most provider `/v1/models` listings disclose an id and nothing else. This
11
+ plugin makes those synced models immediately usable by completing their
12
+ metadata from a locally cached catalog, and reports what it filled and what it
13
+ could not match.
14
+
15
+ ## How it works
16
+
17
+ 1. The plugin listens to the `llm-pi-ai` settings namespace (`settings/updated`).
18
+ Any committed change — a freshly synced provider, an edited provider card, a
19
+ manual `settings.yaml` edit — triggers a reconcile.
20
+ 2. On plugin start it also runs one backfill over the existing configuration.
21
+ 3. For every model entry missing any of `name` / `contextWindow` / `maxTokens` /
22
+ `reasoningEfforts` / `input`, it resolves the best catalog entry and fills
23
+ only the missing fields (fill-only: present values are never overwritten).
24
+ 4. The write goes through the settings seam (`ctx.settings.mutate`), i.e. it
25
+ lands in `~/.dsh/settings.yaml` — the same file you would edit by hand.
26
+
27
+ The reconcile is fill-only by construction, so its own writes cannot loop: the
28
+ next `settings/updated` sees the fields present and produces no ops.
29
+
30
+ ## Matching
31
+
32
+ models.dev keys the same model under many providers (`deepseek-v4-flash`
33
+ appears under 57 providers). Resolution is deterministic and provider-aware:
34
+
35
+ 1. **Provider match** — the models.dev provider mapped for the dsh provider
36
+ (explicit `providerMap` override, then the same provider id). Your
37
+ `opencode-go` route is also a models.dev provider, so its entries win.
38
+ 2. **Exact full-id match** — a dsh model id already carrying a `vendor/` prefix
39
+ matches the identical models.dev key.
40
+ 3. **First-party vendor priority** — `officialProviders` (deepseek, openai,
41
+ anthropic, google, xai, …) break collisions in favor of the vendor's own
42
+ entry.
43
+ 4. **Completeness** — entries with both limits known win over partial ones.
44
+ 5. **Alphabetical provider id** — stable last resort.
45
+
46
+ Bare ids are matched case-insensitively against the last path segment, so
47
+ `qwen3.7-max` resolves `Qwen/Qwen3.7-Max` and `kimi-k2.7-code` resolves
48
+ `Kimi-K2.7-Code`.
49
+
50
+ ## Filled fields
51
+
52
+ | dsh field | models.dev source | notes |
53
+ |---|---|---|
54
+ | `name` | `name` | display name |
55
+ | `contextWindow` | `limit.context` | tokens |
56
+ | `maxTokens` | `limit.output` | tokens |
57
+ | `reasoningEfforts` | `reasoning_options[type=effort].values` | identity dict `{high:"high", max:"max"}`; values outside pi-ai's levels (`default`/`none`/…) are filtered; `toggle`/`budget_tokens` options are ignored |
58
+ | `input` | `modalities.input` | filtered to `text`/`image` (the only modalities pi-ai accepts; `pdf`/`audio`/`video` are dropped) |
59
+
60
+ Models with no catalog match (e.g. a local gateway model like
61
+ `hy3-paid`) are left untouched and listed in the fill report as unmatched.
62
+
63
+ ## Catalog caching & updates
64
+
65
+ - The catalog is fetched from `https://models.dev/api.json` and cached at
66
+ `~/.dsh/model-parameters/catalog.json` (~4 MB).
67
+ - A cached catalog is refreshed lazily on the next reconcile once older than
68
+ `ttlDays` (default **7 days**).
69
+ - A failed fetch keeps the last good cache; with no cache at all the plugin
70
+ simply fills nothing until a refresh succeeds.
71
+ - The settings page has an **Update catalog & fill now** button for a forced
72
+ refresh, and shows the last update time and freshness.
73
+
74
+ ## Settings page
75
+
76
+ A "模型参数补全 / Model Parameters" section appears in DSH settings:
77
+
78
+ - master enable switch plus per-field toggles (`fillName`, `fillContext`,
79
+ `fillMaxTokens`, `fillReasoning`, `fillInput`);
80
+ - catalog TTL in days;
81
+ - optional `provider → models.dev provider` mapping overrides;
82
+ - catalog freshness card (entries, providers, last update);
83
+ - the last fill report: fields filled, providers touched, and the list of
84
+ unmatched model ids.
85
+
86
+ Plugin configuration persists in the `model-parameters` settings namespace
87
+ (`~/.dsh/settings.yaml`), e.g.:
88
+
89
+ ```yaml
90
+ model-parameters:
91
+ enabled: true
92
+ ttlDays: 7
93
+ fillName: true
94
+ fillContext: true
95
+ fillMaxTokens: true
96
+ fillReasoning: true
97
+ fillInput: true
98
+ providerMap: {}
99
+ officialProviders:
100
+ - deepseek
101
+ - openai
102
+ - anthropic
103
+ - google
104
+ - xai
105
+ ```
106
+
107
+ ## Installation
108
+
109
+ Install with the `dsh plugin` command (replace `web` with your profile name):
110
+
111
+ **From npm**:
112
+
113
+ ```bash
114
+ dsh plugin --profile web add @fonlan/dsh-model-parameters
115
+ ```
116
+
117
+ **Directly from GitHub**:
118
+
119
+ ```bash
120
+ dsh plugin --profile web add github:fonlan/dsh-model-parameters
121
+ ```
122
+
123
+ **Uninstall**:
124
+
125
+ ```bash
126
+ dsh plugin --profile web remove @fonlan/dsh-model-parameters
127
+ ```
128
+
129
+ ## Development
130
+
131
+ ```bash
132
+ pnpm install
133
+ pnpm build # tsc types + tsdown host & client bundles
134
+ pnpm typecheck
135
+ node scripts/verify-catalog.mjs # matching-logic check against a models.dev dump
136
+ ```
137
+
138
+ ## License
139
+
140
+ MIT
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # dsh-model-parameters
2
+
3
+ **中文** | [English](README.en.md)
4
+
5
+ DSH 插件:当 provider 的模型同步(或任何设置写入)留下缺失能力字段的模型条目时,自动从 [models.dev](https://models.dev) 目录补全——显示名称(display name)、上下文窗口(context window)、最大输出 token、推理档位(reasoning efforts)和输入模态(input modalities)。
6
+
7
+ 大多数 provider 的 `/v1/models` 列表只披露一个 id,别无其他。本插件用本地缓存的目录补全这些同步模型的元数据,让它们立即可用,并报告补全了什么、哪些无法匹配。
8
+
9
+ ## 工作原理
10
+
11
+ 1. 插件监听 `llm-pi-ai` 设置命名空间(`settings/updated`)。任何已提交的变更——新同步的 provider、编辑过的 provider 卡片、手动编辑的 `settings.yaml`——都会触发一次 reconcile。
12
+ 2. 插件启动时还会对现有配置执行一次全量回填。
13
+ 3. 对每个缺少 `name` / `contextWindow` / `maxTokens` / `reasoningEfforts` / `input` 任一字段的模型条目,解析出最佳目录条目,只补全缺失字段(fill-only:已有值绝不覆盖)。
14
+ 4. 写入走设置接缝(`ctx.settings.mutate`),即落到 `~/.dsh/settings.yaml`——与你手动编辑的是同一个文件。
15
+
16
+ reconcile 天然是 fill-only 的,因此它自己的写入不会造成循环:下一次 `settings/updated` 看到字段已存在,不会产生任何操作。
17
+
18
+ ## 匹配逻辑
19
+
20
+ models.dev 把同一模型挂在许多 provider 名下(`deepseek-v4-flash` 出现在 57 个 provider 下)。解析是确定性的、且 provider 感知:
21
+
22
+ 1. **Provider 匹配** —— 为 dsh provider 映射的 models.dev provider(显式 `providerMap` 覆盖,其次同 id)。你的 `opencode-go` 路由本身也是 models.dev provider,所以它的条目优先。
23
+ 2. **完整 id 精确匹配** —— 已带 `vendor/` 前缀的 dsh 模型 id 与完全相同的 models.dev key 匹配。
24
+ 3. **官方 vendor 优先** —— `officialProviders`(deepseek、openai、anthropic、google、xai……)在冲突时偏向厂商自己的条目。
25
+ 4. **完整性** —— 两个 limit 都已知的条目优于部分已知的。
26
+ 5. **provider id 字母序** —— 稳定的兜底。
27
+
28
+ 裸 id 对最后一段路径段做大小写不敏感匹配,所以 `qwen3.7-max` 解析到 `Qwen/Qwen3.7-Max`,`kimi-k2.7-code` 解析到 `Kimi-K2.7-Code`。
29
+
30
+ ## 补全字段
31
+
32
+ | dsh 字段 | models.dev 来源 | 说明 |
33
+ |---|---|---|
34
+ | `name` | `name` | 显示名称 |
35
+ | `contextWindow` | `limit.context` | token 数 |
36
+ | `maxTokens` | `limit.output` | token 数 |
37
+ | `reasoningEfforts` | `reasoning_options[type=effort].values` | 恒等字典 `{high:"high", max:"max"}`;pi-ai 档位之外的取值(`default`/`none`/……)被过滤;`toggle`/`budget_tokens` 选项忽略 |
38
+ | `input` | `modalities.input` | 过滤到 `text`/`image`(pi-ai 仅接受这两种模态;`pdf`/`audio`/`video` 丢弃) |
39
+
40
+ 目录中无匹配的模型(例如本地网关模型 `hy3-paid`)保持原样,并在补全报告中列为 unmatched。
41
+
42
+ ## 目录缓存与更新
43
+
44
+ - 目录从 `https://models.dev/api.json` 拉取,缓存在 `~/.dsh/model-parameters/catalog.json`(约 4 MB)。
45
+ - 缓存超过 `ttlDays`(默认 **7 天**)后,在下一次 reconcile 时惰性刷新。
46
+ - 拉取失败则保留上次成功的缓存;完全没有缓存时插件什么都不补,直到刷新成功。
47
+ - 设置页有 **Update catalog & fill now** 按钮可强制刷新,并显示上次更新时间与新鲜度。
48
+
49
+ ## 设置页面
50
+
51
+ DSH 设置中会出现一个 "模型参数补全 / Model Parameters" 区块:
52
+
53
+ - 总开关 + 逐字段开关(`fillName`、`fillContext`、`fillMaxTokens`、`fillReasoning`、`fillInput`);
54
+ - 目录 TTL(天);
55
+ - 可选的 `provider → models.dev provider` 映射覆盖;
56
+ - 目录新鲜度卡片(条目数、provider 数、上次更新);
57
+ - 上次补全报告:补全的字段、涉及的 provider、未匹配的模型 id 列表。
58
+
59
+ 插件配置保存在 `model-parameters` 设置命名空间(`~/.dsh/settings.yaml`),例如:
60
+
61
+ ```yaml
62
+ model-parameters:
63
+ enabled: true
64
+ ttlDays: 7
65
+ fillName: true
66
+ fillContext: true
67
+ fillMaxTokens: true
68
+ fillReasoning: true
69
+ fillInput: true
70
+ providerMap: {}
71
+ officialProviders:
72
+ - deepseek
73
+ - openai
74
+ - anthropic
75
+ - google
76
+ - xai
77
+ ```
78
+
79
+ ## 安装
80
+
81
+ 通过 `dsh plugin` 命令安装(`web` 换成你的 profile 名):
82
+
83
+ **从 npm 安装**:
84
+
85
+ ```bash
86
+ dsh plugin --profile web add @fonlan/dsh-model-parameters
87
+ ```
88
+
89
+ **直接从 GitHub 安装**:
90
+
91
+ ```bash
92
+ dsh plugin --profile web add github:fonlan/dsh-model-parameters
93
+ ```
94
+
95
+ **卸载**:
96
+
97
+ ```bash
98
+ dsh plugin --profile web remove @fonlan/dsh-model-parameters
99
+ ```
100
+
101
+ ## 开发
102
+
103
+ ```bash
104
+ pnpm install
105
+ pnpm build # tsc 类型 + tsdown host 与 client bundle
106
+ pnpm typecheck
107
+ node scripts/verify-catalog.mjs # 用 models.dev dump 校验匹配逻辑
108
+ ```
109
+
110
+ ## License
111
+
112
+ MIT
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: model-parameters
3
+ name: '@fonlan/dsh-model-parameters'