pi-models-discovery 1.3.0 → 1.4.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 CHANGED
@@ -59,7 +59,20 @@ Forces a rediscovery of every discovery provider and updates the local cache, no
59
59
  - **Offline / fetch failure**: handwritten `models` in models.json (if any) are kept as a fallback, and an explicit warning is surfaced via in-session notify — never a silent degradation. One provider failing does not affect the others.
60
60
  - **apiKey resolution** (discovery request only): supports literals and `$ENV_VAR` / `${ENV_VAR}` interpolation; `!command` values skip discovery with an explicit warning (chat requests are still resolved by pi itself and are unaffected).
61
61
  - Default parameters for discovered models: `reasoning: true`, `input: ["text", "image"]`, zero cost, `contextWindow` 1M, `maxTokens` 64K, `compat.supportsDeveloperRole: false`. Provider-level `compat` is merged into every discovered model.
62
- - Discovered models do not declare `thinkingLevelMap`, so pi applies the provider's default thinking-level mapping (standard levels through `high`; the extended `xhigh` / `max` levels are not exposed). `/models` cannot report per-model thinking capability, and the extension does not guess it — declare `thinkingLevelMap` yourself in a handwritten `models` entry if a provider needs something different.
62
+ - Discovered models declare `thinkingLevelMap: { xhigh: "xhigh", max: "max" }`, so `xhigh` and `max` appear in `/thinking`; the standard levels stay omitted and keep pi's provider default mapping. `/models` cannot report per-model thinking capability, so this is a blanket default for every discovered model: when a provider rejects those levels, override it per model through `modelOverrides` in models.json (set `xhigh` / `max` to `null` to hide them), or declare the model yourself in a handwritten `models` entry.
63
+
64
+ ```json
65
+ {
66
+ "providers": {
67
+ "llm-proxy": {
68
+ "discoverModels": true,
69
+ "modelOverrides": {
70
+ "some-model": { "thinkingLevelMap": { "xhigh": null, "max": null } }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
63
76
  - Model metadata may carry `name` / `context_window` (or `contextWindow`) / `max_tokens` (or `maxTokens`); defaults are used when absent.
64
77
 
65
78
  The old `/model-discovery`, `/model-discovery-refresh`, `/pi-model-discovery`, and `/pi-model-discovery-refresh` names remain available as compatibility aliases.
package/README.zh-CN.md CHANGED
@@ -59,7 +59,20 @@ pi install npm:pi-models-discovery
59
59
  - **离线 / 拉取失败**:保留 models.json 里手写的 `models`(如有,作为回退),并通过会话内 notify 显式警告,不静默降级;单个 provider 失败不影响其他 provider。
60
60
  - **apiKey 解析**(仅发现请求):支持字面量与 `$ENV_VAR` / `${ENV_VAR}` 插值;`!command` 形式跳过发现并显式警告(聊天请求仍由 pi 自身解析执行,不受影响)。
61
61
  - 发现的模型默认参数:`reasoning: true`、`input: ["text", "image"]`、cost 全 0、`contextWindow` 1M、`maxTokens` 64K、`compat.supportsDeveloperRole: false`;provider 级 `compat` 会合并进每个发现的模型。
62
- - 发现的模型不声明 `thinkingLevelMap`,由 pi 按 provider 默认映射决定可选思考等级(标准等级直至 `high`,不提供扩展的 `xhigh` / `max`)。`/models` 无法逐个模型返回思考能力,扩展也不替它猜;个别 provider 需要不同映射时,请在 models.json 里手写该模型的 `models` 条目自行声明。
62
+ - 发现的模型声明 `thinkingLevelMap: { xhigh: "xhigh", max: "max" }`,让 `xhigh` / `max` 出现在 `/thinking`;标准档位保持缺省,仍由 pi 的 provider 默认映射决定。`/models` 无法逐个模型返回思考能力,所以这是对所有发现模型一刀切的默认值:某个 provider 拒绝这些档位时,在 models.json 的 `modelOverrides` 里按 model.id 覆盖(把 `xhigh` / `max` 置 `null` 可隐藏),或改用手写 `models` 条目自行声明。
63
+
64
+ ```json
65
+ {
66
+ "providers": {
67
+ "llm-proxy": {
68
+ "discoverModels": true,
69
+ "modelOverrides": {
70
+ "some-model": { "thinkingLevelMap": { "xhigh": null, "max": null } }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
63
76
  - 模型元数据可携带 `name` / `context_window`(或 `contextWindow`)/ `max_tokens`(或 `maxTokens`),缺失时用默认值。
64
77
 
65
78
  旧的 `/model-discovery`、`/model-discovery-refresh`、`/pi-model-discovery` 和 `/pi-model-discovery-refresh` 名称仍作为兼容别名保留。
package/SKILL.md CHANGED
@@ -21,6 +21,10 @@ description: "配置与排查 models.json 的动态模型发现、缓存刷新
21
21
 
22
22
  `apiKey` 可用字面量、`$ENV_VAR` 或 `${ENV_VAR}`;`!command` 不用于发现请求,会被跳过并警告。不要把密钥写入 Skill、仓库或回复。
23
23
 
24
+ ## 思考等级
25
+
26
+ 发现的模型默认声明 `thinkingLevelMap: { xhigh: "xhigh", max: "max" }`(对所有模型一刀切)。若某个模型不认 `xhigh` / `max`,用 models.json 的 `modelOverrides` 按 model.id 把它们置 `null`。
27
+
24
28
  ## 验证
25
29
 
26
30
  - `/config:model-discovery-refresh` 强制联网刷新并更新缓存;旧命令名仅为兼容别名。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-models-discovery",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Pi extension: discover models from {baseUrl}/models for providers marked with discoverModels in models.json",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -57,7 +57,7 @@
57
57
  "@earendil-works/pi-coding-agent": ">=0.80.0"
58
58
  },
59
59
  "dependencies": {
60
- "pi-extensions-i18n": "^0.6.0"
60
+ "pi-extensions-i18n": "^0.8.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@earendil-works/pi-ai": "0.85.1",
package/src/index.ts CHANGED
@@ -35,6 +35,9 @@
35
35
  * - 注册 refreshModels:打开 /model 触发在线刷新时重新发现;
36
36
  * 离线初始化(allowNetwork=false)返回上次成功列表(含缓存),尚无成功记录时抛错,
37
37
  * 以免空列表清掉 models.json 手写 models。
38
+ * - 发现模型默认声明 thinkingLevelMap { xhigh: "xhigh", max: "max" },让 xhigh/max 出现在
39
+ * /thinking;标准档位缺省沿用 pi 的 provider 默认映射。这是对所有发现模型一刀切的默认值,
40
+ * 上游不认这些值时用 models.json 的 provider.modelOverrides 按 model.id 覆盖。
38
41
  * - 发现请求的 apiKey 解析仅支持字面量与 $ENV_VAR/${ENV_VAR} 插值;
39
42
  * "!command" 形式的 apiKey 跳过发现(显式警告),pi 发起聊天请求时仍由 pi 自身解析。
40
43
  * - /config:model-discovery 命令对 models.json 的修改立即生效(registerProvider 运行时可直接调用);
@@ -48,7 +51,7 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
48
51
  import type { ExtensionAPI, ProviderModelConfig } from "@earendil-works/pi-coding-agent";
49
52
  import { mkdir, readFile, writeFile } from "node:fs/promises";
50
53
  import { dirname, join } from "node:path";
51
- import { createTranslator, installNoticeRenderer, loadCatalog, notifyWithSource, type NoticeColor, type NoticeSource } from "pi-extensions-i18n";
54
+ import { NOTICE_TAG_COLOR, createTranslator, installNoticeRenderer, loadCatalog, notifyWithSource, type NoticeColor, type NoticeSource } from "pi-extensions-i18n";
52
55
 
53
56
  const i18n = createTranslator(loadCatalog(new URL("../locales/index.json", import.meta.url)));
54
57
 
@@ -57,8 +60,8 @@ const DISCOVERY_MARKER = "discoverModels";
57
60
  const LOG_PREFIX = "[model-discovery]";
58
61
  /** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
59
62
  const NOTICE_TAG = "models";
60
- /** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
61
- const NOTICE_COLOR: NoticeColor = "accent";
63
+ /** 提示标签颜色:所有扩展统一用弱化色,来源靠 tag 文本区分,不靠颜色。 */
64
+ const NOTICE_COLOR: NoticeColor = NOTICE_TAG_COLOR;
62
65
  /** 本扩展的提示来源。 */
63
66
  const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
64
67
  const API_CHOICES = ["openai-completions", "anthropic-messages", "openai-responses", "google-generative-ai"] as const;
@@ -288,7 +291,7 @@ function resolveEnvValue(raw: string): { value: string | null; error: string | n
288
291
  return { value, error: null };
289
292
  }
290
293
 
291
- function buildModel(
294
+ export function buildModel(
292
295
  id: string,
293
296
  name: string | undefined,
294
297
  contextWindow: number | undefined,
@@ -299,6 +302,9 @@ function buildModel(
299
302
  id,
300
303
  name: name ?? id,
301
304
  reasoning: true,
305
+ // xhigh/max 必须给非 null 值才会出现在 /thinking(缺省键等同不支持);
306
+ // 标准档位保持缺省,仍走 pi 的 provider 默认映射,语义不变。
307
+ thinkingLevelMap: { xhigh: "xhigh", max: "max" },
302
308
  input: ["text", "image"],
303
309
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
304
310
  contextWindow: contextWindow ?? 1_000_000,