@astralyn/pi 0.87.0 → 0.87.2

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.
Files changed (301) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/bundle/chunks/{anthropic-messages-R2LYJUDD.js → anthropic-messages-XWFTZP2N.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-INDBRWNK.js → chunk-NBIUJDV6.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-RKLIHRPH.js → chunk-RFLBIA5Z.js} +82 -82
  5. package/dist/bundle/chunks/github-copilot.js +1 -1
  6. package/dist/bundle/chunks/{openai-completions-JZCEEJ43.js → openai-completions-SHS3CAEL.js} +1 -1
  7. package/dist/bundle/chunks/{virtual-modules-CG7NJ5WO.js → virtual-modules-GOHLE5JL.js} +1 -1
  8. package/dist/bundle/cli.js +1 -1
  9. package/dist/bundle/index.js +1 -1
  10. package/dist/bundle/rpc-entry.js +1 -1
  11. package/dist/cli/args.d.ts.map +1 -1
  12. package/dist/cli/args.js +14 -4
  13. package/dist/cli/args.js.map +1 -1
  14. package/dist/config.d.ts +1 -1
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/core/agent-session-runtime.d.ts +9 -0
  18. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  19. package/dist/core/agent-session-runtime.js +158 -157
  20. package/dist/core/agent-session-runtime.js.map +1 -1
  21. package/dist/core/agent-session.d.ts +30 -0
  22. package/dist/core/agent-session.d.ts.map +1 -1
  23. package/dist/core/agent-session.js +514 -443
  24. package/dist/core/agent-session.js.map +1 -1
  25. package/dist/core/background/service.d.ts +9 -0
  26. package/dist/core/background/service.d.ts.map +1 -1
  27. package/dist/core/background/service.js +13 -1
  28. package/dist/core/background/service.js.map +1 -1
  29. package/dist/core/background/session.d.ts +5 -0
  30. package/dist/core/background/session.d.ts.map +1 -1
  31. package/dist/core/background/session.js +2 -1
  32. package/dist/core/background/session.js.map +1 -1
  33. package/dist/core/background/types.d.ts +2 -0
  34. package/dist/core/background/types.d.ts.map +1 -1
  35. package/dist/core/background/types.js.map +1 -1
  36. package/dist/core/compaction/compaction.js +9 -9
  37. package/dist/core/compaction/compaction.js.map +1 -1
  38. package/dist/core/extensions/distribution-api.d.ts +41 -0
  39. package/dist/core/extensions/distribution-api.d.ts.map +1 -0
  40. package/dist/core/extensions/distribution-api.js +12 -0
  41. package/dist/core/extensions/distribution-api.js.map +1 -0
  42. package/dist/core/extensions/index.d.ts +1 -1
  43. package/dist/core/extensions/index.d.ts.map +1 -1
  44. package/dist/core/extensions/index.js.map +1 -1
  45. package/dist/core/extensions/loader.d.ts.map +1 -1
  46. package/dist/core/extensions/loader.js +1 -0
  47. package/dist/core/extensions/loader.js.map +1 -1
  48. package/dist/core/extensions/runner.d.ts.map +1 -1
  49. package/dist/core/extensions/runner.js +0 -2
  50. package/dist/core/extensions/runner.js.map +1 -1
  51. package/dist/core/extensions/types.d.ts +15 -45
  52. package/dist/core/extensions/types.d.ts.map +1 -1
  53. package/dist/core/extensions/types.js +1 -11
  54. package/dist/core/extensions/types.js.map +1 -1
  55. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  56. package/dist/core/extensions/virtual-modules.js +2 -1
  57. package/dist/core/extensions/virtual-modules.js.map +1 -1
  58. package/dist/core/keybinding-registry.d.ts +11 -0
  59. package/dist/core/keybinding-registry.d.ts.map +1 -0
  60. package/dist/core/keybinding-registry.js +24 -0
  61. package/dist/core/keybinding-registry.js.map +1 -0
  62. package/dist/core/keybindings.d.ts +4 -64
  63. package/dist/core/keybindings.d.ts.map +1 -1
  64. package/dist/core/keybindings.js +2 -41
  65. package/dist/core/keybindings.js.map +1 -1
  66. package/dist/core/model-config.d.ts +70 -2
  67. package/dist/core/model-config.d.ts.map +1 -1
  68. package/dist/core/model-config.js +2 -26
  69. package/dist/core/model-config.js.map +1 -1
  70. package/dist/core/model-resolver.js +1 -1
  71. package/dist/core/model-resolver.js.map +1 -1
  72. package/dist/core/resource-loader.d.ts.map +1 -1
  73. package/dist/core/resource-loader.js +5 -11
  74. package/dist/core/resource-loader.js.map +1 -1
  75. package/dist/core/tools/bash.d.ts.map +1 -1
  76. package/dist/core/tools/bash.js +2 -2
  77. package/dist/core/tools/bash.js.map +1 -1
  78. package/dist/core/tools/shell-execution.d.ts +1 -0
  79. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  80. package/dist/core/tools/shell-execution.js +21 -0
  81. package/dist/core/tools/shell-execution.js.map +1 -1
  82. package/dist/core/trust-manager.d.ts.map +1 -1
  83. package/dist/core/trust-manager.js +11 -48
  84. package/dist/core/trust-manager.js.map +1 -1
  85. package/dist/extensions/background/index.d.ts +2 -0
  86. package/dist/extensions/background/index.d.ts.map +1 -1
  87. package/dist/extensions/background/index.js +17 -0
  88. package/dist/extensions/background/index.js.map +1 -1
  89. package/dist/extensions/background/keybindings.d.ts +10 -0
  90. package/dist/extensions/background/keybindings.d.ts.map +1 -0
  91. package/dist/extensions/background/keybindings.js +14 -0
  92. package/dist/extensions/background/keybindings.js.map +1 -0
  93. package/dist/extensions/background/manager.d.ts +2 -0
  94. package/dist/extensions/background/manager.d.ts.map +1 -1
  95. package/dist/extensions/background/manager.js +1 -0
  96. package/dist/extensions/background/manager.js.map +1 -1
  97. package/dist/extensions/btw/controller.d.ts +1 -0
  98. package/dist/extensions/btw/controller.d.ts.map +1 -1
  99. package/dist/extensions/btw/controller.js +5 -5
  100. package/dist/extensions/btw/controller.js.map +1 -1
  101. package/dist/extensions/btw/index.js +1 -2
  102. package/dist/extensions/btw/index.js.map +1 -1
  103. package/dist/extensions/btw/keybindings.d.ts +10 -0
  104. package/dist/extensions/btw/keybindings.d.ts.map +1 -0
  105. package/dist/extensions/btw/keybindings.js +8 -0
  106. package/dist/extensions/btw/keybindings.js.map +1 -0
  107. package/dist/extensions/btw/panel.d.ts +1 -0
  108. package/dist/extensions/btw/panel.d.ts.map +1 -1
  109. package/dist/extensions/btw/panel.js +1 -0
  110. package/dist/extensions/btw/panel.js.map +1 -1
  111. package/dist/extensions/list-keybindings.d.ts +8 -0
  112. package/dist/extensions/list-keybindings.d.ts.map +1 -0
  113. package/dist/extensions/list-keybindings.js +8 -0
  114. package/dist/extensions/list-keybindings.js.map +1 -0
  115. package/dist/extensions/provider/compat-fields.d.ts.map +1 -1
  116. package/dist/extensions/provider/compat-fields.js +23 -3
  117. package/dist/extensions/provider/compat-fields.js.map +1 -1
  118. package/dist/extensions/provider/connection.d.ts.map +1 -1
  119. package/dist/extensions/provider/connection.js +1 -1
  120. package/dist/extensions/provider/connection.js.map +1 -1
  121. package/dist/extensions/provider/constants.d.ts +2 -0
  122. package/dist/extensions/provider/constants.d.ts.map +1 -1
  123. package/dist/extensions/provider/constants.js +2 -0
  124. package/dist/extensions/provider/constants.js.map +1 -1
  125. package/dist/extensions/provider/keybindings.d.ts +9 -0
  126. package/dist/extensions/provider/keybindings.d.ts.map +1 -0
  127. package/dist/extensions/provider/keybindings.js +12 -0
  128. package/dist/extensions/provider/keybindings.js.map +1 -0
  129. package/dist/extensions/provider/probe.d.ts +8 -4
  130. package/dist/extensions/provider/probe.d.ts.map +1 -1
  131. package/dist/extensions/provider/probe.js +169 -11
  132. package/dist/extensions/provider/probe.js.map +1 -1
  133. package/dist/extensions/provider/ui/builtin-data.d.ts +1 -0
  134. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  135. package/dist/extensions/provider/ui/builtin-data.js +1 -0
  136. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  137. package/dist/extensions/provider/ui/compat.d.ts +1 -0
  138. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  139. package/dist/extensions/provider/ui/compat.js +1 -0
  140. package/dist/extensions/provider/ui/compat.js.map +1 -1
  141. package/dist/extensions/provider/ui/dictionary.d.ts +1 -0
  142. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  143. package/dist/extensions/provider/ui/dictionary.js +1 -0
  144. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  145. package/dist/extensions/provider/ui/editor.d.ts +1 -0
  146. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  147. package/dist/extensions/provider/ui/editor.js +1 -0
  148. package/dist/extensions/provider/ui/editor.js.map +1 -1
  149. package/dist/extensions/provider/ui/fetch-models.d.ts +5 -3
  150. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  151. package/dist/extensions/provider/ui/fetch-models.js +28 -3
  152. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  153. package/dist/extensions/provider/ui/model-fields.d.ts +1 -0
  154. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  155. package/dist/extensions/provider/ui/model-fields.js +1 -0
  156. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  157. package/dist/extensions/provider/ui/model-options.d.ts +1 -0
  158. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  159. package/dist/extensions/provider/ui/model-options.js +1 -0
  160. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  161. package/dist/extensions/provider/ui/provider-fields.d.ts +1 -0
  162. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  163. package/dist/extensions/provider/ui/provider-fields.js +1 -0
  164. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  165. package/dist/extensions/question/dialog.d.ts +1 -0
  166. package/dist/extensions/question/dialog.d.ts.map +1 -1
  167. package/dist/extensions/question/dialog.js +1 -0
  168. package/dist/extensions/question/dialog.js.map +1 -1
  169. package/dist/extensions/question/keybindings.d.ts +2 -0
  170. package/dist/extensions/question/keybindings.d.ts.map +1 -0
  171. package/dist/extensions/question/keybindings.js +3 -0
  172. package/dist/extensions/question/keybindings.js.map +1 -0
  173. package/dist/index.d.ts +1 -1
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js.map +1 -1
  176. package/dist/modes/interactive/editor-host.d.ts +43 -0
  177. package/dist/modes/interactive/editor-host.d.ts.map +1 -0
  178. package/dist/modes/interactive/editor-host.js +83 -0
  179. package/dist/modes/interactive/editor-host.js.map +1 -0
  180. package/dist/modes/interactive/interactive-mode.d.ts +1 -11
  181. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  182. package/dist/modes/interactive/interactive-mode.js +300 -360
  183. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  184. package/dist/modes/interactive/tool-chat.d.ts +21 -0
  185. package/dist/modes/interactive/tool-chat.d.ts.map +1 -0
  186. package/dist/modes/interactive/tool-chat.js +58 -0
  187. package/dist/modes/interactive/tool-chat.js.map +1 -0
  188. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  189. package/dist/modes/rpc/rpc-mode.js +0 -2
  190. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  191. package/dist/utils/path-identity.d.ts +12 -0
  192. package/dist/utils/path-identity.d.ts.map +1 -0
  193. package/dist/utils/path-identity.js +63 -0
  194. package/dist/utils/path-identity.js.map +1 -0
  195. package/dist/utils/shell.d.ts +0 -1
  196. package/dist/utils/shell.d.ts.map +1 -1
  197. package/dist/utils/shell.js +0 -21
  198. package/dist/utils/shell.js.map +1 -1
  199. package/dist/utils/syntax-highlight.d.ts +2 -0
  200. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  201. package/dist/utils/syntax-highlight.js +2 -0
  202. package/dist/utils/syntax-highlight.js.map +1 -1
  203. package/docs/bundled/extensions/background.md +3 -3
  204. package/docs/bundled/extensions/provider.md +7 -3
  205. package/docs/bundled/extensions/subagent.md +1 -1
  206. package/docs/compaction.md +1 -1
  207. package/docs/extensions.md +15 -5
  208. package/docs/sdk.md +1 -1
  209. package/docs/usage.md +3 -0
  210. package/examples/README.md +11 -1
  211. package/examples/extensions/README.md +34 -14
  212. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  213. package/examples/extensions/bash-spawn-hook.ts +2 -2
  214. package/examples/extensions/bookmark.ts +1 -1
  215. package/examples/extensions/border-status-editor.ts +6 -1
  216. package/examples/extensions/built-in-tool-renderer.ts +2 -2
  217. package/examples/extensions/claude-rules.ts +1 -1
  218. package/examples/extensions/commands.ts +1 -1
  219. package/examples/extensions/confirm-destructive.ts +1 -1
  220. package/examples/extensions/custom-compaction.ts +2 -2
  221. package/examples/extensions/custom-footer.ts +1 -1
  222. package/examples/extensions/custom-header.ts +2 -2
  223. package/examples/extensions/custom-provider-anthropic/index.ts +6 -6
  224. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  225. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  226. package/examples/extensions/custom-provider-gitlab-duo/index.ts +3 -3
  227. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  228. package/examples/extensions/dirty-repo-guard.ts +1 -1
  229. package/examples/extensions/doom-overlay/index.ts +1 -1
  230. package/examples/extensions/dynamic-resources/dynamic.json +3 -1
  231. package/examples/extensions/dynamic-resources/index.ts +1 -1
  232. package/examples/extensions/dynamic-tools.ts +1 -1
  233. package/examples/extensions/entry-renderer.ts +1 -1
  234. package/examples/extensions/event-bus.ts +1 -1
  235. package/examples/extensions/file-trigger.ts +1 -1
  236. package/examples/extensions/git-checkpoint.ts +1 -1
  237. package/examples/extensions/git-merge-and-resolve.ts +1 -1
  238. package/examples/extensions/github-issue-autocomplete.ts +1 -1
  239. package/examples/extensions/gondolin/index.ts +9 -7
  240. package/examples/extensions/gondolin/package-lock.json +2 -2
  241. package/examples/extensions/gondolin/package.json +1 -1
  242. package/examples/extensions/handoff.ts +2 -2
  243. package/examples/extensions/hello.ts +1 -1
  244. package/examples/extensions/hidden-thinking-label.ts +1 -1
  245. package/examples/extensions/inline-bash.ts +1 -1
  246. package/examples/extensions/input-transform-streaming.ts +1 -1
  247. package/examples/extensions/input-transform.ts +1 -1
  248. package/examples/extensions/interactive-shell.ts +1 -1
  249. package/examples/extensions/mac-system-theme.ts +1 -1
  250. package/examples/extensions/message-renderer.ts +1 -1
  251. package/examples/extensions/minimal-mode.ts +2 -2
  252. package/examples/extensions/modal-editor.ts +1 -1
  253. package/examples/extensions/model-status.ts +1 -1
  254. package/examples/extensions/notify.ts +1 -1
  255. package/examples/extensions/overlay-qa-tests.ts +3 -3
  256. package/examples/extensions/overlay-test.ts +1 -1
  257. package/examples/extensions/permission-gate.ts +1 -1
  258. package/examples/extensions/pirate.ts +1 -1
  259. package/examples/extensions/plan-mode/index.ts +1 -1
  260. package/examples/extensions/preset.ts +2 -2
  261. package/examples/extensions/project-trust.ts +3 -3
  262. package/examples/extensions/prompt-customizer.ts +1 -1
  263. package/examples/extensions/protected-paths.ts +1 -1
  264. package/examples/extensions/provider-payload.ts +1 -1
  265. package/examples/extensions/qna.ts +2 -2
  266. package/examples/extensions/question.ts +1 -1
  267. package/examples/extensions/questionnaire.ts +1 -1
  268. package/examples/extensions/rainbow-editor.ts +1 -1
  269. package/examples/extensions/reload-runtime.ts +1 -1
  270. package/examples/extensions/rpc-demo.ts +1 -1
  271. package/examples/extensions/sandbox/index.ts +2 -2
  272. package/examples/extensions/sandbox/package-lock.json +2 -2
  273. package/examples/extensions/sandbox/package.json +1 -1
  274. package/examples/extensions/send-user-message.ts +1 -1
  275. package/examples/extensions/session-name.ts +1 -1
  276. package/examples/extensions/shutdown-command.ts +1 -1
  277. package/examples/extensions/snake.ts +1 -1
  278. package/examples/extensions/space-invaders.ts +1 -1
  279. package/examples/extensions/ssh.ts +2 -2
  280. package/examples/extensions/status-line.ts +1 -1
  281. package/examples/extensions/structured-output.ts +1 -1
  282. package/examples/extensions/summarize.ts +2 -3
  283. package/examples/extensions/system-prompt-header.ts +1 -1
  284. package/examples/extensions/tic-tac-toe.ts +1 -1
  285. package/examples/extensions/timed-confirm.ts +1 -1
  286. package/examples/extensions/titlebar-spinner.ts +1 -1
  287. package/examples/extensions/todo.ts +1 -1
  288. package/examples/extensions/tool-override.ts +1 -1
  289. package/examples/extensions/tools.ts +2 -2
  290. package/examples/extensions/trigger-compact.ts +1 -1
  291. package/examples/extensions/truncated-tool.ts +4 -4
  292. package/examples/extensions/widget-placement.ts +1 -1
  293. package/examples/extensions/with-deps/index.ts +1 -1
  294. package/examples/extensions/with-deps/package-lock.json +2 -2
  295. package/examples/extensions/with-deps/package.json +1 -1
  296. package/examples/extensions/working-indicator.ts +1 -1
  297. package/examples/extensions/working-message-test.ts +1 -1
  298. package/examples/rpc-client.ts +35 -0
  299. package/examples/rpc-extension-ui.ts +25 -5
  300. package/npm-shrinkwrap.json +43 -43
  301. package/package.json +8 -8
