agentsw 0.10.2 → 0.11.1

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
@@ -27,14 +27,17 @@ without touching the settings you hand-tuned.
27
27
  `npx agentsw use myproxy -a codex,omp` is one line in a provisioning script; nine GUI
28
28
  clicks are not.
29
29
  - **`--dry-run` prints redacted diffs.** Preview changes without writing files or creating
30
- backups. Existing configuration files are backed up when actual changes are committed.
30
+ backups — the provider store included, so a previewed `sync` does not leave its refreshed
31
+ model list behind. Existing configuration files are backed up when changes are committed.
31
32
  - **Non-destructive by design.** Only the fields agentsw owns are rewritten. Provider-level
32
33
  keys it does not model — `authHeader`, `headers`, `compat`, `discovery` — per-model extras
33
34
  like `thinkingLevelMap`, and YAML comments all survive a re-sync.
34
35
  - **Model metadata, not just an id list.** Reseller `/v1/models` endpoints return bare ids.
35
36
  agentsw enriches them from [models.dev](https://models.dev), automatically fills meaningful gaps from AI Gateway when needed, and writes what each app
36
37
  actually reads: `thinkingLevelMap` for pi/prime, `limit`/`attachment` for opencode,
37
- `contextWindow`/`maxTokens` for omp, `reasoningEfforts`/`input` for dsh.
38
+ `contextWindow`/`maxTokens` for omp, `reasoningEfforts`/`input` for dsh. Limits the endpoint declares for
39
+ its own models outrank the catalogs, so one model cannot end up with two different context windows
40
+ depending on which provider lists it.
38
41
  - **Adopts what you already have** — including [cc-switch](https://github.com/farion1231/cc-switch).
39
42
  `import` scans every installed agent *and* cc-switch's own store, merges duplicates
40
43
  (same protocol + normalized endpoint + credentials), and never writes back to either.
@@ -94,9 +97,10 @@ agentsw # once installed globally; the short alias `asw` is id
94
97
 
95
98
  **Run it with no arguments and you get a menu — that is the whole tool.** Every action lives
96
99
  there: add a provider (auto-detect or manual setup), import the providers already configured in
97
- your agents, switch provider and default model, re-sync, update a model list, configure model
98
- metadata, rename or delete, install/upgrade an agent, change language. On the first run it asks
99
- for English or 简体中文 and offers to adopt what your agents are already using.
100
+ your agents, switch provider and default model, sync a provider (fetch its current model list,
101
+ then write it to your agents), configure model metadata, rename or delete, install/upgrade an
102
+ agent, change language. On the first run it asks for English or 简体中文 and offers to adopt what
103
+ your agents are already using.
100
104
 
101
105
  Each menu action has a command equivalent for scripts, CI and headless machines — see
102
106
  [Commands](#commands). Examples below are written as `asw`; without a global install, run them
@@ -202,8 +206,9 @@ use `--all` explicitly in scripts. Model discovery may update the local metadata
202
206
 
203
207
  ## Model discovery filters
204
208
 
205
- `--discover` lists model ids from the provider's `/v1/models`, then enriches each id from
206
- models.dev first, with automatic AI Gateway supplementation when needed. Reseller lists are noisy,
209
+ `--discover` lists model ids from the provider's `/v1/models`, then enriches each id from models.dev first,
210
+ with automatic AI Gateway supplementation when needed. Limits the provider declares for its own models in
211
+ that same listing win over what a catalog claims for them; ids it lists bare are enriched as before. Reseller lists are noisy,
207
212
  so filters are persisted per provider and re-applied on every `discover`:
208
213
 
209
214
  ```bash
@@ -213,6 +218,10 @@ asw add -y --discover --exclude "*embedding*,*video*" --id myproxy ...
213
218
  asw add -y --discover --no-dedup ... # keep duplicates
214
219
  asw discover myproxy --include "gpt-*,glm-*" # update the persisted filter
215
220
  asw discover myproxy --no-filter # clear it
221
+
222
+ # Refresh several providers' model lists without writing any agent config.
223
+ asw discover --all
224
+ asw discover myproxy backup-proxy
216
225
  ```
217
226
 
218
227
  Explicit `--models` entries and the default model are never filtered out.
@@ -249,9 +258,16 @@ asw refresh --provider myproxy --metadata-mode off
249
258
  # Return an explicitly disabled provider to automatic mode
250
259
  asw refresh --provider myproxy --metadata-mode auto
251
260
 
252
- # Preview and apply separately; sync does not query catalogs
261
+ # Preview and apply separately. Sync fetches the model list first;
262
+ # --dry-run still fetches, so the preview matches a real sync, but saves nothing;
263
+ # --no-refresh writes the saved list without touching the network.
253
264
  asw sync --provider myproxy --dry-run
254
265
  asw sync --provider myproxy
266
+ asw sync --provider myproxy --no-refresh
267
+
268
+ # Refresh and push several providers in one run.
269
+ asw sync --all
270
+ asw sync --provider myproxy,backup-proxy
255
271
  ```
256
272
 
257
273
  The menu's **Configure and refresh model metadata** action offers **Automatic (recommended)**,
@@ -264,9 +280,12 @@ Without `--provider`, `refresh` applies to all providers, including any supplied
264
280
  `--gateway-models` replaces the whole alias map (`{}` clears it); aliases do not change the saved mode or override `off`.
265
281
  Import still skips already configured accounts.
266
282
 
267
- - **Field-level priority:** manual values > models.dev > Gateway gap filling. Tracked automatic values may
268
- refresh; subsequent manual edits are retained. Legacy values without provenance are conservatively treated
269
- as manual overrides. Unmodeled extension fields survive enrichment too.
283
+ - **Field-level priority:** manual values > the endpoint's own declaration > models.dev > Gateway gap filling.
284
+ An endpoint that advertises `context_window_tokens`/`maximum_output_tokens`
285
+ (or their `context_length`/`max_output_tokens` spellings) for its own list is authoritative for its own
286
+ route, so those limits are written instead of a catalog's estimate for the same model. Tracked automatic
287
+ values may refresh; subsequent manual edits are retained. Legacy values without provenance are conservatively
288
+ treated as manual overrides. Unmodeled extension fields survive enrichment too.
270
289
  - **Exact identities:** automatic lookup can map a bare, case-sensitive ID (no `/`) to a unique Gateway
271
290
  `creator/model` identity when models.dev evidence is absent or agrees. Ambiguous creator evidence in either
272
291
  catalog is rejected; custom or ambiguous names need explicit aliases. Qualified IDs never have their prefixes
@@ -286,9 +305,28 @@ Import still skips already configured accounts.
286
305
  Gateway has a separate 24-hour cache; a failed request is retried once before falling back to stale cached data
287
306
  (or skipping supplementation when there is none). `AGENTSW_DEBUG=1` reports why an attempt failed, and
288
307
  `AGENTSW_GATEWAY_TIMEOUT_MS` overrides the 15-second whole-request budget.
289
- - **Automatic lookup is not automatic sync:** enrichment updates saved metadata during add/quick/discover/import/refresh.
290
- It does not add an automatic push to agents. Sync behavior is unchanged: ordinary `sync` only writes saved settings
291
- and fetches neither model lists nor metadata catalogs.
308
+ - **A model the endpoint dropped is reported, not hidden.** A refresh keeps the default and small
309
+ model even when the listing stops carrying them — one flaky listing must not delete the model you
310
+ chose — but being kept also keeps them out of the "removed upstream" line, so they are named in a
311
+ `warning:` after the apply and in `--json` as `refreshed.missing`. That is what a renamed model
312
+ looks like from the client side: the agents keep working with an id the endpoint now rejects.
313
+ - **One selection everywhere:** `--all` and a comma-separated `-p a,b` mean the same thing on `sync`, `discover`
314
+ and `refresh`, and `discover` also takes its ids positionally (`discover alpha beta`). Every id is resolved before
315
+ the first request, so a typo fails before half the run is on disk. Omitting the selection keeps each command's own
316
+ default: the active provider for `sync` and `discover`, every provider for `refresh`.
317
+ - **Syncing several providers:** `sync --all` takes every configured provider and `-p a,b` takes a list; each is
318
+ refreshed and written in turn, finishing with the active provider so whatever "current" pointer an app keeps ends
319
+ up where the store says it should. An app that names one provider instead of a map — Claude Code's env block — is
320
+ written once rather than once per provider: it gets the active provider when it can accept it, or the single
321
+ provider in the run that it can (Claude Code takes anthropic endpoints only, so an openai active provider does not
322
+ starve it). With several candidates and the active provider not among them the choice is yours, so the app keeps
323
+ pointing where it already does: syncing is not switching. A provider whose endpoint cannot be reached is reported
324
+ and skipped, the rest still sync, and the run exits non-zero.
325
+ - **Automatic lookup is not an automatic push:** enrichment updates saved metadata during add/quick/discover/import/refresh
326
+ and never writes agent configs by itself. `sync` is the push, and it refreshes first: it fetches the provider's model
327
+ list, re-enriches it from the catalogs, saves the store, then applies it. `sync --dry-run` fetches the same list so
328
+ the preview is accurate but saves neither it nor the configs. `sync --no-refresh` writes the saved list without
329
+ fetching, and `discover` stops after the refresh without writing any agent.
292
330
 
293
331
  ## Commands
294
332
 
@@ -301,11 +339,11 @@ Import still skips already configured accounts.
301
339
  | `list` / `status` | configured providers / what each agent points at |
302
340
  | `list --apps omp,prime` | list agent-local provider IDs, including entries absent from agentsw |
303
341
  | `rename <id> <new-id>` | back up and migrate the ID and config references; supports `--dry-run` |
304
- | `use <id>` | switch every detected agent; `-a codex,omp`, `-m <model>`, `--dry-run` |
305
- | `sync` | re-apply the active provider (after an agent update, say) |
306
- | `discover <id> [--sync]` | refresh the model list + metadata from `/v1/models` |
342
+ | `use <id>` | switch every detected agent; `-a codex,omp`, `-m <model>`, `--small-model <id>` / `--no-small-model`, `--dry-run` |
343
+ | `sync` | refresh each provider's model list, then re-apply it to the agent configs; `--all` or `-p a,b` for several, `--no-refresh` writes the saved list |
344
+ | `discover [ids...] [--sync]` | refresh the model list + metadata from `/v1/models`; `--all` or several ids for more than one, no id for the active provider; `--sync` pushes them to the agents |
307
345
  | `models [query]` | search the models.dev catalog (`-r` refresh the cache, `-l <n>` limit rows) |
308
- | `refresh [--provider <id>]` | refresh saved metadata and optionally configure Gateway; keep the model list |
346
+ | `refresh [--provider <ids>]` | refresh saved metadata and optionally configure Gateway; keep the model list; every provider unless `-p a,b` narrows it |
309
347
  | `models --provider <id> --metadata` | inspect field sources, conflicts and reference pricing as JSON |
310
348
  | `prune <id>` / `remove <id> [--prune]` | remove from app configs / from the store |
311
349
  | `remove <id> --apps omp` | delete only the selected app's entry; supports `--dry-run` |
package/README.zh-CN.md CHANGED
@@ -25,15 +25,15 @@
25
25
 
26
26
  - **它能去桌面应用去不了的地方。** 无头服务器、容器、devcontainer、CI。
27
27
  `npx agentsw use myproxy -a codex,omp` 在开机脚本里是一行;GUI 点九次不是。
28
- - **`--dry-run` 输出脱敏 diff。** 写盘前先预览;预览不写文件、不创建备份。
29
- 正式提交变更时,已有配置文件才会先备份。
28
+ - **`--dry-run` 输出脱敏 diff。** 写盘前先预览;预览不写文件、不创建备份,供应商 store 也一样——
29
+ 预览 `sync` 不会把刷新到的模型列表留在配置里。正式提交变更时,已有配置文件才会先备份。
30
30
  - **默认不破坏现有配置。** 只覆盖 agentsw 自己管理的字段:它不建模的供应商级键
31
31
  (`authHeader`、`headers`、`compat`、`discovery`)、`thinkingLevelMap` 之类的模型级字段、
32
32
  以及 YAML 注释,都会在重新同步后原样保留。
33
33
  - **写的是元数据,不只是模型 id。** 转售商 `/v1/models` 只返回裸 id;agentsw 从
34
34
  [models.dev](https://models.dev) 优先补全,并在有实际缺口时自动查询 AI Gateway,按各应用真正读取的字段下发:pi/prime 的
35
35
  `thinkingLevelMap`、opencode 的 `limit`/`attachment`、omp 的 `contextWindow`/`maxTokens`、
36
- dsh 的 `reasoningEfforts`/`input`。
36
+ dsh 的 `reasoningEfforts`/`input`。端点自己声明的上下文/输出上限优先于目录,避免同一模型在不同供应商下被写成不同窗口。
37
37
  - **接管你已有的配置——包括 [cc-switch](https://github.com/farion1231/cc-switch)。**
38
38
  `import` 会扫描所有已安装的智能体**以及 cc-switch 自己的存储**,合并重复项
39
39
  (相同协议 + 归一化端点 + 凭据),并且对两者都只读不写。
@@ -87,7 +87,7 @@ agentsw # 全局安装后可用;短名 `asw` 完全等价
87
87
  ```
88
88
 
89
89
  **不带参数运行就是一个菜单——整个工具都在里面。** 添加供应商(自动识别或手动设置)、导入各智能体
90
- 已有的供应商、切换供应商和默认模型、重新同步、更新模型列表、设置模型参数补充源、重命名或删除、
90
+ 已有的供应商、切换供应商和默认模型、同步供应商(重新获取模型列表再写入)、设置模型参数补充源、重命名或删除、
91
91
  安装/升级智能体、切换语言。首次运行会先问你要 English 还是简体中文,并提议接管你各智能体已经在用的配置。
92
92
 
93
93
  菜单里的每项操作都有对应的命令,方便脚本、CI 和无头机器——见 [命令](#命令)。
@@ -191,6 +191,7 @@ imported zhipu-glm · anthropic · https://open.bigmodel.cn/api/anthropic · 1 m
191
191
  ## 模型发现过滤
192
192
 
193
193
  `--discover` 从供应商 `/v1/models` 拉取模型 id,优先从 models.dev 补全元数据,必要时自动查询 AI Gateway。
194
+ 同一份列表里供应商为自家模型声明的上下文/输出上限优先于目录的估算,只给出裸 id 的模型仍按原逻辑补全。
194
195
  转售商列表噪音大,过滤规则持久化在供应商上,每次 `discover` 自动复用:
195
196
 
196
197
  ```bash
@@ -200,6 +201,10 @@ asw add -y --discover --exclude "*embedding*,*video*" --id myproxy ...
200
201
  asw add -y --discover --no-dedup ... # 保留重复项
201
202
  asw discover myproxy --include "gpt-*,glm-*" # 更新持久化过滤规则
202
203
  asw discover myproxy --no-filter # 清除规则
204
+
205
+ # 只刷新模型列表、不写任何智能体配置,可一次多个。
206
+ asw discover --all
207
+ asw discover myproxy backup-proxy
203
208
  ```
204
209
 
205
210
  手动 `--models` 指定的 id 和默认模型永不被过滤。
@@ -234,9 +239,16 @@ asw refresh --provider myproxy --metadata-mode off
234
239
  # 将显式关闭的供应商恢复为自动模式
235
240
  asw refresh --provider myproxy --metadata-mode auto
236
241
 
237
- # 单独预览、同步;sync 不查询目录
242
+ # 单独预览、应用。sync 会先重新获取模型列表;
243
+ # --dry-run 同样会获取,预览因此与真实 sync 一致,但什么都不保存;
244
+ # --no-refresh 则完全不联网,只写入已保存的列表。
238
245
  asw sync --provider myproxy --dry-run
239
246
  asw sync --provider myproxy
247
+ asw sync --provider myproxy --no-refresh
248
+
249
+ # 一次刷新并推送多个供应商。
250
+ asw sync --all
251
+ asw sync --provider myproxy,backup-proxy
240
252
  ```
241
253
 
242
254
  交互菜单的“设置并刷新模型参数补充源”提供“自动按需(推荐)”“始终补充”“关闭”,
@@ -249,7 +261,9 @@ asw sync --provider myproxy
249
261
  `--gateway-models` 替换整个映射,传 `{}` 清空;映射不会更改保存的模式,也不会覆盖 `off`。
250
262
  导入仍跳过已经配置的账号。
251
263
 
252
- - **按字段合并:** 用户手动值优先,其次 models.dev,最后 Gateway 补缺。已记录来源的自动值可以刷新,
264
+ - **按字段合并:** 用户手动值优先,其次端点自己声明的值,然后 models.dev,最后 Gateway 补缺。
265
+ 端点在 `/v1/models` 中为自家模型声明了 `context_window_tokens`/`maximum_output_tokens`(或
266
+ `context_length`/`max_output_tokens` 写法)时,以它为准而不是目录对同一模型的估算。已记录来源的自动值可以刷新,
253
267
  手动修改后会保留;旧版本中没有来源记录的已有值保守视为手动值,不强制覆盖。未知扩展字段也保留。
254
268
  - **精确匹配:** 不含 `/` 的裸 ID 可按大小写精确匹配唯一的 Gateway `creator/model` 身份,
255
269
  前提是 models.dev 没有身份线索或线索一致。任一目录中的创建者身份有歧义时拒绝自动匹配;
@@ -266,8 +280,25 @@ asw sync --provider myproxy
266
280
  审计信息仅保存在 agentsw,不写入智能体运行配置。Gateway 目录独立缓存 24 小时;请求失败会先重试一次,
267
281
  仍失败才使用旧缓存,无缓存时只跳过补充。`AGENTSW_DEBUG=1` 会说明该次尝试失败的原因,
268
282
  `AGENTSW_GATEWAY_TIMEOUT_MS` 可覆盖默认 15 秒的整体请求预算。
269
- - **自动查询不等于自动同步:** 添加、快速添加、发现、导入、刷新时补全保存的元数据,并不新增自动推送。
270
- 同步行为不变:普通 `sync` 仅写入已保存的设置,既不获取模型列表,也不请求元数据目录。
283
+ - **端点下掉的模型会被明确报出,而不是悄悄保留。** 刷新时即使列表里不再有默认模型和小模型,也会保留它们——
284
+ 一次抖动的列表不该删掉你选定的模型——但「removed upstream」里就不会出现它们了,所以改为在写入之后用
285
+ `warning:` 点名,`--json` 里对应 `refreshed.missing`。模型被改名时从客户端看到的就是这个现象:
286
+ 配置照旧,而端点已经不认这个 id 了。
287
+ - **选择供应商的方式统一:** `sync`、`discover`、`refresh` 都支持 `--all` 和逗号分隔的 `-p a,b`,
288
+ `discover` 还可以直接写位置参数(`discover alpha beta`)。所有 id 在第一次请求前就全部解析,
289
+ 写错一个会在任何东西落盘之前失败。不指定时各命令保持自己的默认:`sync` 和 `discover` 取当前供应商,
290
+ `refresh` 取全部。
291
+ - **一次同步多个供应商:** `sync --all` 取全部已配置的供应商,`-p a,b` 取指定列表;逐个刷新并写入,
292
+ 并把当前供应商放在最后,这样各智能体记录的“当前指向”最终就停在 store 所说的那一个。
293
+ 只记录单个供应商(而非供应商表)的应用——例如 Claude Code 的 env 块——只写一次而不是每个供应商写一遍:
294
+ 能接受当前供应商时就写它,不能接受时(Claude Code 只收 anthropic 端点,当前供应商却可能是 openai 的)
295
+ 就写本次同步里它唯一能接受的那个。若有多个候选且当前供应商不在其中,选择权在你,它保持原有指向:
296
+ 同步不是切换。
297
+ 某个供应商的端点不可达时会被报告并跳过,其余照常同步,整个运行以非零状态结束。
298
+ - **自动查询不等于自动推送:** 添加、快速添加、发现、导入、刷新时补全保存的元数据,永远不会自行写入智能体配置。
299
+ 推送是 `sync`,而且它先刷新:先获取供应商模型列表、按目录补全、保存到 store,再写入各智能体。
300
+ `sync --dry-run` 会获取同一份列表以保证预览准确,但既不保存列表也不写配置;
301
+ `sync --no-refresh` 不联网,只写入已保存的列表;`discover` 刷新完就停,不写任何智能体。
271
302
 
272
303
  ## 命令
273
304
 
@@ -280,11 +311,11 @@ asw sync --provider myproxy
280
311
  | `list` / `status` | 已配置的供应商 / 各智能体当前指向 |
281
312
  | `list --apps omp,prime` | 列出智能体本地供应商 ID,包括未导入 agentsw 的条目 |
282
313
  | `rename <id> <new-id>` | 备份并迁移 ID 和配置引用,支持 `--dry-run` |
283
- | `use <id>` | 切换所有检测到的智能体;`-a codex,omp`、`-m <model>`、`--dry-run` |
284
- | `sync` | 重新应用当前供应商(比如某个智能体升级之后) |
285
- | `discover <id> [--sync]` | 从 `/v1/models` 刷新模型列表与元数据 |
314
+ | `use <id>` | 切换所有检测到的智能体;`-a codex,omp`、`-m <model>`、`--small-model <id>` / `--no-small-model`、`--dry-run` |
315
+ | `sync` | 先刷新各供应商的模型列表,再写入各智能体配置;`--all` 或 `-p a,b` 可一次处理多个,`--no-refresh` 只写已保存的列表 |
316
+ | `discover [ids...] [--sync]` | 从 `/v1/models` 刷新模型列表与元数据;`--all` 或多个 id 可一次处理多个,不给 id 则取当前供应商;`--sync` 再推送到各智能体 |
286
317
  | `models [query]` | 搜索 models.dev 目录(`-r` 强制刷新缓存,`-l <n>` 限制条数) |
287
- | `refresh [--provider <id>]` | 刷新已有模型参数,可设置 Gateway 补充源,不改变模型列表 |
318
+ | `refresh [--provider <ids>]` | 刷新已有模型参数,可设置 Gateway 补充源,不改变模型列表;默认全部,`-p a,b` 可缩小范围 |
288
319
  | `models --provider <id> --metadata` | 以 JSON 查看字段来源、冲突和参考价格 |
289
320
  | `prune <id>` / `remove <id> [--prune]` | 从各应用配置中清除 / 从存储中删除 |
290
321
  | `remove <id> --apps omp` | 仅删除指定智能体内的条目,支持 `--dry-run` |