@@ -5,6 +5,11 @@
5
5
  * credential precedence (auth.json > env > models.json) applies. Raw
6
6
  * `$VAR` / `!command` placeholders never reach the wire: a failed resolution
7
7
  * aborts before this function is called.
8
+ *
9
+ * Entries keep the metadata they declare under common field names: context
10
+ * window, output limit, image input, and reasoning. Anthropic-compatible
11
+ * gateways that reject the Anthropic catalog request get one OpenAI-style
12
+ * retry, and Anthropic catalogs follow their `has_more` pages.
8
13
  */
9
14
  import { stripTerminalSequences } from "@earendil-works/pi-tui";
10
15
  import { readResponseTextBounded } from "../../utils/http-response.js";
@@ -30,10 +35,8 @@ export async function probeProviderModels(opts) {
30
35
  const timer = setTimeout(() => controller.abort(), timeoutMs);
31
36
  const onOuterAbort = () => controller.abort();
32
37
  opts.signal?.addEventListener("abort", onOuterAbort, { once: true });
33
- try {
34
- const url = modelCatalogUrl(baseUrl, opts.api);
35
- const headers = buildHeaders(opts.auth, opts.api);
36
- const doFetch = opts.fetch ?? globalThis.fetch;
38
+ const doFetch = opts.fetch ?? globalThis.fetch;
39
+ const getPage = async (url, headers) => {
37
40
  const response = await doFetch(url, { method: "GET", headers, signal: controller.signal });
38
41
  if (!response.ok) {
39
42
  const body = await readResponseTextBounded(response, {
@@ -42,6 +45,7 @@ export async function probeProviderModels(opts) {
42
45
  });
43
46
  return {
44
47
  ok: false,
48
+ status: response.status,
45
49
  error: `HTTP ${response.status}${body ? `: ${safeErrorText(body, opts.auth).slice(0, PROBE_LIMITS.maxErrorChars)}` : ""}`,
46
50
  };
47
51
  }
@@ -50,23 +54,62 @@ export async function probeProviderModels(opts) {
50
54
  overflowMessage: `Response exceeds ${PROBE_LIMITS.maxBodyBytes} bytes.`,
51
55
  signal: controller.signal,
52
56
  });
53
- let json;
54
57
  try {
55
- json = JSON.parse(text);
58
+ return { ok: true, json: JSON.parse(text) };
56
59
  }
57
60
  catch {
58
61
  return { ok: false, error: "Model catalog response is not JSON." };
59
62
  }
60
- const models = parseCatalogModels(json);
63
+ };
64
+ try {
65
+ let url = modelCatalogUrl(baseUrl, opts.api);
66
+ let headers = buildHeaders(opts.auth, opts.api);
67
+ let page = await getPage(url, headers);
68
+ const retry = page.ok
69
+ ? undefined
70
+ : openAIStyleRetry(baseUrl, opts.auth, opts.api, { url, headers, status: page.status });
71
+ if (!page.ok && retry) {
72
+ const retried = await getPage(retry.url, retry.headers);
73
+ if (!retried.ok) {
74
+ return {
75
+ ok: false,
76
+ error: safeErrorText(`${url.href} → HTTP ${page.status}; OpenAI-style retry ${retry.url.href} → ${retried.error}`, opts.auth),
77
+ };
78
+ }
79
+ ({ url, headers } = retry);
80
+ page = retried;
81
+ }
82
+ if (!page.ok)
83
+ return { ok: false, error: page.error };
84
+ const models = parseCatalogModels(page.json);
61
85
  if (models === null) {
62
86
  return {
63
87
  ok: false,
64
88
  error: "JSON has no supported OpenAI-style data[] or models[] catalog with model ids. Add models manually if this endpoint uses another catalog format.",
65
89
  };
66
90
  }
91
+ // Anthropic lists 20 models per page unless asked for more; follow its cursor.
92
+ let json = page.json;
93
+ for (let pages = 1; opts.api === "anthropic-messages" && pages < PROBE_LIMITS.maxPages && models.length < PROBE_LIMITS.maxModels; pages++) {
94
+ const cursor = nextPageCursor(json);
95
+ if (!cursor)
96
+ break;
97
+ const nextUrl = new URL(url.href);
98
+ nextUrl.searchParams.set("after_id", cursor);
99
+ nextUrl.searchParams.set("limit", "1000");
100
+ const next = await getPage(nextUrl, headers);
101
+ const more = next.ok ? parseCatalogModels(next.json) : null;
102
+ // A failed page keeps what is already listed; the catalog stays marked partial.
103
+ if (!next.ok || !more)
104
+ break;
105
+ models.push(...more);
106
+ // A server ignoring the cursor would repeat this page forever.
107
+ if (nextPageCursor(next.json) === cursor)
108
+ break;
109
+ json = next.json;
110
+ }
67
111
  const sorted = dedupeSort(models);
68
- const morePages = typeof json === "object" && json !== null && "has_more" in json && json.has_more === true;
69
- const truncated = sorted.length > PROBE_LIMITS.maxModels || morePages;
112
+ const truncated = sorted.length > PROBE_LIMITS.maxModels || declaresMorePages(json);
70
113
  return { ok: true, models: sorted.slice(0, PROBE_LIMITS.maxModels), truncated };
71
114
  }
72
115
  catch (error) {
@@ -87,6 +130,25 @@ export function modelCatalogUrl(base, api) {
87
130
  url.pathname = api === "anthropic-messages" && !path.endsWith("/v1") ? `${path}/v1/models` : `${path}/models`;
88
131
  return url;
89
132
  }
133
+ /**
134
+ * Anthropic-compatible gateways often serve their catalog OpenAI-style only:
135
+ * StepFun's /step_plan/v1/models rejects x-api-key but accepts Bearer, and
136
+ * DeepSeek's /anthropic has no catalog while its root /v1/models does. One
137
+ * retry with Bearer auth and a trailing /anthropic segment removed covers
138
+ * both, stays on the same origin, and leaves configured Authorization alone.
139
+ */
140
+ function openAIStyleRetry(base, auth, api, first) {
141
+ if (api !== "anthropic-messages" || ![401, 403, 404].includes(first.status ?? 0))
142
+ return undefined;
143
+ if (Object.keys(auth?.headers ?? {}).some((key) => key.toLowerCase() === "authorization"))
144
+ return undefined;
145
+ const root = new URL(base.href);
146
+ root.pathname = root.pathname.replace(/\/+$/, "").replace(/\/anthropic$/i, "");
147
+ const url = modelCatalogUrl(root, api);
148
+ const headers = buildHeaders(auth, undefined);
149
+ const unchanged = url.href === first.url.href && headers.get("authorization") === first.headers.get("authorization");
150
+ return unchanged ? undefined : { url, headers };
151
+ }
90
152
  function safeErrorText(text, auth) {
91
153
  for (const value of [auth?.apiKey, ...Object.values(auth?.headers ?? {})]) {
92
154
  if (typeof value !== "string" || !value)
@@ -114,7 +176,6 @@ function buildHeaders(auth, api) {
114
176
  else if (value === null)
115
177
  headers.delete(key);
116
178
  }
117
- headers.set("accept", "application/json");
118
179
  if (!auth?.apiKey || hasAuthorization)
119
180
  return headers;
120
181
  const lower = (name) => Object.keys(configured).some((key) => key.toLowerCase() === name);
@@ -139,6 +200,91 @@ function buildHeaders(auth, api) {
139
200
  headers.set("authorization", `Bearer ${auth.apiKey}`);
140
201
  return headers;
141
202
  }
203
+ function declaresMorePages(json) {
204
+ return typeof json === "object" && json !== null && "has_more" in json && json.has_more === true;
205
+ }
206
+ function nextPageCursor(json) {
207
+ if (!declaresMorePages(json))
208
+ return undefined;
209
+ const lastId = json.last_id;
210
+ return typeof lastId === "string" && lastId ? lastId : undefined;
211
+ }
212
+ // Catalogs name the same metadata differently; each list holds the field
213
+ // paths seen in real /models responses.
214
+ const CONTEXT_WINDOW_FIELDS = [
215
+ "context_window",
216
+ "context_window.tokens",
217
+ "context_length",
218
+ "top_provider.context_length",
219
+ "max_input_tokens",
220
+ "max_context_length",
221
+ "max_model_len",
222
+ "context_size",
223
+ "metadata.context_length",
224
+ ];
225
+ const MAX_TOKENS_FIELDS = [
226
+ "max_output_tokens",
227
+ "max_completion_tokens",
228
+ "top_provider.max_completion_tokens",
229
+ "max_tokens",
230
+ "max_output_length",
231
+ ];
232
+ const INPUT_MODALITY_FIELDS = ["input_modalities", "architecture.input_modalities", "modalities.input"];
233
+ const IMAGE_FLAG_FIELDS = [
234
+ "supports_vision",
235
+ "enable_vision_input",
236
+ "capabilities.vision",
237
+ "capabilities.image_input.supported",
238
+ ];
239
+ const REASONING_FLAG_FIELDS = [
240
+ "reasoning",
241
+ "supports_reasoning",
242
+ "enable_reason",
243
+ "capabilities.reasoning",
244
+ "capabilities.thinking.supported",
245
+ ];
246
+ const REASONING_LEVEL_FIELDS = ["effort.supported_levels", "reasoning_effort_support_list"];
247
+ /** Capability lists that can name `reasoning` or `vision`. */
248
+ const CAPABILITY_LIST_FIELDS = ["supported_parameters", "tags", "features", "supported_features", "metadata.tags"];
249
+ function fieldAt(record, path) {
250
+ let value = record;
251
+ for (const key of path.split(".")) {
252
+ if (!value || typeof value !== "object" || Array.isArray(value))
253
+ return undefined;
254
+ value = value[key];
255
+ }
256
+ return value;
257
+ }
258
+ function listAt(record, path) {
259
+ const value = fieldAt(record, path);
260
+ if (!Array.isArray(value))
261
+ return [];
262
+ return value.filter((entry) => typeof entry === "string").map((entry) => entry.toLowerCase());
263
+ }
264
+ /**
265
+ * Only positive integers count (Anthropic documents 0 as a placeholder). When
266
+ * fields disagree the smallest wins: overstating a limit overflows requests,
267
+ * understating it only compacts earlier.
268
+ */
269
+ function declaredLimit(record, paths) {
270
+ let limit;
271
+ for (const path of paths) {
272
+ const value = fieldAt(record, path);
273
+ if (typeof value === "number" && Number.isSafeInteger(value) && value > 0)
274
+ limit = Math.min(limit ?? value, value);
275
+ }
276
+ return limit;
277
+ }
278
+ function declaresImageInput(record) {
279
+ return (INPUT_MODALITY_FIELDS.some((path) => listAt(record, path).includes("image")) ||
280
+ IMAGE_FLAG_FIELDS.some((path) => fieldAt(record, path) === true) ||
281
+ CAPABILITY_LIST_FIELDS.some((path) => listAt(record, path).includes("vision")));
282
+ }
283
+ function declaresReasoning(record) {
284
+ return (REASONING_FLAG_FIELDS.some((path) => fieldAt(record, path) === true) ||
285
+ REASONING_LEVEL_FIELDS.some((path) => listAt(record, path).length > 0) ||
286
+ CAPABILITY_LIST_FIELDS.some((path) => listAt(record, path).includes("reasoning")));
287
+ }
142
288
  function parseCatalogModels(json) {
143
289
  if (!json || typeof json !== "object")
144
290
  return null;
@@ -163,7 +309,19 @@ function parseCatalogModels(json) {
163
309
  ? record.displayName.trim()
164
310
  : undefined;
165
311
  const name = (displayName ?? anthropicName) !== id ? (displayName ?? anthropicName) : undefined;
166
- models.push(name ? { id, name } : { id });
312
+ const model = name ? { id, name } : { id };
313
+ const contextWindow = declaredLimit(record, CONTEXT_WINDOW_FIELDS);
314
+ if (contextWindow)
315
+ model.contextWindow = contextWindow;
316
+ const maxTokens = declaredLimit(record, MAX_TOKENS_FIELDS);
317
+ if (maxTokens)
318
+ model.maxTokens = maxTokens;
319
+ // models.json represents only text and image input.
320
+ if (declaresImageInput(record))
321
+ model.input = ["text", "image"];
322
+ if (declaresReasoning(record))
323
+ model.reasoning = true;
324
+ models.push(model);
167
325
  }
168
326
  return data.length > 0 && models.length === 0 ? null : models;
169
327
  }
@@ -1 +1 @@
1
- {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../src/extensions/provider/probe.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Fetch the OpenAI-style model catalog from a configured provider endpoint.\n *\n * Auth is resolved by the caller through ModelRuntime.getAuth() so Pi's\n * credential precedence (auth.json > env > models.json) applies. Raw\n * `$VAR` / `!command` placeholders never reach the wire: a failed resolution\n * aborts before this function is called.\n */\n\nimport type { FetchFunction, ModelAuth, ProviderHeaders } from \"@earendil-works/pi-ai\";\nimport { stripTerminalSequences } from \"@earendil-works/pi-tui\";\nimport { readResponseTextBounded } from \"../../utils/http-response.ts\";\nimport { formatError, PROBE_LIMITS } from \"./constants.ts\";\n\nexport interface ProbeModel {\n\tid: string;\n\tname?: string;\n}\n\nexport type ProbeResult = { ok: true; models: ProbeModel[]; truncated: boolean } | { ok: false; error: string };\n\nexport async function probeProviderModels(opts: {\n\tbaseUrl: string;\n\t/** Resolved auth from ModelRuntime.getAuth(). Undefined = anonymous public catalog. */\n\tauth?: ModelAuth;\n\t/** Effective provider api; selects the protocol's auth header scheme. */\n\tapi?: string;\n\tfetch?: FetchFunction;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}): Promise<ProbeResult> {\n\tlet baseUrl: URL;\n\ttry {\n\t\tbaseUrl = new URL(opts.baseUrl);\n\t} catch {\n\t\treturn { ok: false, error: \"Base URL is not a valid URL.\" };\n\t}\n\tif (baseUrl.protocol !== \"http:\" && baseUrl.protocol !== \"https:\") {\n\t\treturn { ok: false, error: `Unsupported protocol: ${baseUrl.protocol}` };\n\t}\n\tif (baseUrl.username || baseUrl.password || baseUrl.hash) {\n\t\treturn { ok: false, error: \"Base URL must not contain credentials or a fragment.\" };\n\t}\n\tif (opts.signal?.aborted) return { ok: false, error: \"Cancelled.\" };\n\n\tconst controller = new AbortController();\n\tconst timeoutMs = opts.timeoutMs ?? PROBE_LIMITS.timeoutMs;\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onOuterAbort = () => controller.abort();\n\topts.signal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\n\ttry {\n\t\tconst url = modelCatalogUrl(baseUrl, opts.api);\n\t\tconst headers = buildHeaders(opts.auth, opts.api);\n\t\tconst doFetch = opts.fetch ?? globalThis.fetch;\n\t\tconst response = await doFetch(url, { method: \"GET\", headers, signal: controller.signal });\n\t\tif (!response.ok) {\n\t\t\tconst body = await readResponseTextBounded(response, {\n\t\t\t\tmaxBytes: PROBE_LIMITS.maxErrorBytes,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `HTTP ${response.status}${body ? `: ${safeErrorText(body, opts.auth).slice(0, PROBE_LIMITS.maxErrorChars)}` : \"\"}`,\n\t\t\t};\n\t\t}\n\t\tconst text = await readResponseTextBounded(response, {\n\t\t\tmaxBytes: PROBE_LIMITS.maxBodyBytes,\n\t\t\toverflowMessage: `Response exceeds ${PROBE_LIMITS.maxBodyBytes} bytes.`,\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tlet json: unknown;\n\t\ttry {\n\t\t\tjson = JSON.parse(text);\n\t\t} catch {\n\t\t\treturn { ok: false, error: \"Model catalog response is not JSON.\" };\n\t\t}\n\t\tconst models = parseCatalogModels(json);\n\t\tif (models === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"JSON has no supported OpenAI-style data[] or models[] catalog with model ids. Add models manually if this endpoint uses another catalog format.\",\n\t\t\t};\n\t\t}\n\t\tconst sorted = dedupeSort(models);\n\t\tconst morePages = typeof json === \"object\" && json !== null && \"has_more\" in json && json.has_more === true;\n\t\tconst truncated = sorted.length > PROBE_LIMITS.maxModels || morePages;\n\t\treturn { ok: true, models: sorted.slice(0, PROBE_LIMITS.maxModels), truncated };\n\t} catch (error) {\n\t\tif (controller.signal.aborted) {\n\t\t\treturn { ok: false, error: opts.signal?.aborted ? \"Cancelled.\" : `Timed out after ${timeoutMs}ms.` };\n\t\t}\n\t\treturn { ok: false, error: safeErrorText(formatError(error), opts.auth) };\n\t} finally {\n\t\tclearTimeout(timer);\n\t\topts.signal?.removeEventListener(\"abort\", onOuterAbort);\n\t}\n}\n\n/** Append a path segment, keeping the query string and avoiding duplicate slashes or a doubled /v1. */\nexport function modelCatalogUrl(base: URL, api?: string): URL {\n\tconst url = new URL(base.href);\n\tconst path = url.pathname.replace(/\\/+$/, \"\");\n\turl.pathname = api === \"anthropic-messages\" && !path.endsWith(\"/v1\") ? `${path}/v1/models` : `${path}/models`;\n\treturn url;\n}\n\nfunction safeErrorText(text: string, auth: ModelAuth | undefined): string {\n\tfor (const value of [auth?.apiKey, ...Object.values(auth?.headers ?? {})]) {\n\t\tif (typeof value !== \"string\" || !value) continue;\n\t\ttext = text.replaceAll(value, \"[redacted]\");\n\t\tconst token = value.replace(/^Bearer\\s+/i, \"\");\n\t\tif (token !== value && token) text = text.replaceAll(token, \"[redacted]\");\n\t}\n\treturn stripTerminalSequences(text);\n}\n\nfunction buildHeaders(auth: ModelAuth | undefined, api: string | undefined): Headers {\n\tconst headers = new Headers();\n\theaders.set(\"accept\", \"application/json\");\n\tconst configured: ProviderHeaders = auth?.headers ?? {};\n\tif (api === \"anthropic-messages\") headers.set(\"anthropic-version\", \"2023-06-01\");\n\tlet hasAuthorization = false;\n\tfor (const [key, value] of Object.entries(configured)) {\n\t\t// null explicitly removes a header; it also suppresses the default auth header.\n\t\tif (key.toLowerCase() === \"authorization\") hasAuthorization = true;\n\t\tif (typeof value === \"string\") headers.set(key, value);\n\t\telse if (value === null) headers.delete(key);\n\t}\n\theaders.set(\"accept\", \"application/json\");\n\tif (!auth?.apiKey || hasAuthorization) return headers;\n\tconst lower = (name: string) => Object.keys(configured).some((key) => key.toLowerCase() === name);\n\tif (api === \"anthropic-messages\") {\n\t\t// Mirror pi-ai: OAuth tokens use Bearer; plain keys use x-api-key + version.\n\t\tif (auth.apiKey.includes(\"sk-ant-oat\")) {\n\t\t\theaders.set(\"authorization\", `Bearer ${auth.apiKey}`);\n\t\t} else {\n\t\t\tif (!lower(\"x-api-key\")) headers.set(\"x-api-key\", auth.apiKey);\n\t\t\tif (!lower(\"anthropic-version\")) headers.set(\"anthropic-version\", \"2023-06-01\");\n\t\t}\n\t\treturn headers;\n\t}\n\tif (api === \"google-generative-ai\" || api === \"google-vertex\") {\n\t\tif (!lower(\"x-goog-api-key\")) headers.set(\"x-goog-api-key\", auth.apiKey);\n\t\treturn headers;\n\t}\n\theaders.set(\"authorization\", `Bearer ${auth.apiKey}`);\n\treturn headers;\n}\n\nfunction parseCatalogModels(json: unknown): ProbeModel[] | null {\n\tif (!json || typeof json !== \"object\") return null;\n\tconst payload = json as { models?: unknown; data?: unknown };\n\tconst data = Array.isArray(json) ? json : Array.isArray(payload.models) ? payload.models : payload.data;\n\tif (!Array.isArray(data)) return null;\n\tconst models: ProbeModel[] = [];\n\tfor (const item of data) {\n\t\tif (!item || typeof item !== \"object\") continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst id =\n\t\t\t(typeof record.id === \"string\" ? record.id.trim() : \"\") ||\n\t\t\t(typeof record.slug === \"string\" ? record.slug.trim() : \"\");\n\t\tif (!id) continue;\n\t\t// OpenAI uses `name`; Anthropic's /v1/models uses `display_name`.\n\t\tconst displayName = typeof record.name === \"string\" && record.name.trim() ? record.name.trim() : undefined;\n\t\tconst anthropicName =\n\t\t\ttypeof record.display_name === \"string\" && record.display_name.trim()\n\t\t\t\t? record.display_name.trim()\n\t\t\t\t: typeof record.displayName === \"string\"\n\t\t\t\t\t? record.displayName.trim()\n\t\t\t\t\t: undefined;\n\t\tconst name = (displayName ?? anthropicName) !== id ? (displayName ?? anthropicName) : undefined;\n\t\tmodels.push(name ? { id, name } : { id });\n\t}\n\treturn data.length > 0 && models.length === 0 ? null : models;\n}\n\nfunction dedupeSort(models: ProbeModel[]): ProbeModel[] {\n\tconst map = new Map<string, ProbeModel>();\n\tfor (const model of models) {\n\t\tif (!map.has(model.id)) map.set(model.id, model);\n\t}\n\treturn [...map.values()].sort((a, b) => a.id.localeCompare(b.id));\n}\n"]}
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../src/extensions/provider/probe.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Fetch the OpenAI-style model catalog from a configured provider endpoint.\n *\n * Auth is resolved by the caller through ModelRuntime.getAuth() so Pi's\n * credential precedence (auth.json > env > models.json) applies. Raw\n * `$VAR` / `!command` placeholders never reach the wire: a failed resolution\n * aborts before this function is called.\n *\n * Entries keep the metadata they declare under common field names: context\n * window, output limit, image input, and reasoning. Anthropic-compatible\n * gateways that reject the Anthropic catalog request get one OpenAI-style\n * retry, and Anthropic catalogs follow their `has_more` pages.\n */\n\nimport type { FetchFunction, ModelAuth, ProviderHeaders } from \"@earendil-works/pi-ai\";\nimport { stripTerminalSequences } from \"@earendil-works/pi-tui\";\nimport type { ModelsJsonModel } from \"../../core/model-config.ts\";\nimport { readResponseTextBounded } from \"../../utils/http-response.ts\";\nimport { formatError, PROBE_LIMITS } from \"./constants.ts\";\n\n/** A catalog entry: its id plus the metadata it declared, already valid as a models.json model. */\nexport type ProbeModel = Pick<ModelsJsonModel, \"id\" | \"name\" | \"contextWindow\" | \"maxTokens\" | \"input\" | \"reasoning\">;\n\nexport type ProbeResult = { ok: true; models: ProbeModel[]; truncated: boolean } | { ok: false; error: string };\n\ntype CatalogPage = { ok: true; json: unknown } | { ok: false; status?: number; error: string };\n\nexport async function probeProviderModels(opts: {\n\tbaseUrl: string;\n\t/** Resolved auth from ModelRuntime.getAuth(). Undefined = anonymous public catalog. */\n\tauth?: ModelAuth;\n\t/** Effective provider api; selects the protocol's auth header scheme. */\n\tapi?: string;\n\tfetch?: FetchFunction;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}): Promise<ProbeResult> {\n\tlet baseUrl: URL;\n\ttry {\n\t\tbaseUrl = new URL(opts.baseUrl);\n\t} catch {\n\t\treturn { ok: false, error: \"Base URL is not a valid URL.\" };\n\t}\n\tif (baseUrl.protocol !== \"http:\" && baseUrl.protocol !== \"https:\") {\n\t\treturn { ok: false, error: `Unsupported protocol: ${baseUrl.protocol}` };\n\t}\n\tif (baseUrl.username || baseUrl.password || baseUrl.hash) {\n\t\treturn { ok: false, error: \"Base URL must not contain credentials or a fragment.\" };\n\t}\n\tif (opts.signal?.aborted) return { ok: false, error: \"Cancelled.\" };\n\n\tconst controller = new AbortController();\n\tconst timeoutMs = opts.timeoutMs ?? PROBE_LIMITS.timeoutMs;\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onOuterAbort = () => controller.abort();\n\topts.signal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\n\tconst doFetch = opts.fetch ?? globalThis.fetch;\n\tconst getPage = async (url: URL, headers: Headers): Promise<CatalogPage> => {\n\t\tconst response = await doFetch(url, { method: \"GET\", headers, signal: controller.signal });\n\t\tif (!response.ok) {\n\t\t\tconst body = await readResponseTextBounded(response, {\n\t\t\t\tmaxBytes: PROBE_LIMITS.maxErrorBytes,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tstatus: response.status,\n\t\t\t\terror: `HTTP ${response.status}${body ? `: ${safeErrorText(body, opts.auth).slice(0, PROBE_LIMITS.maxErrorChars)}` : \"\"}`,\n\t\t\t};\n\t\t}\n\t\tconst text = await readResponseTextBounded(response, {\n\t\t\tmaxBytes: PROBE_LIMITS.maxBodyBytes,\n\t\t\toverflowMessage: `Response exceeds ${PROBE_LIMITS.maxBodyBytes} bytes.`,\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\ttry {\n\t\t\treturn { ok: true, json: JSON.parse(text) };\n\t\t} catch {\n\t\t\treturn { ok: false, error: \"Model catalog response is not JSON.\" };\n\t\t}\n\t};\n\n\ttry {\n\t\tlet url = modelCatalogUrl(baseUrl, opts.api);\n\t\tlet headers = buildHeaders(opts.auth, opts.api);\n\t\tlet page = await getPage(url, headers);\n\t\tconst retry = page.ok\n\t\t\t? undefined\n\t\t\t: openAIStyleRetry(baseUrl, opts.auth, opts.api, { url, headers, status: page.status });\n\t\tif (!page.ok && retry) {\n\t\t\tconst retried = await getPage(retry.url, retry.headers);\n\t\t\tif (!retried.ok) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: safeErrorText(\n\t\t\t\t\t\t`${url.href} → HTTP ${page.status}; OpenAI-style retry ${retry.url.href} → ${retried.error}`,\n\t\t\t\t\t\topts.auth,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t\t({ url, headers } = retry);\n\t\t\tpage = retried;\n\t\t}\n\t\tif (!page.ok) return { ok: false, error: page.error };\n\t\tconst models = parseCatalogModels(page.json);\n\t\tif (models === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"JSON has no supported OpenAI-style data[] or models[] catalog with model ids. Add models manually if this endpoint uses another catalog format.\",\n\t\t\t};\n\t\t}\n\t\t// Anthropic lists 20 models per page unless asked for more; follow its cursor.\n\t\tlet json = page.json;\n\t\tfor (\n\t\t\tlet pages = 1;\n\t\t\topts.api === \"anthropic-messages\" && pages < PROBE_LIMITS.maxPages && models.length < PROBE_LIMITS.maxModels;\n\t\t\tpages++\n\t\t) {\n\t\t\tconst cursor = nextPageCursor(json);\n\t\t\tif (!cursor) break;\n\t\t\tconst nextUrl = new URL(url.href);\n\t\t\tnextUrl.searchParams.set(\"after_id\", cursor);\n\t\t\tnextUrl.searchParams.set(\"limit\", \"1000\");\n\t\t\tconst next = await getPage(nextUrl, headers);\n\t\t\tconst more = next.ok ? parseCatalogModels(next.json) : null;\n\t\t\t// A failed page keeps what is already listed; the catalog stays marked partial.\n\t\t\tif (!next.ok || !more) break;\n\t\t\tmodels.push(...more);\n\t\t\t// A server ignoring the cursor would repeat this page forever.\n\t\t\tif (nextPageCursor(next.json) === cursor) break;\n\t\t\tjson = next.json;\n\t\t}\n\t\tconst sorted = dedupeSort(models);\n\t\tconst truncated = sorted.length > PROBE_LIMITS.maxModels || declaresMorePages(json);\n\t\treturn { ok: true, models: sorted.slice(0, PROBE_LIMITS.maxModels), truncated };\n\t} catch (error) {\n\t\tif (controller.signal.aborted) {\n\t\t\treturn { ok: false, error: opts.signal?.aborted ? \"Cancelled.\" : `Timed out after ${timeoutMs}ms.` };\n\t\t}\n\t\treturn { ok: false, error: safeErrorText(formatError(error), opts.auth) };\n\t} finally {\n\t\tclearTimeout(timer);\n\t\topts.signal?.removeEventListener(\"abort\", onOuterAbort);\n\t}\n}\n\n/** Append a path segment, keeping the query string and avoiding duplicate slashes or a doubled /v1. */\nexport function modelCatalogUrl(base: URL, api?: string): URL {\n\tconst url = new URL(base.href);\n\tconst path = url.pathname.replace(/\\/+$/, \"\");\n\turl.pathname = api === \"anthropic-messages\" && !path.endsWith(\"/v1\") ? `${path}/v1/models` : `${path}/models`;\n\treturn url;\n}\n\n/**\n * Anthropic-compatible gateways often serve their catalog OpenAI-style only:\n * StepFun's /step_plan/v1/models rejects x-api-key but accepts Bearer, and\n * DeepSeek's /anthropic has no catalog while its root /v1/models does. One\n * retry with Bearer auth and a trailing /anthropic segment removed covers\n * both, stays on the same origin, and leaves configured Authorization alone.\n */\nfunction openAIStyleRetry(\n\tbase: URL,\n\tauth: ModelAuth | undefined,\n\tapi: string | undefined,\n\tfirst: { url: URL; headers: Headers; status?: number },\n): { url: URL; headers: Headers } | undefined {\n\tif (api !== \"anthropic-messages\" || ![401, 403, 404].includes(first.status ?? 0)) return undefined;\n\tif (Object.keys(auth?.headers ?? {}).some((key) => key.toLowerCase() === \"authorization\")) return undefined;\n\tconst root = new URL(base.href);\n\troot.pathname = root.pathname.replace(/\\/+$/, \"\").replace(/\\/anthropic$/i, \"\");\n\tconst url = modelCatalogUrl(root, api);\n\tconst headers = buildHeaders(auth, undefined);\n\tconst unchanged = url.href === first.url.href && headers.get(\"authorization\") === first.headers.get(\"authorization\");\n\treturn unchanged ? undefined : { url, headers };\n}\n\nfunction safeErrorText(text: string, auth: ModelAuth | undefined): string {\n\tfor (const value of [auth?.apiKey, ...Object.values(auth?.headers ?? {})]) {\n\t\tif (typeof value !== \"string\" || !value) continue;\n\t\ttext = text.replaceAll(value, \"[redacted]\");\n\t\tconst token = value.replace(/^Bearer\\s+/i, \"\");\n\t\tif (token !== value && token) text = text.replaceAll(token, \"[redacted]\");\n\t}\n\treturn stripTerminalSequences(text);\n}\n\nfunction buildHeaders(auth: ModelAuth | undefined, api: string | undefined): Headers {\n\tconst headers = new Headers();\n\theaders.set(\"accept\", \"application/json\");\n\tconst configured: ProviderHeaders = auth?.headers ?? {};\n\tif (api === \"anthropic-messages\") headers.set(\"anthropic-version\", \"2023-06-01\");\n\tlet hasAuthorization = false;\n\tfor (const [key, value] of Object.entries(configured)) {\n\t\t// null explicitly removes a header; it also suppresses the default auth header.\n\t\tif (key.toLowerCase() === \"authorization\") hasAuthorization = true;\n\t\tif (typeof value === \"string\") headers.set(key, value);\n\t\telse if (value === null) headers.delete(key);\n\t}\n\tif (!auth?.apiKey || hasAuthorization) return headers;\n\tconst lower = (name: string) => Object.keys(configured).some((key) => key.toLowerCase() === name);\n\tif (api === \"anthropic-messages\") {\n\t\t// Mirror pi-ai: OAuth tokens use Bearer; plain keys use x-api-key + version.\n\t\tif (auth.apiKey.includes(\"sk-ant-oat\")) {\n\t\t\theaders.set(\"authorization\", `Bearer ${auth.apiKey}`);\n\t\t} else {\n\t\t\tif (!lower(\"x-api-key\")) headers.set(\"x-api-key\", auth.apiKey);\n\t\t\tif (!lower(\"anthropic-version\")) headers.set(\"anthropic-version\", \"2023-06-01\");\n\t\t}\n\t\treturn headers;\n\t}\n\tif (api === \"google-generative-ai\" || api === \"google-vertex\") {\n\t\tif (!lower(\"x-goog-api-key\")) headers.set(\"x-goog-api-key\", auth.apiKey);\n\t\treturn headers;\n\t}\n\theaders.set(\"authorization\", `Bearer ${auth.apiKey}`);\n\treturn headers;\n}\n\nfunction declaresMorePages(json: unknown): boolean {\n\treturn typeof json === \"object\" && json !== null && \"has_more\" in json && json.has_more === true;\n}\n\nfunction nextPageCursor(json: unknown): string | undefined {\n\tif (!declaresMorePages(json)) return undefined;\n\tconst lastId = (json as { last_id?: unknown }).last_id;\n\treturn typeof lastId === \"string\" && lastId ? lastId : undefined;\n}\n\n// Catalogs name the same metadata differently; each list holds the field\n// paths seen in real /models responses.\nconst CONTEXT_WINDOW_FIELDS = [\n\t\"context_window\",\n\t\"context_window.tokens\",\n\t\"context_length\",\n\t\"top_provider.context_length\",\n\t\"max_input_tokens\",\n\t\"max_context_length\",\n\t\"max_model_len\",\n\t\"context_size\",\n\t\"metadata.context_length\",\n];\nconst MAX_TOKENS_FIELDS = [\n\t\"max_output_tokens\",\n\t\"max_completion_tokens\",\n\t\"top_provider.max_completion_tokens\",\n\t\"max_tokens\",\n\t\"max_output_length\",\n];\nconst INPUT_MODALITY_FIELDS = [\"input_modalities\", \"architecture.input_modalities\", \"modalities.input\"];\nconst IMAGE_FLAG_FIELDS = [\n\t\"supports_vision\",\n\t\"enable_vision_input\",\n\t\"capabilities.vision\",\n\t\"capabilities.image_input.supported\",\n];\nconst REASONING_FLAG_FIELDS = [\n\t\"reasoning\",\n\t\"supports_reasoning\",\n\t\"enable_reason\",\n\t\"capabilities.reasoning\",\n\t\"capabilities.thinking.supported\",\n];\nconst REASONING_LEVEL_FIELDS = [\"effort.supported_levels\", \"reasoning_effort_support_list\"];\n/** Capability lists that can name `reasoning` or `vision`. */\nconst CAPABILITY_LIST_FIELDS = [\"supported_parameters\", \"tags\", \"features\", \"supported_features\", \"metadata.tags\"];\n\nfunction fieldAt(record: Record<string, unknown>, path: string): unknown {\n\tlet value: unknown = record;\n\tfor (const key of path.split(\".\")) {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\t\tvalue = (value as Record<string, unknown>)[key];\n\t}\n\treturn value;\n}\n\nfunction listAt(record: Record<string, unknown>, path: string): string[] {\n\tconst value = fieldAt(record, path);\n\tif (!Array.isArray(value)) return [];\n\treturn value.filter((entry): entry is string => typeof entry === \"string\").map((entry) => entry.toLowerCase());\n}\n\n/**\n * Only positive integers count (Anthropic documents 0 as a placeholder). When\n * fields disagree the smallest wins: overstating a limit overflows requests,\n * understating it only compacts earlier.\n */\nfunction declaredLimit(record: Record<string, unknown>, paths: readonly string[]): number | undefined {\n\tlet limit: number | undefined;\n\tfor (const path of paths) {\n\t\tconst value = fieldAt(record, path);\n\t\tif (typeof value === \"number\" && Number.isSafeInteger(value) && value > 0)\n\t\t\tlimit = Math.min(limit ?? value, value);\n\t}\n\treturn limit;\n}\n\nfunction declaresImageInput(record: Record<string, unknown>): boolean {\n\treturn (\n\t\tINPUT_MODALITY_FIELDS.some((path) => listAt(record, path).includes(\"image\")) ||\n\t\tIMAGE_FLAG_FIELDS.some((path) => fieldAt(record, path) === true) ||\n\t\tCAPABILITY_LIST_FIELDS.some((path) => listAt(record, path).includes(\"vision\"))\n\t);\n}\n\nfunction declaresReasoning(record: Record<string, unknown>): boolean {\n\treturn (\n\t\tREASONING_FLAG_FIELDS.some((path) => fieldAt(record, path) === true) ||\n\t\tREASONING_LEVEL_FIELDS.some((path) => listAt(record, path).length > 0) ||\n\t\tCAPABILITY_LIST_FIELDS.some((path) => listAt(record, path).includes(\"reasoning\"))\n\t);\n}\n\nfunction parseCatalogModels(json: unknown): ProbeModel[] | null {\n\tif (!json || typeof json !== \"object\") return null;\n\tconst payload = json as { models?: unknown; data?: unknown };\n\tconst data = Array.isArray(json) ? json : Array.isArray(payload.models) ? payload.models : payload.data;\n\tif (!Array.isArray(data)) return null;\n\tconst models: ProbeModel[] = [];\n\tfor (const item of data) {\n\t\tif (!item || typeof item !== \"object\") continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst id =\n\t\t\t(typeof record.id === \"string\" ? record.id.trim() : \"\") ||\n\t\t\t(typeof record.slug === \"string\" ? record.slug.trim() : \"\");\n\t\tif (!id) continue;\n\t\t// OpenAI uses `name`; Anthropic's /v1/models uses `display_name`.\n\t\tconst displayName = typeof record.name === \"string\" && record.name.trim() ? record.name.trim() : undefined;\n\t\tconst anthropicName =\n\t\t\ttypeof record.display_name === \"string\" && record.display_name.trim()\n\t\t\t\t? record.display_name.trim()\n\t\t\t\t: typeof record.displayName === \"string\"\n\t\t\t\t\t? record.displayName.trim()\n\t\t\t\t\t: undefined;\n\t\tconst name = (displayName ?? anthropicName) !== id ? (displayName ?? anthropicName) : undefined;\n\t\tconst model: ProbeModel = name ? { id, name } : { id };\n\t\tconst contextWindow = declaredLimit(record, CONTEXT_WINDOW_FIELDS);\n\t\tif (contextWindow) model.contextWindow = contextWindow;\n\t\tconst maxTokens = declaredLimit(record, MAX_TOKENS_FIELDS);\n\t\tif (maxTokens) model.maxTokens = maxTokens;\n\t\t// models.json represents only text and image input.\n\t\tif (declaresImageInput(record)) model.input = [\"text\", \"image\"];\n\t\tif (declaresReasoning(record)) model.reasoning = true;\n\t\tmodels.push(model);\n\t}\n\treturn data.length > 0 && models.length === 0 ? null : models;\n}\n\nfunction dedupeSort(models: ProbeModel[]): ProbeModel[] {\n\tconst map = new Map<string, ProbeModel>();\n\tfor (const model of models) {\n\t\tif (!map.has(model.id)) map.set(model.id, model);\n\t}\n\treturn [...map.values()].sort((a, b) => a.id.localeCompare(b.id));\n}\n"]}
@@ -5,6 +5,7 @@
5
5
  * Esc applies nothing. Identity/connection fields (provider, id, api,
6
6
  * baseUrl, keys) are never touched.
7
7
  */
8
+ import "../keybindings.ts";
8
9
  import { type CatalogEntry } from "../catalog.ts";
9
10
  import type { EditorHost, EditorPane, ModelHandle } from "./pane.ts";
10
11
  import { type ScrollWindowInfo } from "./value-row.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-data.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/builtin-data.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,KAAK,YAAY,EAA6D,MAAM,eAAe,CAAC;AAG7G,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAmC,KAAK,gBAAgB,EAAe,MAAM,gBAAgB,CAAC;AAOrG,qBAAa,qBAAsB,YAAW,UAAU;IACvD,QAAQ,CAAC,KAAK,uBAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBACxB,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAYhD,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,KAAK;IAIb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA4B/B,YAAY,IAAI,gBAAgB;IAKhC,OAAO,CAAC,WAAW;IAMnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4B/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAQf;AAED,qBAAa,kBAAmB,YAAW,UAAU;IACpD,QAAQ,CAAC,KAAK,sCAAiC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAC7B,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY;IAYzE,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAsC/B,YAAY,IAAI,gBAAgB;IAahC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4C/B,OAAO,CAAC,KAAK;IA8Bb,OAAO,CAAC,WAAW;IAsDnB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,KAAK,IAAI,MAAM;CAOf"}
1
+ {"version":3,"file":"builtin-data.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/builtin-data.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,mBAAmB,CAAC;AAI3B,OAAO,EAAE,KAAK,YAAY,EAA6D,MAAM,eAAe,CAAC;AAG7G,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAmC,KAAK,gBAAgB,EAAe,MAAM,gBAAgB,CAAC;AAOrG,qBAAa,qBAAsB,YAAW,UAAU;IACvD,QAAQ,CAAC,KAAK,uBAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBACxB,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAYhD,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,KAAK;IAIb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA4B/B,YAAY,IAAI,gBAAgB;IAKhC,OAAO,CAAC,WAAW;IAMnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4B/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAQf;AAED,qBAAa,kBAAmB,YAAW,UAAU;IACpD,QAAQ,CAAC,KAAK,sCAAiC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAC7B,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY;IAYzE,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAsC/B,YAAY,IAAI,gBAAgB;IAahC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4C/B,OAAO,CAAC,KAAK;IA8Bb,OAAO,CAAC,WAAW;IAsDnB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,KAAK,IAAI,MAAM;CAOf"}
@@ -5,6 +5,7 @@
5
5
  * Esc applies nothing. Identity/connection fields (provider, id, api,
6
6
  * baseUrl, keys) are never touched.
7
7
  */
8
+ import "../keybindings.js";
8
9
  import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
9
10
  import { computeFieldChanges, matchBuiltinModels } from "../catalog.js";
10
11
  import { truncate } from "../constants.js";
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-data.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/builtin-data.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Use Built-in Data: pick a Pi builtin catalog entry as a reference for the\n * current model, preview per-field changes (\"current → reference\"), check the\n * fields to copy, and apply once. Selection and preview are temporary state;\n * Esc applies nothing. Identity/connection fields (provider, id, api,\n * baseUrl, keys) are never touched.\n */\n\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { ModelsJsonModel } from \"../../../core/model-config.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { type CatalogEntry, computeFieldChanges, type FieldChange, matchBuiltinModels } from \"../catalog.ts\";\nimport { truncate } from \"../constants.ts\";\nimport { jsonEquals } from \"../store.ts\";\nimport type { EditorHost, EditorPane, ModelHandle } from \"./pane.ts\";\nimport { renderInfoLine, renderPlainLine, type ScrollWindowInfo, ValueEditor } from \"./value-row.ts\";\n\nfunction formatContext(model: Model<Api>): string {\n\tconst ctx = model.contextWindow >= 1000 ? `${Math.round(model.contextWindow / 1024)}k` : String(model.contextWindow);\n\treturn `${model.api} · ${ctx} ctx${model.reasoning ? \" · reasoning\" : \"\"}`;\n}\n\nexport class BuiltinCandidatesPane implements EditorPane {\n\treadonly crumb = \"Use Built-in Data\";\n\tprivate readonly search: ValueEditor;\n\tprivate query: string;\n\tprivate index = 0;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly model: ModelHandle;\n\tconstructor(host: EditorHost, model: ModelHandle) {\n\t\tthis.host = host;\n\t\tthis.model = model;\n\n\t\tthis.query = this.model.read().id ?? \"\";\n\t\tthis.search = new ValueEditor({\n\t\t\tonCommit: () => this.pickCurrent(),\n\t\t\tonCancel: () => this.host.popPane(),\n\t\t});\n\t\tthis.search.reset(this.query);\n\t}\n\n\tprivate candidates(): CatalogEntry[] {\n\t\treturn matchBuiltinModels(this.query, this.host.effectiveApi(this.model.read())).map((match) => match.entry);\n\t}\n\n\tprivate tiers(): ReturnType<typeof matchBuiltinModels> {\n\t\treturn matchBuiltinModels(this.query, this.host.effectiveApi(this.model.read()));\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst lines: string[] = [this.search.renderLine(width)];\n\t\tconst matches = this.tiers();\n\t\tif (matches.length === 0) {\n\t\t\tlines.push(renderInfoLine(theme, \"No builtin candidates — keep configuring manually.\", width));\n\t\t}\n\t\tfor (const [rowIndex, match] of matches.entries()) {\n\t\t\tconst { providerId, model } = match.entry;\n\t\t\tconst label = `${providerId} / ${model.id}`;\n\t\t\tconst note =\n\t\t\t\t(match.tier === \"exact\" ? \"exact · \" : \"\") +\n\t\t\t\t`${model.name !== model.id ? `${model.name} · ` : \"\"}${formatContext(model)}`;\n\t\t\tlines.push(\n\t\t\t\trenderPlainLine(theme, label, {\n\t\t\t\t\tactive: rowIndex === this.index,\n\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\tnote,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tlines.push(\n\t\t\trenderInfoLine(theme, \"Candidates are a reference only; the configured id is never rewritten.\", width),\n\t\t);\n\t\treturn lines;\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\t// The filter input pins above, the reference disclaimer below.\n\t\treturn { top: 1, bottom: 1, cursor: 1 + this.index };\n\t}\n\n\tprivate pickCurrent(): void {\n\t\tconst entry = this.candidates()[this.index];\n\t\tif (!entry) return;\n\t\tthis.host.pushPane(new BuiltinPreviewPane(this.host, this.model, entry));\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tconst count = this.candidates().length;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tif (count > 0) this.index = this.index === 0 ? count - 1 : this.index - 1;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tif (count > 0) this.index = (this.index + 1) % count;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.pickCurrent();\n\t\t\treturn;\n\t\t}\n\t\tconst before = this.query;\n\t\tthis.search.handleInput(data);\n\t\tthis.query = this.search.value;\n\t\tif (this.query !== before) this.index = 0;\n\t\tthis.host.refresh();\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t\tthis.search.focused = focused;\n\t}\n\n\tisEditing(): boolean {\n\t\treturn true; // the candidate filter always owns ←/→\n\t}\n\n\thints(): string {\n\t\treturn [\n\t\t\trawKeyHint(\"type\", \"filter\"),\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"preview\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n\nexport class BuiltinPreviewPane implements EditorPane {\n\treadonly crumb = \"Use Built-in Data · preview\";\n\tprivate readonly changes: FieldChange[];\n\tprivate readonly checked: boolean[];\n\tprivate readonly snapshot: Partial<ModelsJsonModel> & { id?: string };\n\tprivate readonly snapshotApi: string | undefined;\n\tprivate index = 0;\n\tprivate expanded: number | undefined;\n\tprivate error: string | undefined;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly model: ModelHandle;\n\tprivate readonly reference: CatalogEntry;\n\tconstructor(host: EditorHost, model: ModelHandle, reference: CatalogEntry) {\n\t\tthis.host = host;\n\t\tthis.model = model;\n\t\tthis.reference = reference;\n\n\t\tconst current = model.read();\n\t\tthis.snapshot = structuredClone(current);\n\t\tthis.snapshotApi = host.effectiveApi(current);\n\t\tthis.changes = computeFieldChanges(current, reference.model, host.effectiveApi(current));\n\t\tthis.checked = this.changes.map((change) => change.checked && change.applicable);\n\t}\n\n\tprivate rowCount(): number {\n\t\treturn this.changes.length + 1; // + Apply row\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst lines: string[] = [\n\t\t\trenderInfoLine(theme, `reference: ${this.reference.providerId} / ${this.reference.model.id}`, width),\n\t\t];\n\t\tfor (const [rowIndex, change] of this.changes.entries()) {\n\t\t\tconst active = rowIndex === this.index;\n\t\t\tconst expandable = change.referenceDetails !== undefined;\n\t\t\tconst note = !change.applicable ? \"· view only\" : undefined;\n\t\t\tlines.push(\n\t\t\t\trenderPlainLine(theme, `${change.field}: ${change.currentText} → ${change.referenceText}`, {\n\t\t\t\t\tchecked: change.applicable ? this.checked[rowIndex] : undefined,\n\t\t\t\t\tactive,\n\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\tnote,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (this.expanded === rowIndex && expandable) {\n\t\t\t\tfor (const detail of change.referenceDetails!) {\n\t\t\t\t\tlines.push(renderInfoLine(theme, ` ${detail}`, width));\n\t\t\t\t}\n\t\t\t\tif (change.referenceHasTiers) {\n\t\t\t\t\tlines.push(renderInfoLine(theme, \" reference has cost tiers — tiers are never imported.\", width));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlines.push(\n\t\t\trenderPlainLine(theme, \"Apply Selected Fields\", {\n\t\t\t\tactive: this.index === this.changes.length,\n\t\t\t\tpaneFocused: this.focused,\n\t\t\t\twidth,\n\t\t\t}),\n\t\t);\n\t\tif (this.error) lines.push(theme.fg(\"error\", truncate(this.error, Math.max(10, width - 2))));\n\t\treturn lines;\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\t// The reference header pins above; errors pin below. Expanded detail\n\t\t// lines shift the cursor row when they sit above it.\n\t\tlet cursor = 1 + this.index;\n\t\tif (this.expanded !== undefined && this.expanded < this.index) {\n\t\t\tconst change = this.changes[this.expanded]!;\n\t\t\tif (change.referenceDetails) {\n\t\t\t\tcursor += change.referenceDetails.length + (change.referenceHasTiers ? 1 : 0);\n\t\t\t}\n\t\t}\n\t\treturn { top: 1, bottom: this.error ? 1 : 0, cursor };\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.index = this.index === 0 ? this.rowCount() - 1 : this.index - 1;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.index = (this.index + 1) % this.rowCount();\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"app.list.toggle\")) {\n\t\t\tconst change = this.changes[this.index];\n\t\t\tif (!change) return;\n\t\t\tif (!change.applicable) {\n\t\t\t\tthis.expanded = this.expanded === this.index ? undefined : this.index;\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.checked[this.index] = !this.checked[this.index];\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tif (this.index === this.changes.length) {\n\t\t\t\tthis.apply();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst change = this.changes[this.index]!;\n\t\t\tif (change.referenceDetails) {\n\t\t\t\tthis.expanded = this.expanded === this.index ? undefined : this.index;\n\t\t\t} else if (change.applicable) {\n\t\t\t\tthis.checked[this.index] = !this.checked[this.index];\n\t\t\t}\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate apply(): void {\n\t\t// Re-validate against the live model: a stale preview must not write to a changed model.\n\t\tconst current = this.model.read();\n\t\tif (this.host.effectiveApi(current) !== this.snapshotApi) {\n\t\t\tthis.error = \"The API changed since this preview opened; reopen to continue.\";\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (!current.id || !jsonEquals(current, this.snapshot)) {\n\t\t\tthis.error = \"The model changed since this preview opened; reopen to continue.\";\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tconst chosen = this.changes.filter((_, rowIndex) => this.checked[rowIndex] && this.changes[rowIndex]!.applicable);\n\t\tif (chosen.length === 0) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tthis.host.store.batch(() => {\n\t\t\tfor (const change of chosen) this.applyChange(change.field);\n\t\t});\n\t\tthis.host.refresher.touch(this.host.providerId);\n\t\tthis.host.notify(\n\t\t\t`Applied ${chosen.length} field${chosen.length === 1 ? \"\" : \"s\"} from ${this.reference.providerId} / ${this.reference.model.id}.`,\n\t\t\t\"info\",\n\t\t);\n\t\tthis.host.popPane(); // preview\n\t\tthis.host.popPane(); // candidates → back to the model fields\n\t}\n\n\tprivate applyChange(field: FieldChange[\"field\"]): void {\n\t\tconst reference = this.reference.model;\n\t\tconst current = this.model.read();\n\t\tswitch (field) {\n\t\t\tcase \"name\":\n\t\t\t\tthis.model.setField([\"name\"], reference.name);\n\t\t\t\treturn;\n\t\t\tcase \"reasoning\":\n\t\t\t\tthis.model.setField([\"reasoning\"], reference.reasoning);\n\t\t\t\treturn;\n\t\t\tcase \"input\":\n\t\t\t\tthis.model.setField([\"input\"], [...reference.input]);\n\t\t\t\treturn;\n\t\t\tcase \"contextWindow\":\n\t\t\t\tthis.model.setField([\"contextWindow\"], reference.contextWindow);\n\t\t\t\treturn;\n\t\t\tcase \"maxTokens\":\n\t\t\t\tthis.model.setField([\"maxTokens\"], reference.maxTokens);\n\t\t\t\treturn;\n\t\t\tcase \"thinkingLevelMap\":\n\t\t\t\tfor (const [level, target] of Object.entries(reference.thinkingLevelMap ?? {})) {\n\t\t\t\t\tthis.model.setField([\"thinkingLevelMap\", level], target);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"compat\":\n\t\t\t\tfor (const [key, value] of Object.entries(reference.compat ?? {})) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t[\"chatTemplateKwargs\", \"chatTemplateArgs\", \"openRouterRouting\", \"vercelGatewayRouting\"].includes(\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\tvalue !== null &&\n\t\t\t\t\t\ttypeof value === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(value)\n\t\t\t\t\t) {\n\t\t\t\t\t\tfor (const [entryKey, entryValue] of Object.entries(value))\n\t\t\t\t\t\t\tthis.model.setField([\"compat\", key, entryKey], structuredClone(entryValue));\n\t\t\t\t\t} else this.model.setField([\"compat\", key], structuredClone(value));\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"cost\": {\n\t\t\t\tconst rates = {\n\t\t\t\t\tinput: reference.cost.input,\n\t\t\t\t\toutput: reference.cost.output,\n\t\t\t\t\tcacheRead: reference.cost.cacheRead,\n\t\t\t\t\tcacheWrite: reference.cost.cacheWrite,\n\t\t\t\t};\n\t\t\t\tif (current.cost) {\n\t\t\t\t\tfor (const [rate, value] of Object.entries(rates)) this.model.setField([\"cost\", rate], value);\n\t\t\t\t} else this.model.setField([\"cost\"], rates);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t}\n\n\thints(): string {\n\t\treturn [\n\t\t\tkeyHint(\"app.list.toggle\", \"check\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"details / apply\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n"]}
1
+ {"version":3,"file":"builtin-data.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/builtin-data.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Use Built-in Data: pick a Pi builtin catalog entry as a reference for the\n * current model, preview per-field changes (\"current → reference\"), check the\n * fields to copy, and apply once. Selection and preview are temporary state;\n * Esc applies nothing. Identity/connection fields (provider, id, api,\n * baseUrl, keys) are never touched.\n */\n\nimport \"../keybindings.ts\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { ModelsJsonModel } from \"../../../core/model-config.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { type CatalogEntry, computeFieldChanges, type FieldChange, matchBuiltinModels } from \"../catalog.ts\";\nimport { truncate } from \"../constants.ts\";\nimport { jsonEquals } from \"../store.ts\";\nimport type { EditorHost, EditorPane, ModelHandle } from \"./pane.ts\";\nimport { renderInfoLine, renderPlainLine, type ScrollWindowInfo, ValueEditor } from \"./value-row.ts\";\n\nfunction formatContext(model: Model<Api>): string {\n\tconst ctx = model.contextWindow >= 1000 ? `${Math.round(model.contextWindow / 1024)}k` : String(model.contextWindow);\n\treturn `${model.api} · ${ctx} ctx${model.reasoning ? \" · reasoning\" : \"\"}`;\n}\n\nexport class BuiltinCandidatesPane implements EditorPane {\n\treadonly crumb = \"Use Built-in Data\";\n\tprivate readonly search: ValueEditor;\n\tprivate query: string;\n\tprivate index = 0;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly model: ModelHandle;\n\tconstructor(host: EditorHost, model: ModelHandle) {\n\t\tthis.host = host;\n\t\tthis.model = model;\n\n\t\tthis.query = this.model.read().id ?? \"\";\n\t\tthis.search = new ValueEditor({\n\t\t\tonCommit: () => this.pickCurrent(),\n\t\t\tonCancel: () => this.host.popPane(),\n\t\t});\n\t\tthis.search.reset(this.query);\n\t}\n\n\tprivate candidates(): CatalogEntry[] {\n\t\treturn matchBuiltinModels(this.query, this.host.effectiveApi(this.model.read())).map((match) => match.entry);\n\t}\n\n\tprivate tiers(): ReturnType<typeof matchBuiltinModels> {\n\t\treturn matchBuiltinModels(this.query, this.host.effectiveApi(this.model.read()));\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst lines: string[] = [this.search.renderLine(width)];\n\t\tconst matches = this.tiers();\n\t\tif (matches.length === 0) {\n\t\t\tlines.push(renderInfoLine(theme, \"No builtin candidates — keep configuring manually.\", width));\n\t\t}\n\t\tfor (const [rowIndex, match] of matches.entries()) {\n\t\t\tconst { providerId, model } = match.entry;\n\t\t\tconst label = `${providerId} / ${model.id}`;\n\t\t\tconst note =\n\t\t\t\t(match.tier === \"exact\" ? \"exact · \" : \"\") +\n\t\t\t\t`${model.name !== model.id ? `${model.name} · ` : \"\"}${formatContext(model)}`;\n\t\t\tlines.push(\n\t\t\t\trenderPlainLine(theme, label, {\n\t\t\t\t\tactive: rowIndex === this.index,\n\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\tnote,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tlines.push(\n\t\t\trenderInfoLine(theme, \"Candidates are a reference only; the configured id is never rewritten.\", width),\n\t\t);\n\t\treturn lines;\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\t// The filter input pins above, the reference disclaimer below.\n\t\treturn { top: 1, bottom: 1, cursor: 1 + this.index };\n\t}\n\n\tprivate pickCurrent(): void {\n\t\tconst entry = this.candidates()[this.index];\n\t\tif (!entry) return;\n\t\tthis.host.pushPane(new BuiltinPreviewPane(this.host, this.model, entry));\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tconst count = this.candidates().length;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tif (count > 0) this.index = this.index === 0 ? count - 1 : this.index - 1;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tif (count > 0) this.index = (this.index + 1) % count;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.pickCurrent();\n\t\t\treturn;\n\t\t}\n\t\tconst before = this.query;\n\t\tthis.search.handleInput(data);\n\t\tthis.query = this.search.value;\n\t\tif (this.query !== before) this.index = 0;\n\t\tthis.host.refresh();\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t\tthis.search.focused = focused;\n\t}\n\n\tisEditing(): boolean {\n\t\treturn true; // the candidate filter always owns ←/→\n\t}\n\n\thints(): string {\n\t\treturn [\n\t\t\trawKeyHint(\"type\", \"filter\"),\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"preview\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n\nexport class BuiltinPreviewPane implements EditorPane {\n\treadonly crumb = \"Use Built-in Data · preview\";\n\tprivate readonly changes: FieldChange[];\n\tprivate readonly checked: boolean[];\n\tprivate readonly snapshot: Partial<ModelsJsonModel> & { id?: string };\n\tprivate readonly snapshotApi: string | undefined;\n\tprivate index = 0;\n\tprivate expanded: number | undefined;\n\tprivate error: string | undefined;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly model: ModelHandle;\n\tprivate readonly reference: CatalogEntry;\n\tconstructor(host: EditorHost, model: ModelHandle, reference: CatalogEntry) {\n\t\tthis.host = host;\n\t\tthis.model = model;\n\t\tthis.reference = reference;\n\n\t\tconst current = model.read();\n\t\tthis.snapshot = structuredClone(current);\n\t\tthis.snapshotApi = host.effectiveApi(current);\n\t\tthis.changes = computeFieldChanges(current, reference.model, host.effectiveApi(current));\n\t\tthis.checked = this.changes.map((change) => change.checked && change.applicable);\n\t}\n\n\tprivate rowCount(): number {\n\t\treturn this.changes.length + 1; // + Apply row\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst lines: string[] = [\n\t\t\trenderInfoLine(theme, `reference: ${this.reference.providerId} / ${this.reference.model.id}`, width),\n\t\t];\n\t\tfor (const [rowIndex, change] of this.changes.entries()) {\n\t\t\tconst active = rowIndex === this.index;\n\t\t\tconst expandable = change.referenceDetails !== undefined;\n\t\t\tconst note = !change.applicable ? \"· view only\" : undefined;\n\t\t\tlines.push(\n\t\t\t\trenderPlainLine(theme, `${change.field}: ${change.currentText} → ${change.referenceText}`, {\n\t\t\t\t\tchecked: change.applicable ? this.checked[rowIndex] : undefined,\n\t\t\t\t\tactive,\n\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\tnote,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (this.expanded === rowIndex && expandable) {\n\t\t\t\tfor (const detail of change.referenceDetails!) {\n\t\t\t\t\tlines.push(renderInfoLine(theme, ` ${detail}`, width));\n\t\t\t\t}\n\t\t\t\tif (change.referenceHasTiers) {\n\t\t\t\t\tlines.push(renderInfoLine(theme, \" reference has cost tiers — tiers are never imported.\", width));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlines.push(\n\t\t\trenderPlainLine(theme, \"Apply Selected Fields\", {\n\t\t\t\tactive: this.index === this.changes.length,\n\t\t\t\tpaneFocused: this.focused,\n\t\t\t\twidth,\n\t\t\t}),\n\t\t);\n\t\tif (this.error) lines.push(theme.fg(\"error\", truncate(this.error, Math.max(10, width - 2))));\n\t\treturn lines;\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\t// The reference header pins above; errors pin below. Expanded detail\n\t\t// lines shift the cursor row when they sit above it.\n\t\tlet cursor = 1 + this.index;\n\t\tif (this.expanded !== undefined && this.expanded < this.index) {\n\t\t\tconst change = this.changes[this.expanded]!;\n\t\t\tif (change.referenceDetails) {\n\t\t\t\tcursor += change.referenceDetails.length + (change.referenceHasTiers ? 1 : 0);\n\t\t\t}\n\t\t}\n\t\treturn { top: 1, bottom: this.error ? 1 : 0, cursor };\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.index = this.index === 0 ? this.rowCount() - 1 : this.index - 1;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.index = (this.index + 1) % this.rowCount();\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"app.list.toggle\")) {\n\t\t\tconst change = this.changes[this.index];\n\t\t\tif (!change) return;\n\t\t\tif (!change.applicable) {\n\t\t\t\tthis.expanded = this.expanded === this.index ? undefined : this.index;\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.checked[this.index] = !this.checked[this.index];\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tif (this.index === this.changes.length) {\n\t\t\t\tthis.apply();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst change = this.changes[this.index]!;\n\t\t\tif (change.referenceDetails) {\n\t\t\t\tthis.expanded = this.expanded === this.index ? undefined : this.index;\n\t\t\t} else if (change.applicable) {\n\t\t\t\tthis.checked[this.index] = !this.checked[this.index];\n\t\t\t}\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate apply(): void {\n\t\t// Re-validate against the live model: a stale preview must not write to a changed model.\n\t\tconst current = this.model.read();\n\t\tif (this.host.effectiveApi(current) !== this.snapshotApi) {\n\t\t\tthis.error = \"The API changed since this preview opened; reopen to continue.\";\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (!current.id || !jsonEquals(current, this.snapshot)) {\n\t\t\tthis.error = \"The model changed since this preview opened; reopen to continue.\";\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tconst chosen = this.changes.filter((_, rowIndex) => this.checked[rowIndex] && this.changes[rowIndex]!.applicable);\n\t\tif (chosen.length === 0) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t\tthis.host.store.batch(() => {\n\t\t\tfor (const change of chosen) this.applyChange(change.field);\n\t\t});\n\t\tthis.host.refresher.touch(this.host.providerId);\n\t\tthis.host.notify(\n\t\t\t`Applied ${chosen.length} field${chosen.length === 1 ? \"\" : \"s\"} from ${this.reference.providerId} / ${this.reference.model.id}.`,\n\t\t\t\"info\",\n\t\t);\n\t\tthis.host.popPane(); // preview\n\t\tthis.host.popPane(); // candidates → back to the model fields\n\t}\n\n\tprivate applyChange(field: FieldChange[\"field\"]): void {\n\t\tconst reference = this.reference.model;\n\t\tconst current = this.model.read();\n\t\tswitch (field) {\n\t\t\tcase \"name\":\n\t\t\t\tthis.model.setField([\"name\"], reference.name);\n\t\t\t\treturn;\n\t\t\tcase \"reasoning\":\n\t\t\t\tthis.model.setField([\"reasoning\"], reference.reasoning);\n\t\t\t\treturn;\n\t\t\tcase \"input\":\n\t\t\t\tthis.model.setField([\"input\"], [...reference.input]);\n\t\t\t\treturn;\n\t\t\tcase \"contextWindow\":\n\t\t\t\tthis.model.setField([\"contextWindow\"], reference.contextWindow);\n\t\t\t\treturn;\n\t\t\tcase \"maxTokens\":\n\t\t\t\tthis.model.setField([\"maxTokens\"], reference.maxTokens);\n\t\t\t\treturn;\n\t\t\tcase \"thinkingLevelMap\":\n\t\t\t\tfor (const [level, target] of Object.entries(reference.thinkingLevelMap ?? {})) {\n\t\t\t\t\tthis.model.setField([\"thinkingLevelMap\", level], target);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"compat\":\n\t\t\t\tfor (const [key, value] of Object.entries(reference.compat ?? {})) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t[\"chatTemplateKwargs\", \"chatTemplateArgs\", \"openRouterRouting\", \"vercelGatewayRouting\"].includes(\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\tvalue !== null &&\n\t\t\t\t\t\ttypeof value === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(value)\n\t\t\t\t\t) {\n\t\t\t\t\t\tfor (const [entryKey, entryValue] of Object.entries(value))\n\t\t\t\t\t\t\tthis.model.setField([\"compat\", key, entryKey], structuredClone(entryValue));\n\t\t\t\t\t} else this.model.setField([\"compat\", key], structuredClone(value));\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"cost\": {\n\t\t\t\tconst rates = {\n\t\t\t\t\tinput: reference.cost.input,\n\t\t\t\t\toutput: reference.cost.output,\n\t\t\t\t\tcacheRead: reference.cost.cacheRead,\n\t\t\t\t\tcacheWrite: reference.cost.cacheWrite,\n\t\t\t\t};\n\t\t\t\tif (current.cost) {\n\t\t\t\t\tfor (const [rate, value] of Object.entries(rates)) this.model.setField([\"cost\", rate], value);\n\t\t\t\t} else this.model.setField([\"cost\"], rates);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t}\n\n\thints(): string {\n\t\treturn [\n\t\t\tkeyHint(\"app.list.toggle\", \"check\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"details / apply\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n"]}
@@ -4,6 +4,7 @@
4
4
  * keys). Open dictionaries (chatTemplateKwargs/chatTemplateArgs) nest one
5
5
  * level deeper and allow free keys per the schema.
6
6
  */
7
+ import "../keybindings.ts";
7
8
  import type { EditorHost, EditorPane, ModelHandle } from "./pane.ts";
8
9
  import { type ScrollWindowInfo } from "./value-row.ts";
9
10
  export declare class CompatPane implements EditorPane {
@@ -1 +1 @@
1
- {"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/compat.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAIN,KAAK,gBAAgB,EAErB,MAAM,gBAAgB,CAAC;AAoBxB,qBAAa,UAAW,YAAW,UAAU;IAC5C,QAAQ,CAAC,KAAK,YAAY;IAC1B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBACxB,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAKhD,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,YAAY;IAIpB,yDAAyD;IACzD,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA6D/B,YAAY,IAAI,gBAAgB;IAMhC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6D/B,OAAO,CAAC,WAAW;IA4CnB,4EAA4E;IAC5E,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,IAAI;IAKZ,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAgBf;AAMD,qBAAa,mBAAoB,YAAW,UAAU;IACrD,QAAQ,CAAC,KAAK,6BAAwB;IACtC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAEnC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;IAYpG,OAAO,CAAC,UAAU;IAMlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAmB/B,YAAY,IAAI,gBAAgB;IAKhC,OAAO,CAAC,WAAW;IAOnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6B/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAQf"}
1
+ {"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/compat.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,mBAAmB,CAAC;AAO3B,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAIN,KAAK,gBAAgB,EAErB,MAAM,gBAAgB,CAAC;AAoBxB,qBAAa,UAAW,YAAW,UAAU;IAC5C,QAAQ,CAAC,KAAK,YAAY;IAC1B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBACxB,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAKhD,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,YAAY;IAIpB,yDAAyD;IACzD,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA6D/B,YAAY,IAAI,gBAAgB;IAMhC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6D/B,OAAO,CAAC,WAAW;IA4CnB,4EAA4E;IAC5E,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,IAAI;IAKZ,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAgBf;AAMD,qBAAa,mBAAoB,YAAW,UAAU;IACrD,QAAQ,CAAC,KAAK,6BAAwB;IACtC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAEnC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;IAYpG,OAAO,CAAC,UAAU;IAMlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAmB/B,YAAY,IAAI,gBAAgB;IAKhC,OAAO,CAAC,WAAW;IAOnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6B/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAQf"}
@@ -4,6 +4,7 @@
4
4
  * keys). Open dictionaries (chatTemplateKwargs/chatTemplateArgs) nest one
5
5
  * level deeper and allow free keys per the schema.
6
6
  */
7
+ import "../keybindings.js";
7
8
  import { fuzzyFilter } from "@earendil-works/pi-tui";
8
9
  import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
9
10
  import { compatFieldFor, compatFieldsForApi, validateJsonCompatValue } from "../compat-fields.js";