@astralyn/pi 0.87.1 → 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 (275) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/bundle/chunks/{chunk-CDMUKIXY.js → chunk-NBIUJDV6.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-772GXEFD.js → chunk-RFLBIA5Z.js} +69 -69
  4. package/dist/bundle/chunks/{virtual-modules-LQO2MG3T.js → virtual-modules-GOHLE5JL.js} +1 -1
  5. package/dist/bundle/cli.js +1 -1
  6. package/dist/bundle/index.js +1 -1
  7. package/dist/bundle/rpc-entry.js +1 -1
  8. package/dist/config.d.ts +1 -1
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session-runtime.d.ts +9 -0
  12. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  13. package/dist/core/agent-session-runtime.js +158 -157
  14. package/dist/core/agent-session-runtime.js.map +1 -1
  15. package/dist/core/agent-session.d.ts +14 -0
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +437 -434
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/background/types.d.ts +2 -0
  20. package/dist/core/background/types.d.ts.map +1 -1
  21. package/dist/core/background/types.js.map +1 -1
  22. package/dist/core/extensions/distribution-api.d.ts +41 -0
  23. package/dist/core/extensions/distribution-api.d.ts.map +1 -0
  24. package/dist/core/extensions/distribution-api.js +12 -0
  25. package/dist/core/extensions/distribution-api.js.map +1 -0
  26. package/dist/core/extensions/index.d.ts +1 -1
  27. package/dist/core/extensions/index.d.ts.map +1 -1
  28. package/dist/core/extensions/index.js.map +1 -1
  29. package/dist/core/extensions/loader.d.ts.map +1 -1
  30. package/dist/core/extensions/loader.js +1 -0
  31. package/dist/core/extensions/loader.js.map +1 -1
  32. package/dist/core/extensions/runner.d.ts.map +1 -1
  33. package/dist/core/extensions/runner.js +0 -2
  34. package/dist/core/extensions/runner.js.map +1 -1
  35. package/dist/core/extensions/types.d.ts +15 -45
  36. package/dist/core/extensions/types.d.ts.map +1 -1
  37. package/dist/core/extensions/types.js +1 -11
  38. package/dist/core/extensions/types.js.map +1 -1
  39. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  40. package/dist/core/extensions/virtual-modules.js +2 -1
  41. package/dist/core/extensions/virtual-modules.js.map +1 -1
  42. package/dist/core/keybinding-registry.d.ts +11 -0
  43. package/dist/core/keybinding-registry.d.ts.map +1 -0
  44. package/dist/core/keybinding-registry.js +24 -0
  45. package/dist/core/keybinding-registry.js.map +1 -0
  46. package/dist/core/keybindings.d.ts +4 -64
  47. package/dist/core/keybindings.d.ts.map +1 -1
  48. package/dist/core/keybindings.js +2 -41
  49. package/dist/core/keybindings.js.map +1 -1
  50. package/dist/core/model-config.d.ts +70 -2
  51. package/dist/core/model-config.d.ts.map +1 -1
  52. package/dist/core/model-config.js +2 -26
  53. package/dist/core/model-config.js.map +1 -1
  54. package/dist/core/resource-loader.d.ts.map +1 -1
  55. package/dist/core/resource-loader.js +5 -11
  56. package/dist/core/resource-loader.js.map +1 -1
  57. package/dist/core/tools/bash.d.ts.map +1 -1
  58. package/dist/core/tools/bash.js +2 -2
  59. package/dist/core/tools/bash.js.map +1 -1
  60. package/dist/core/tools/shell-execution.d.ts +1 -0
  61. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  62. package/dist/core/tools/shell-execution.js +21 -0
  63. package/dist/core/tools/shell-execution.js.map +1 -1
  64. package/dist/core/trust-manager.d.ts.map +1 -1
  65. package/dist/core/trust-manager.js +11 -48
  66. package/dist/core/trust-manager.js.map +1 -1
  67. package/dist/extensions/background/index.d.ts +2 -0
  68. package/dist/extensions/background/index.d.ts.map +1 -1
  69. package/dist/extensions/background/index.js +17 -0
  70. package/dist/extensions/background/index.js.map +1 -1
  71. package/dist/extensions/background/keybindings.d.ts +10 -0
  72. package/dist/extensions/background/keybindings.d.ts.map +1 -0
  73. package/dist/extensions/background/keybindings.js +14 -0
  74. package/dist/extensions/background/keybindings.js.map +1 -0
  75. package/dist/extensions/background/manager.d.ts +2 -0
  76. package/dist/extensions/background/manager.d.ts.map +1 -1
  77. package/dist/extensions/background/manager.js +1 -0
  78. package/dist/extensions/background/manager.js.map +1 -1
  79. package/dist/extensions/btw/controller.d.ts +1 -0
  80. package/dist/extensions/btw/controller.d.ts.map +1 -1
  81. package/dist/extensions/btw/controller.js +5 -5
  82. package/dist/extensions/btw/controller.js.map +1 -1
  83. package/dist/extensions/btw/index.js +1 -2
  84. package/dist/extensions/btw/index.js.map +1 -1
  85. package/dist/extensions/btw/keybindings.d.ts +10 -0
  86. package/dist/extensions/btw/keybindings.d.ts.map +1 -0
  87. package/dist/extensions/btw/keybindings.js +8 -0
  88. package/dist/extensions/btw/keybindings.js.map +1 -0
  89. package/dist/extensions/btw/panel.d.ts +1 -0
  90. package/dist/extensions/btw/panel.d.ts.map +1 -1
  91. package/dist/extensions/btw/panel.js +1 -0
  92. package/dist/extensions/btw/panel.js.map +1 -1
  93. package/dist/extensions/list-keybindings.d.ts +8 -0
  94. package/dist/extensions/list-keybindings.d.ts.map +1 -0
  95. package/dist/extensions/list-keybindings.js +8 -0
  96. package/dist/extensions/list-keybindings.js.map +1 -0
  97. package/dist/extensions/provider/compat-fields.d.ts.map +1 -1
  98. package/dist/extensions/provider/compat-fields.js +23 -3
  99. package/dist/extensions/provider/compat-fields.js.map +1 -1
  100. package/dist/extensions/provider/connection.d.ts.map +1 -1
  101. package/dist/extensions/provider/connection.js +1 -1
  102. package/dist/extensions/provider/connection.js.map +1 -1
  103. package/dist/extensions/provider/constants.d.ts +2 -0
  104. package/dist/extensions/provider/constants.d.ts.map +1 -1
  105. package/dist/extensions/provider/constants.js +2 -0
  106. package/dist/extensions/provider/constants.js.map +1 -1
  107. package/dist/extensions/provider/keybindings.d.ts +9 -0
  108. package/dist/extensions/provider/keybindings.d.ts.map +1 -0
  109. package/dist/extensions/provider/keybindings.js +12 -0
  110. package/dist/extensions/provider/keybindings.js.map +1 -0
  111. package/dist/extensions/provider/probe.d.ts +8 -4
  112. package/dist/extensions/provider/probe.d.ts.map +1 -1
  113. package/dist/extensions/provider/probe.js +169 -11
  114. package/dist/extensions/provider/probe.js.map +1 -1
  115. package/dist/extensions/provider/ui/builtin-data.d.ts +1 -0
  116. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  117. package/dist/extensions/provider/ui/builtin-data.js +1 -0
  118. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  119. package/dist/extensions/provider/ui/compat.d.ts +1 -0
  120. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  121. package/dist/extensions/provider/ui/compat.js +1 -0
  122. package/dist/extensions/provider/ui/compat.js.map +1 -1
  123. package/dist/extensions/provider/ui/dictionary.d.ts +1 -0
  124. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  125. package/dist/extensions/provider/ui/dictionary.js +1 -0
  126. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  127. package/dist/extensions/provider/ui/editor.d.ts +1 -0
  128. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  129. package/dist/extensions/provider/ui/editor.js +1 -0
  130. package/dist/extensions/provider/ui/editor.js.map +1 -1
  131. package/dist/extensions/provider/ui/fetch-models.d.ts +5 -3
  132. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  133. package/dist/extensions/provider/ui/fetch-models.js +28 -3
  134. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  135. package/dist/extensions/provider/ui/model-fields.d.ts +1 -0
  136. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  137. package/dist/extensions/provider/ui/model-fields.js +1 -0
  138. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  139. package/dist/extensions/provider/ui/model-options.d.ts +1 -0
  140. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  141. package/dist/extensions/provider/ui/model-options.js +1 -0
  142. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  143. package/dist/extensions/provider/ui/provider-fields.d.ts +1 -0
  144. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  145. package/dist/extensions/provider/ui/provider-fields.js +1 -0
  146. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  147. package/dist/extensions/question/dialog.d.ts +1 -0
  148. package/dist/extensions/question/dialog.d.ts.map +1 -1
  149. package/dist/extensions/question/dialog.js +1 -0
  150. package/dist/extensions/question/dialog.js.map +1 -1
  151. package/dist/extensions/question/keybindings.d.ts +2 -0
  152. package/dist/extensions/question/keybindings.d.ts.map +1 -0
  153. package/dist/extensions/question/keybindings.js +3 -0
  154. package/dist/extensions/question/keybindings.js.map +1 -0
  155. package/dist/index.d.ts +1 -1
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/modes/interactive/editor-host.d.ts +43 -0
  159. package/dist/modes/interactive/editor-host.d.ts.map +1 -0
  160. package/dist/modes/interactive/editor-host.js +83 -0
  161. package/dist/modes/interactive/editor-host.js.map +1 -0
  162. package/dist/modes/interactive/interactive-mode.d.ts +1 -11
  163. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  164. package/dist/modes/interactive/interactive-mode.js +300 -360
  165. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  166. package/dist/modes/interactive/tool-chat.d.ts +21 -0
  167. package/dist/modes/interactive/tool-chat.d.ts.map +1 -0
  168. package/dist/modes/interactive/tool-chat.js +58 -0
  169. package/dist/modes/interactive/tool-chat.js.map +1 -0
  170. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  171. package/dist/modes/rpc/rpc-mode.js +0 -2
  172. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  173. package/dist/utils/path-identity.d.ts +12 -0
  174. package/dist/utils/path-identity.d.ts.map +1 -0
  175. package/dist/utils/path-identity.js +63 -0
  176. package/dist/utils/path-identity.js.map +1 -0
  177. package/dist/utils/shell.d.ts +0 -1
  178. package/dist/utils/shell.d.ts.map +1 -1
  179. package/dist/utils/shell.js +0 -21
  180. package/dist/utils/shell.js.map +1 -1
  181. package/dist/utils/syntax-highlight.d.ts +2 -0
  182. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  183. package/dist/utils/syntax-highlight.js +2 -0
  184. package/dist/utils/syntax-highlight.js.map +1 -1
  185. package/docs/bundled/extensions/provider.md +7 -3
  186. package/docs/extensions.md +15 -5
  187. package/examples/extensions/README.md +34 -14
  188. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  189. package/examples/extensions/bash-spawn-hook.ts +2 -2
  190. package/examples/extensions/bookmark.ts +1 -1
  191. package/examples/extensions/border-status-editor.ts +6 -1
  192. package/examples/extensions/built-in-tool-renderer.ts +2 -2
  193. package/examples/extensions/claude-rules.ts +1 -1
  194. package/examples/extensions/commands.ts +1 -1
  195. package/examples/extensions/confirm-destructive.ts +1 -1
  196. package/examples/extensions/custom-compaction.ts +2 -2
  197. package/examples/extensions/custom-footer.ts +1 -1
  198. package/examples/extensions/custom-header.ts +2 -2
  199. package/examples/extensions/custom-provider-anthropic/index.ts +6 -6
  200. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  201. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  202. package/examples/extensions/custom-provider-gitlab-duo/index.ts +3 -3
  203. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  204. package/examples/extensions/dirty-repo-guard.ts +1 -1
  205. package/examples/extensions/doom-overlay/index.ts +1 -1
  206. package/examples/extensions/dynamic-resources/dynamic.json +3 -1
  207. package/examples/extensions/dynamic-resources/index.ts +1 -1
  208. package/examples/extensions/dynamic-tools.ts +1 -1
  209. package/examples/extensions/entry-renderer.ts +1 -1
  210. package/examples/extensions/event-bus.ts +1 -1
  211. package/examples/extensions/file-trigger.ts +1 -1
  212. package/examples/extensions/git-checkpoint.ts +1 -1
  213. package/examples/extensions/git-merge-and-resolve.ts +1 -1
  214. package/examples/extensions/github-issue-autocomplete.ts +1 -1
  215. package/examples/extensions/gondolin/index.ts +9 -7
  216. package/examples/extensions/gondolin/package-lock.json +2 -2
  217. package/examples/extensions/gondolin/package.json +1 -1
  218. package/examples/extensions/handoff.ts +2 -2
  219. package/examples/extensions/hello.ts +1 -1
  220. package/examples/extensions/hidden-thinking-label.ts +1 -1
  221. package/examples/extensions/inline-bash.ts +1 -1
  222. package/examples/extensions/input-transform-streaming.ts +1 -1
  223. package/examples/extensions/input-transform.ts +1 -1
  224. package/examples/extensions/interactive-shell.ts +1 -1
  225. package/examples/extensions/mac-system-theme.ts +1 -1
  226. package/examples/extensions/message-renderer.ts +1 -1
  227. package/examples/extensions/minimal-mode.ts +2 -2
  228. package/examples/extensions/modal-editor.ts +1 -1
  229. package/examples/extensions/model-status.ts +1 -1
  230. package/examples/extensions/notify.ts +1 -1
  231. package/examples/extensions/overlay-qa-tests.ts +3 -3
  232. package/examples/extensions/overlay-test.ts +1 -1
  233. package/examples/extensions/permission-gate.ts +1 -1
  234. package/examples/extensions/pirate.ts +1 -1
  235. package/examples/extensions/plan-mode/index.ts +1 -1
  236. package/examples/extensions/preset.ts +2 -2
  237. package/examples/extensions/project-trust.ts +3 -3
  238. package/examples/extensions/prompt-customizer.ts +1 -1
  239. package/examples/extensions/protected-paths.ts +1 -1
  240. package/examples/extensions/provider-payload.ts +1 -1
  241. package/examples/extensions/qna.ts +2 -2
  242. package/examples/extensions/question.ts +1 -1
  243. package/examples/extensions/questionnaire.ts +1 -1
  244. package/examples/extensions/rainbow-editor.ts +1 -1
  245. package/examples/extensions/reload-runtime.ts +1 -1
  246. package/examples/extensions/rpc-demo.ts +1 -1
  247. package/examples/extensions/sandbox/index.ts +2 -2
  248. package/examples/extensions/sandbox/package-lock.json +2 -2
  249. package/examples/extensions/sandbox/package.json +1 -1
  250. package/examples/extensions/send-user-message.ts +1 -1
  251. package/examples/extensions/session-name.ts +1 -1
  252. package/examples/extensions/shutdown-command.ts +1 -1
  253. package/examples/extensions/snake.ts +1 -1
  254. package/examples/extensions/space-invaders.ts +1 -1
  255. package/examples/extensions/ssh.ts +2 -2
  256. package/examples/extensions/status-line.ts +1 -1
  257. package/examples/extensions/structured-output.ts +1 -1
  258. package/examples/extensions/summarize.ts +2 -3
  259. package/examples/extensions/system-prompt-header.ts +1 -1
  260. package/examples/extensions/tic-tac-toe.ts +1 -1
  261. package/examples/extensions/timed-confirm.ts +1 -1
  262. package/examples/extensions/titlebar-spinner.ts +1 -1
  263. package/examples/extensions/todo.ts +1 -1
  264. package/examples/extensions/tool-override.ts +1 -1
  265. package/examples/extensions/tools.ts +2 -2
  266. package/examples/extensions/trigger-compact.ts +1 -1
  267. package/examples/extensions/truncated-tool.ts +4 -4
  268. package/examples/extensions/widget-placement.ts +1 -1
  269. package/examples/extensions/with-deps/index.ts +1 -1
  270. package/examples/extensions/with-deps/package-lock.json +2 -2
  271. package/examples/extensions/with-deps/package.json +1 -1
  272. package/examples/extensions/working-indicator.ts +1 -1
  273. package/examples/extensions/working-message-test.ts +1 -1
  274. package/npm-shrinkwrap.json +2 -2
  275. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/extensions/btw/panel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@earendil-works/pi-ai\";\nimport {\n\ttype Component,\n\tMarkdown,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { BtwTurn } from \"./agent.ts\";\n\nexport interface BtwPanelState {\n\tphase: \"opening\" | \"ready\" | \"error\";\n\terror?: string;\n\tcapturedAt?: number;\n\tmodel?: string;\n\tbusy: boolean;\n\tturns: readonly BtwTurn[];\n\tusage?: Usage;\n\tlatestCacheHitPercent?: number;\n\tusesSubscription?: boolean;\n\tblockedTools: number;\n}\n\nfunction tokens(value: number): string {\n\tif (value < 1000) return String(value);\n\tif (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n\tif (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n\tif (value < 10_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\treturn `${Math.round(value / 1_000_000)}M`;\n}\n\n/** A bounded, scrollable widget above the normal editor. It never takes keyboard focus. */\nexport class BtwPanel implements Component {\n\tprivate readonly tui: Pick<TUI, \"terminal\" | \"requestRender\">;\n\tprivate readonly getTheme: () => Theme;\n\tprivate readonly getState: () => BtwPanelState;\n\tprivate readonly answers = new Map<BtwTurn, Markdown>();\n\tprivate follow = true;\n\tprivate offset = 0;\n\tprivate maxOffset = 0;\n\tprivate heldHeight = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate disposed = false;\n\n\tconstructor(tui: Pick<TUI, \"terminal\" | \"requestRender\">, getTheme: () => Theme, getState: () => BtwPanelState) {\n\t\tthis.tui = tui;\n\t\tthis.getTheme = getTheme;\n\t\tthis.getState = getState;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.answers.clear();\n\t}\n\n\tchanged(): void {\n\t\tif (this.disposed) return;\n\t\tthis.tui.requestRender();\n\t\tif (this.getState().busy && !this.timer) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.timer = undefined;\n\t\t\t\tthis.changed();\n\t\t\t}, 150);\n\t\t\tthis.timer.unref?.();\n\t\t} else if (!this.getState().busy && this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n\n\tfollowTail(): void {\n\t\tthis.follow = true;\n\t\tthis.changed();\n\t}\n\n\tscroll(delta: number): boolean {\n\t\tif (this.maxOffset === 0) return false;\n\t\tthis.offset = Math.max(0, Math.min(this.maxOffset, this.offset + delta));\n\t\tthis.follow = this.offset === this.maxOffset;\n\t\tthis.tui.requestRender();\n\t\treturn true;\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t\tthis.answers.clear();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.disposed || width < 1) return [];\n\t\tconst state = this.getState();\n\t\tconst theme = this.getTheme();\n\t\tconst innerWidth = Math.max(1, width - 4);\n\t\tconst lines = this.body(state, innerWidth, theme);\n\t\tconst cap = Math.max(1, Math.floor(this.tui.terminal.rows / 3) - 2);\n\t\tconst needed = Math.min(cap, Math.max(1, lines.length));\n\t\tthis.heldHeight = state.busy ? Math.min(cap, Math.max(this.heldHeight, needed)) : needed;\n\t\tthis.maxOffset = Math.max(0, lines.length - this.heldHeight);\n\t\tthis.offset = this.follow ? this.maxOffset : Math.min(this.offset, this.maxOffset);\n\t\tconst body = lines.slice(this.offset, this.offset + this.heldHeight);\n\t\twhile (body.length < this.heldHeight) body.push(\"\");\n\t\tconst close = keyLabel(\"app.btw.close\");\n\t\tconst cancel = keyLabel(\"app.btw.cancel\");\n\t\tconst title = [\n\t\t\ttheme.fg(\"accent\", theme.bold(\"BTW\")),\n\t\t\tclose && theme.fg(\"text\", close) + theme.fg(\"muted\", \" close\"),\n\t\t\tstate.busy && cancel && theme.fg(\"text\", cancel) + theme.fg(\"muted\", \" stop\"),\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(theme.fg(\"muted\", \" · \"));\n\t\tconst footer = this.footer(state, theme);\n\t\tif (width < 6) return body.map((line) => truncateToWidth(line, width));\n\t\treturn [\n\t\t\tthis.border(title, width, true, theme),\n\t\t\t...body.map(\n\t\t\t\t(line) =>\n\t\t\t\t\ttheme.fg(\"borderAccent\", \"│ \") +\n\t\t\t\t\ttruncateToWidth(line, innerWidth, \"…\", true) +\n\t\t\t\t\ttheme.fg(\"borderAccent\", \" │\"),\n\t\t\t),\n\t\t\tthis.border(footer, width, false, theme),\n\t\t];\n\t}\n\n\tprivate body(state: BtwPanelState, width: number, theme: Theme): string[] {\n\t\tif (state.phase === \"opening\") return [theme.fg(\"muted\", \"Capturing context…\")];\n\t\tif (state.phase === \"error\")\n\t\t\treturn new Text(theme.fg(\"error\", state.error ?? \"Could not open BTW.\"), 0, 0).render(width);\n\t\tif (!state.turns.length) {\n\t\t\treturn [\n\t\t\t\t...new Text(theme.fg(\"text\", \"Ask a side question in the editor below.\"), 0, 0).render(width),\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t`Context at ${new Date(state.capturedAt ?? Date.now()).toTimeString().slice(0, 8)} · ${state.model ?? \"\"}`,\n\t\t\t\t\t),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t];\n\t\t}\n\t\tconst lines: string[] = [];\n\t\tfor (const [index, turn] of state.turns.entries()) {\n\t\t\tif (index > 0) lines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(`Q${index + 1}: `)) + theme.fg(\"text\", turn.question),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t);\n\t\t\tif (turn.answer) {\n\t\t\t\tlet markdown = this.answers.get(turn);\n\t\t\t\tif (!markdown) {\n\t\t\t\t\tmarkdown = new Markdown(turn.answer, 0, 0, getMarkdownTheme(), {\n\t\t\t\t\t\tcolor: (text) => theme.fg(\"text\", text),\n\t\t\t\t\t});\n\t\t\t\t\tthis.answers.set(turn, markdown);\n\t\t\t\t} else markdown.setText(turn.answer);\n\t\t\t\tlines.push(...markdown.render(width));\n\t\t\t} else if (turn.thinking && (turn.status === \"streaming\" || turn.status === \"cancelling\")) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(theme.fg(\"muted\", turn.thinking.trimEnd()), width).slice(-2));\n\t\t\t}\n\t\t\tif (turn.status === \"streaming\" || turn.status === \"cancelling\") {\n\t\t\t\tconst elapsed = ((Date.now() - turn.startedAt) / 1000).toFixed(1);\n\t\t\t\tlines.push(theme.fg(\"muted\", `${turn.status === \"cancelling\" ? \"Stopping\" : \"Answering\"}… ${elapsed}s`));\n\t\t\t}\n\t\t\tif (turn.notice)\n\t\t\t\tlines.push(\n\t\t\t\t\t...new Text(theme.fg(turn.status === \"error\" ? \"error\" : \"muted\", turn.notice), 0, 0).render(width),\n\t\t\t\t);\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate footer(state: BtwPanelState, theme: Theme): string {\n\t\tconst parts: string[] = [];\n\t\tconst label = (text: string) => theme.fg(\"muted\", text);\n\t\tconst value = (text: string) => theme.fg(\"text\", text);\n\t\tif (this.maxOffset > 0) {\n\t\t\tconst keys = [keyLabel(\"app.btw.scrollUp\"), keyLabel(\"app.btw.scrollDown\")].filter(Boolean).join(\"/\");\n\t\t\tparts.push(\n\t\t\t\tvalue(keys) +\n\t\t\t\t\tlabel(\" scroll \") +\n\t\t\t\t\tvalue(`${this.offset + 1}–${this.offset + this.heldHeight}/${this.maxOffset + this.heldHeight}`),\n\t\t\t);\n\t\t}\n\t\tconst usage = state.usage;\n\t\tif (usage) {\n\t\t\tconst stats: string[] = [];\n\t\t\tif (usage.input > 0) stats.push(`↑${tokens(usage.input)}`);\n\t\t\tif (usage.output > 0) stats.push(`↓${tokens(usage.output)}`);\n\t\t\tif (usage.cacheRead > 0) stats.push(`R${tokens(usage.cacheRead)}`);\n\t\t\tif (usage.cacheWrite > 0) stats.push(`W${tokens(usage.cacheWrite)}`);\n\t\t\tif (state.latestCacheHitPercent !== undefined) stats.push(`CH${state.latestCacheHitPercent.toFixed(1)}%`);\n\t\t\tif (usage.cost.total > 0)\n\t\t\t\tstats.push(`$${usage.cost.total.toFixed(3)}${state.usesSubscription ? \" (sub)\" : \"\"}`);\n\t\t\tif (stats.length) parts.push(value(stats.join(\" \")));\n\t\t}\n\t\tif (state.blockedTools) parts.push(value(String(state.blockedTools)) + label(\" tools blocked\"));\n\t\tconst turn = state.turns.at(-1);\n\t\tif (turn && !state.busy) {\n\t\t\tparts.push(value(`${(turn.elapsedMs / 1000).toFixed(1)}s`));\n\t\t\tif (turn.firstAnswerMs !== undefined)\n\t\t\t\tparts.push(label(\"first \") + value(`${(turn.firstAnswerMs / 1000).toFixed(1)}s`));\n\t\t}\n\t\treturn parts.join(label(\" · \"));\n\t}\n\n\tprivate border(label: string, width: number, top: boolean, theme: Theme): string {\n\t\tconst text = label ? ` ${truncateToWidth(label, Math.max(0, width - 4))} ` : \"\";\n\t\treturn (\n\t\t\ttheme.fg(\"borderAccent\", top ? \"╭\" : \"╰\") +\n\t\t\ttext +\n\t\t\ttheme.fg(\"borderAccent\", `${\"─\".repeat(Math.max(0, width - visibleWidth(text) - 2))}${top ? \"╮\" : \"╯\"}`)\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/extensions/btw/panel.ts"],"names":[],"mappings":"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","sourcesContent":["import \"./keybindings.ts\";\nimport type { Usage } from \"@earendil-works/pi-ai\";\nimport {\n\ttype Component,\n\tMarkdown,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { BtwTurn } from \"./agent.ts\";\n\nexport interface BtwPanelState {\n\tphase: \"opening\" | \"ready\" | \"error\";\n\terror?: string;\n\tcapturedAt?: number;\n\tmodel?: string;\n\tbusy: boolean;\n\tturns: readonly BtwTurn[];\n\tusage?: Usage;\n\tlatestCacheHitPercent?: number;\n\tusesSubscription?: boolean;\n\tblockedTools: number;\n}\n\nfunction tokens(value: number): string {\n\tif (value < 1000) return String(value);\n\tif (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n\tif (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n\tif (value < 10_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\treturn `${Math.round(value / 1_000_000)}M`;\n}\n\n/** A bounded, scrollable widget above the normal editor. It never takes keyboard focus. */\nexport class BtwPanel implements Component {\n\tprivate readonly tui: Pick<TUI, \"terminal\" | \"requestRender\">;\n\tprivate readonly getTheme: () => Theme;\n\tprivate readonly getState: () => BtwPanelState;\n\tprivate readonly answers = new Map<BtwTurn, Markdown>();\n\tprivate follow = true;\n\tprivate offset = 0;\n\tprivate maxOffset = 0;\n\tprivate heldHeight = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate disposed = false;\n\n\tconstructor(tui: Pick<TUI, \"terminal\" | \"requestRender\">, getTheme: () => Theme, getState: () => BtwPanelState) {\n\t\tthis.tui = tui;\n\t\tthis.getTheme = getTheme;\n\t\tthis.getState = getState;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.answers.clear();\n\t}\n\n\tchanged(): void {\n\t\tif (this.disposed) return;\n\t\tthis.tui.requestRender();\n\t\tif (this.getState().busy && !this.timer) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.timer = undefined;\n\t\t\t\tthis.changed();\n\t\t\t}, 150);\n\t\t\tthis.timer.unref?.();\n\t\t} else if (!this.getState().busy && this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n\n\tfollowTail(): void {\n\t\tthis.follow = true;\n\t\tthis.changed();\n\t}\n\n\tscroll(delta: number): boolean {\n\t\tif (this.maxOffset === 0) return false;\n\t\tthis.offset = Math.max(0, Math.min(this.maxOffset, this.offset + delta));\n\t\tthis.follow = this.offset === this.maxOffset;\n\t\tthis.tui.requestRender();\n\t\treturn true;\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t\tthis.answers.clear();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.disposed || width < 1) return [];\n\t\tconst state = this.getState();\n\t\tconst theme = this.getTheme();\n\t\tconst innerWidth = Math.max(1, width - 4);\n\t\tconst lines = this.body(state, innerWidth, theme);\n\t\tconst cap = Math.max(1, Math.floor(this.tui.terminal.rows / 3) - 2);\n\t\tconst needed = Math.min(cap, Math.max(1, lines.length));\n\t\tthis.heldHeight = state.busy ? Math.min(cap, Math.max(this.heldHeight, needed)) : needed;\n\t\tthis.maxOffset = Math.max(0, lines.length - this.heldHeight);\n\t\tthis.offset = this.follow ? this.maxOffset : Math.min(this.offset, this.maxOffset);\n\t\tconst body = lines.slice(this.offset, this.offset + this.heldHeight);\n\t\twhile (body.length < this.heldHeight) body.push(\"\");\n\t\tconst close = keyLabel(\"app.btw.close\");\n\t\tconst cancel = keyLabel(\"app.btw.cancel\");\n\t\tconst title = [\n\t\t\ttheme.fg(\"accent\", theme.bold(\"BTW\")),\n\t\t\tclose && theme.fg(\"text\", close) + theme.fg(\"muted\", \" close\"),\n\t\t\tstate.busy && cancel && theme.fg(\"text\", cancel) + theme.fg(\"muted\", \" stop\"),\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(theme.fg(\"muted\", \" · \"));\n\t\tconst footer = this.footer(state, theme);\n\t\tif (width < 6) return body.map((line) => truncateToWidth(line, width));\n\t\treturn [\n\t\t\tthis.border(title, width, true, theme),\n\t\t\t...body.map(\n\t\t\t\t(line) =>\n\t\t\t\t\ttheme.fg(\"borderAccent\", \"│ \") +\n\t\t\t\t\ttruncateToWidth(line, innerWidth, \"…\", true) +\n\t\t\t\t\ttheme.fg(\"borderAccent\", \" │\"),\n\t\t\t),\n\t\t\tthis.border(footer, width, false, theme),\n\t\t];\n\t}\n\n\tprivate body(state: BtwPanelState, width: number, theme: Theme): string[] {\n\t\tif (state.phase === \"opening\") return [theme.fg(\"muted\", \"Capturing context…\")];\n\t\tif (state.phase === \"error\")\n\t\t\treturn new Text(theme.fg(\"error\", state.error ?? \"Could not open BTW.\"), 0, 0).render(width);\n\t\tif (!state.turns.length) {\n\t\t\treturn [\n\t\t\t\t...new Text(theme.fg(\"text\", \"Ask a side question in the editor below.\"), 0, 0).render(width),\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t`Context at ${new Date(state.capturedAt ?? Date.now()).toTimeString().slice(0, 8)} · ${state.model ?? \"\"}`,\n\t\t\t\t\t),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t];\n\t\t}\n\t\tconst lines: string[] = [];\n\t\tfor (const [index, turn] of state.turns.entries()) {\n\t\t\tif (index > 0) lines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(`Q${index + 1}: `)) + theme.fg(\"text\", turn.question),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t);\n\t\t\tif (turn.answer) {\n\t\t\t\tlet markdown = this.answers.get(turn);\n\t\t\t\tif (!markdown) {\n\t\t\t\t\tmarkdown = new Markdown(turn.answer, 0, 0, getMarkdownTheme(), {\n\t\t\t\t\t\tcolor: (text) => theme.fg(\"text\", text),\n\t\t\t\t\t});\n\t\t\t\t\tthis.answers.set(turn, markdown);\n\t\t\t\t} else markdown.setText(turn.answer);\n\t\t\t\tlines.push(...markdown.render(width));\n\t\t\t} else if (turn.thinking && (turn.status === \"streaming\" || turn.status === \"cancelling\")) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(theme.fg(\"muted\", turn.thinking.trimEnd()), width).slice(-2));\n\t\t\t}\n\t\t\tif (turn.status === \"streaming\" || turn.status === \"cancelling\") {\n\t\t\t\tconst elapsed = ((Date.now() - turn.startedAt) / 1000).toFixed(1);\n\t\t\t\tlines.push(theme.fg(\"muted\", `${turn.status === \"cancelling\" ? \"Stopping\" : \"Answering\"}… ${elapsed}s`));\n\t\t\t}\n\t\t\tif (turn.notice)\n\t\t\t\tlines.push(\n\t\t\t\t\t...new Text(theme.fg(turn.status === \"error\" ? \"error\" : \"muted\", turn.notice), 0, 0).render(width),\n\t\t\t\t);\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate footer(state: BtwPanelState, theme: Theme): string {\n\t\tconst parts: string[] = [];\n\t\tconst label = (text: string) => theme.fg(\"muted\", text);\n\t\tconst value = (text: string) => theme.fg(\"text\", text);\n\t\tif (this.maxOffset > 0) {\n\t\t\tconst keys = [keyLabel(\"app.btw.scrollUp\"), keyLabel(\"app.btw.scrollDown\")].filter(Boolean).join(\"/\");\n\t\t\tparts.push(\n\t\t\t\tvalue(keys) +\n\t\t\t\t\tlabel(\" scroll \") +\n\t\t\t\t\tvalue(`${this.offset + 1}–${this.offset + this.heldHeight}/${this.maxOffset + this.heldHeight}`),\n\t\t\t);\n\t\t}\n\t\tconst usage = state.usage;\n\t\tif (usage) {\n\t\t\tconst stats: string[] = [];\n\t\t\tif (usage.input > 0) stats.push(`↑${tokens(usage.input)}`);\n\t\t\tif (usage.output > 0) stats.push(`↓${tokens(usage.output)}`);\n\t\t\tif (usage.cacheRead > 0) stats.push(`R${tokens(usage.cacheRead)}`);\n\t\t\tif (usage.cacheWrite > 0) stats.push(`W${tokens(usage.cacheWrite)}`);\n\t\t\tif (state.latestCacheHitPercent !== undefined) stats.push(`CH${state.latestCacheHitPercent.toFixed(1)}%`);\n\t\t\tif (usage.cost.total > 0)\n\t\t\t\tstats.push(`$${usage.cost.total.toFixed(3)}${state.usesSubscription ? \" (sub)\" : \"\"}`);\n\t\t\tif (stats.length) parts.push(value(stats.join(\" \")));\n\t\t}\n\t\tif (state.blockedTools) parts.push(value(String(state.blockedTools)) + label(\" tools blocked\"));\n\t\tconst turn = state.turns.at(-1);\n\t\tif (turn && !state.busy) {\n\t\t\tparts.push(value(`${(turn.elapsedMs / 1000).toFixed(1)}s`));\n\t\t\tif (turn.firstAnswerMs !== undefined)\n\t\t\t\tparts.push(label(\"first \") + value(`${(turn.firstAnswerMs / 1000).toFixed(1)}s`));\n\t\t}\n\t\treturn parts.join(label(\" · \"));\n\t}\n\n\tprivate border(label: string, width: number, top: boolean, theme: Theme): string {\n\t\tconst text = label ? ` ${truncateToWidth(label, Math.max(0, width - 4))} ` : \"\";\n\t\treturn (\n\t\t\ttheme.fg(\"borderAccent\", top ? \"╭\" : \"╰\") +\n\t\t\ttext +\n\t\t\ttheme.fg(\"borderAccent\", `${\"─\".repeat(Math.max(0, width - visibleWidth(text) - 2))}${top ? \"╮\" : \"╯\"}`)\n\t\t);\n\t}\n}\n"]}
@@ -0,0 +1,8 @@
1
+ declare module "../core/keybindings.ts" {
2
+ interface AppKeybindings {
3
+ "app.list.toggle": true;
4
+ }
5
+ }
6
+ /** Multi-select lists shared by bundled extensions (Question and /provider). */
7
+ export declare function registerListKeybindings(): void;
8
+ //# sourceMappingURL=list-keybindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-keybindings.d.ts","sourceRoot":"","sources":["../../src/extensions/list-keybindings.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,wBAAwB,CAAC;IACvC,UAAU,cAAc;QACvB,iBAAiB,EAAE,IAAI,CAAC;KACxB;CACD;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C"}
@@ -0,0 +1,8 @@
1
+ import { registerKeybindings } from "../core/keybinding-registry.js";
2
+ /** Multi-select lists shared by bundled extensions (Question and /provider). */
3
+ export function registerListKeybindings() {
4
+ registerKeybindings({
5
+ "app.list.toggle": { defaultKeys: "space", description: "Toggle selected list item" },
6
+ });
7
+ }
8
+ //# sourceMappingURL=list-keybindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-keybindings.js","sourceRoot":"","sources":["../../src/extensions/list-keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAQrE,gFAAgF;AAChF,MAAM,UAAU,uBAAuB;IACtC,mBAAmB,CAAC;QACnB,iBAAiB,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE;KACrF,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { registerKeybindings } from \"../core/keybinding-registry.ts\";\n\ndeclare module \"../core/keybindings.ts\" {\n\tinterface AppKeybindings {\n\t\t\"app.list.toggle\": true;\n\t}\n}\n\n/** Multi-select lists shared by bundled extensions (Question and /provider). */\nexport function registerListKeybindings(): void {\n\tregisterKeybindings({\n\t\t\"app.list.toggle\": { defaultKeys: \"space\", description: \"Toggle selected list item\" },\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compat-fields.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/compat-fields.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnF,MAAM,MAAM,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IACtD,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEhG,eAAO,MAAM,kBAAkB,qEAI0D,CAAC;AAgG1F,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CA0BtE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEhF;AAED,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQrF;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAW5E"}
1
+ {"version":3,"file":"compat-fields.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/compat-fields.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnF,MAAM,MAAM,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IACtD,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEhG,eAAO,MAAM,kBAAkB,qEAI0D,CAAC;AAgG1F,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CA0BtE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEhF;AAuBD,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQrF;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAW5E"}
@@ -4,7 +4,8 @@
4
4
  * AnthropicMessagesCompat / BedrockCompat). Each API variant exposes only the settings consumed by its published
5
5
  * implementation; existing foreign fields are preserved by the editor.
6
6
  */
7
- import { ModelConfig } from "../../core/model-config.js";
7
+ import { Compile } from "typebox/compile";
8
+ import { OpenAICompletionsCompatSchema } from "../../core/model-config.js";
8
9
  export const THINKING_VARIABLES = [
9
10
  "thinking.enabled",
10
11
  "thinking.effort",
@@ -126,6 +127,25 @@ export function compatFieldsForApi(api) {
126
127
  export function compatFieldFor(api, key) {
127
128
  return compatFieldsForApi(api).find((field) => field.key === key);
128
129
  }
130
+ const completionsCompatValidator = Compile(OpenAICompletionsCompatSchema);
131
+ /** Validate against models.json's openai-completions compat schema; returns the first errors, if any. */
132
+ function validateCompletionsCompat(value) {
133
+ if (completionsCompatValidator.Check(value))
134
+ return undefined;
135
+ return completionsCompatValidator
136
+ .Errors(value)
137
+ .slice(0, 5)
138
+ .map((error) => {
139
+ const path = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
140
+ // Name the missing property itself, as models.json load errors do.
141
+ const required = error.keyword === "required"
142
+ ? error.params.requiredProperties?.[0]
143
+ : undefined;
144
+ const field = required ? (path ? `${path}.${required}` : required) : path || "root";
145
+ return `${field}: ${error.message}`;
146
+ })
147
+ .join("; ");
148
+ }
129
149
  /** Parse JSON values and reuse the canonical models.json schema, including nested validation. */
130
150
  export function validateJsonCompatValue(key, text) {
131
151
  let value;
@@ -135,7 +155,7 @@ export function validateJsonCompatValue(key, text) {
135
155
  catch {
136
156
  return "Value is not valid JSON.";
137
157
  }
138
- return ModelConfig.validateCompat("openai-completions", { [key]: value });
158
+ return validateCompletionsCompat({ [key]: value });
139
159
  }
140
160
  /** Chat-template values share the core schema and the published pi-ai value contract. */
141
161
  export function validateChatTemplateKwarg(value) {
@@ -145,7 +165,7 @@ export function validateChatTemplateKwarg(value) {
145
165
  !Object.keys(value).every((key) => key === "$var" || key === "omitWhenOff")) {
146
166
  return 'Only "$var" and "omitWhenOff" are allowed.';
147
167
  }
148
- const error = ModelConfig.validateCompat("openai-completions", { chatTemplateKwargs: { value } });
168
+ const error = validateCompletionsCompat({ chatTemplateKwargs: { value } });
149
169
  return error ? `Value must be a scalar or valid $var reference: ${error}` : undefined;
150
170
  }
151
171
  //# sourceMappingURL=compat-fields.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compat-fields.js","sourceRoot":"","sources":["../../../src/extensions/provider/compat-fields.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Compat field catalog per effective API, derived from pi-ai's public compat\n * types (OpenAICompletionsCompat / OpenAIResponsesCompat /\n * AnthropicMessagesCompat / BedrockCompat). Each API variant exposes only the settings consumed by its published\n * implementation; existing foreign fields are preserved by the editor.\n */\n\nimport type {\n\tAnthropicMessagesCompat,\n\tBedrockCompat,\n\tChatTemplateKwargValue,\n\tOpenAICompletionsCompat,\n\tOpenAIResponsesCompat,\n} from \"@earendil-works/pi-ai\";\nimport { ModelConfig } from \"../../core/model-config.ts\";\n\nexport type CompatValueKind = \"boolean\" | \"enum\" | \"number\" | \"stringMap\" | \"json\";\n\nexport type CompatField<Key extends string = string> = {\n\tkey: Key;\n\tnote?: string;\n} & ({ kind: \"enum\"; options: readonly string[] } | { kind: Exclude<CompatValueKind, \"enum\"> });\n\nexport const THINKING_VARIABLES = [\n\t\"thinking.enabled\",\n\t\"thinking.effort\",\n\t\"thinking.budget\",\n] as const satisfies readonly Extract<ChatTemplateKwargValue, { $var: string }>[\"$var\"][];\n\nconst SESSION_AFFINITY = [\"openai\", \"openai-nosession\", \"openrouter\"] as const;\n\nconst OPENAI_COMPLETIONS_FIELDS: readonly CompatField<keyof OpenAICompletionsCompat>[] = [\n\t{ key: \"supportsStore\", kind: \"boolean\", note: \"Accepts the `store` parameter\" },\n\t{ key: \"supportsDeveloperRole\", kind: \"boolean\", note: \"Accepts `developer` role messages\" },\n\t{ key: \"supportsReasoningEffort\", kind: \"boolean\", note: \"Accepts `reasoning_effort`\" },\n\t{ key: \"supportsUsageInStreaming\", kind: \"boolean\", note: \"Streams usage chunks\" },\n\t{ key: \"supportsFinishReason\", kind: \"boolean\", note: \"Reports finish reasons\" },\n\t{\n\t\tkey: \"maxTokensField\",\n\t\tkind: \"enum\",\n\t\toptions: [\"max_completion_tokens\", \"max_tokens\"],\n\t\tnote: \"Token limit field name\",\n\t},\n\t{ key: \"requiresToolResultName\", kind: \"boolean\", note: \"Tool results need a `name`\" },\n\t{ key: \"requiresAssistantAfterToolResult\", kind: \"boolean\", note: \"Needs assistant message after tool results\" },\n\t{ key: \"requiresThinkingAsText\", kind: \"boolean\", note: \"Thinking must be plain text\" },\n\t{\n\t\tkey: \"requiresReasoningContentOnAssistantMessages\",\n\t\tkind: \"boolean\",\n\t\tnote: \"Assistant messages must carry reasoning content\",\n\t},\n\t{\n\t\tkey: \"thinkingFormat\",\n\t\tkind: \"enum\",\n\t\toptions: [\n\t\t\t\"openai\",\n\t\t\t\"openrouter\",\n\t\t\t\"together\",\n\t\t\t\"baseten\",\n\t\t\t\"deepseek\",\n\t\t\t\"zai\",\n\t\t\t\"qwen\",\n\t\t\t\"chat-template\",\n\t\t\t\"qwen-chat-template\",\n\t\t\t\"string-thinking\",\n\t\t\t\"ant-ling\",\n\t\t],\n\t\tnote: \"Reasoning payload format\",\n\t},\n\t{ key: \"chatTemplateKwargs\", kind: \"stringMap\", note: \"Extra chat-template kwargs (open dictionary)\" },\n\t{ key: \"chatTemplateArgs\", kind: \"stringMap\", note: \"Extra chat-template args (open dictionary)\" },\n\t{ key: \"cacheControlFormat\", kind: \"enum\", options: [\"anthropic\"], note: \"Cache-control payload format\" },\n\t{ key: \"openRouterRouting\", kind: \"json\", note: \"OpenRouter routing preferences object\" },\n\t{ key: \"vercelGatewayRouting\", kind: \"json\", note: \"Vercel AI Gateway routing object\" },\n\t{ key: \"supportsOpenAIGrammarTools\", kind: \"boolean\", note: \"Grammar-constrained tool calls\" },\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"sendSessionAffinityHeaders\", kind: \"boolean\", note: \"Send session affinity headers\" },\n\t{ key: \"supportsMidConvoSystemMessages\", kind: \"boolean\", note: \"Accepts mid-conversation system messages\" },\n\t{ key: \"supportsMidConvoToolAdditions\", kind: \"boolean\", note: \"System messages can add tools mid-conversation\" },\n\t{ key: \"sessionAffinityFormat\", kind: \"enum\", options: SESSION_AFFINITY, note: \"Affinity header format\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"vllmPriority\", kind: \"number\", note: \"vLLM scheduling priority\" },\n\t{ key: \"zaiToolStream\", kind: \"boolean\", note: \"Z.AI streaming tool calls\" },\n\t{ key: \"supportsThinkingTokenBudget\", kind: \"boolean\", note: \"Enable the thinking-token budget alias\" },\n\t{\n\t\tkey: \"thinkingTokenBudgetField\",\n\t\tkind: \"enum\",\n\t\toptions: [\"thinking_token_budget\", \"thinking_budget\", \"thinking_budget_tokens\"],\n\t\tnote: \"Thinking budget field\",\n\t},\n];\n\nconst OPENAI_RESPONSES_FIELDS: readonly CompatField<keyof OpenAIResponsesCompat>[] = [\n\t{ key: \"supportsDeveloperRole\", kind: \"boolean\", note: \"Accepts `developer` role messages\" },\n\t{ key: \"sessionAffinityFormat\", kind: \"enum\", options: SESSION_AFFINITY, note: \"Affinity header format\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"supportsOpenAIGrammarTools\", kind: \"boolean\", note: \"Grammar-constrained tool calls\" },\n\t{ key: \"supportsAdditionalTools\", kind: \"boolean\", note: \"Accepts additional hosted tools\" },\n\t{ key: \"supportsToolSearch\", kind: \"boolean\", note: \"Tool search support\" },\n\t{ key: \"supportsMaxOutputTokens\", kind: \"boolean\", note: \"Accepts `max_output_tokens`\" },\n\t{ key: \"supportsExplicitPromptCacheMode\", kind: \"boolean\", note: \"Explicit prompt caching\" },\n];\n\nconst ANTHROPIC_MESSAGES_FIELDS: readonly CompatField<keyof AnthropicMessagesCompat>[] = [\n\t{ key: \"supportsEagerToolInputStreaming\", kind: \"boolean\", note: \"Streams tool input eagerly\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"sendSessionAffinityHeaders\", kind: \"boolean\", note: \"Send session affinity headers\" },\n\t{ key: \"supportsCacheControlOnTools\", kind: \"boolean\", note: \"Cache control on tool definitions\" },\n\t{ key: \"supportsTemperature\", kind: \"boolean\", note: \"Accepts `temperature`\" },\n\t{ key: \"forceAdaptiveThinking\", kind: \"boolean\", note: \"Force adaptive thinking mode\" },\n\t{ key: \"allowEmptySignature\", kind: \"boolean\", note: \"Tolerate empty thinking signatures\" },\n\t{ key: \"supportsStrictTools\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"supportsMidConvoEffort\", kind: \"boolean\", note: \"Effort changes mid-conversation\" },\n\t{ key: \"supportsMidConvoSystemMessages\", kind: \"boolean\", note: \"Accepts mid-conversation system messages\" },\n\t{ key: \"supportsMidConvoToolChanges\", kind: \"boolean\", note: \"Accepts mid-conversation tool changes\" },\n\t{ key: \"allowedFallbackModels\", kind: \"json\", note: \"Server-side refusal fallback models\" },\n];\n\nconst BEDROCK_FIELDS: readonly CompatField<keyof BedrockCompat>[] = [\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n];\n\n/** Compat fields known for the given effective api; empty when the API consumes no compat object. */\nexport function compatFieldsForApi(api: string): readonly CompatField[] {\n\tswitch (api) {\n\t\tcase \"openai-completions\":\n\t\t\treturn OPENAI_COMPLETIONS_FIELDS;\n\t\tcase \"openai-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS;\n\t\tcase \"azure-openai-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS.filter((field) =>\n\t\t\t\t[\"supportsDeveloperRole\", \"supportsStrictMode\", \"supportsOpenAIGrammarTools\"].includes(field.key),\n\t\t\t);\n\t\tcase \"openai-codex-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS.filter((field) =>\n\t\t\t\t[\n\t\t\t\t\t\"supportsStrictMode\",\n\t\t\t\t\t\"supportsOpenAIGrammarTools\",\n\t\t\t\t\t\"supportsAdditionalTools\",\n\t\t\t\t\t\"supportsToolSearch\",\n\t\t\t\t].includes(field.key),\n\t\t\t);\n\t\tcase \"anthropic-messages\":\n\t\t\treturn ANTHROPIC_MESSAGES_FIELDS;\n\t\tcase \"bedrock-converse-stream\":\n\t\t\treturn BEDROCK_FIELDS;\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nexport function compatFieldFor(api: string, key: string): CompatField | undefined {\n\treturn compatFieldsForApi(api).find((field) => field.key === key);\n}\n\n/** Parse JSON values and reuse the canonical models.json schema, including nested validation. */\nexport function validateJsonCompatValue(key: string, text: string): string | undefined {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {\n\t\treturn \"Value is not valid JSON.\";\n\t}\n\treturn ModelConfig.validateCompat(\"openai-completions\", { [key]: value });\n}\n\n/** Chat-template values share the core schema and the published pi-ai value contract. */\nexport function validateChatTemplateKwarg(value: unknown): string | undefined {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === \"object\" &&\n\t\t!Array.isArray(value) &&\n\t\t!Object.keys(value).every((key) => key === \"$var\" || key === \"omitWhenOff\")\n\t) {\n\t\treturn 'Only \"$var\" and \"omitWhenOff\" are allowed.';\n\t}\n\tconst error = ModelConfig.validateCompat(\"openai-completions\", { chatTemplateKwargs: { value } });\n\treturn error ? `Value must be a scalar or valid $var reference: ${error}` : undefined;\n}\n"]}
1
+ {"version":3,"file":"compat-fields.js","sourceRoot":"","sources":["../../../src/extensions/provider/compat-fields.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Compat field catalog per effective API, derived from pi-ai's public compat\n * types (OpenAICompletionsCompat / OpenAIResponsesCompat /\n * AnthropicMessagesCompat / BedrockCompat). Each API variant exposes only the settings consumed by its published\n * implementation; existing foreign fields are preserved by the editor.\n */\n\nimport type {\n\tAnthropicMessagesCompat,\n\tBedrockCompat,\n\tChatTemplateKwargValue,\n\tOpenAICompletionsCompat,\n\tOpenAIResponsesCompat,\n} from \"@earendil-works/pi-ai\";\nimport { Compile } from \"typebox/compile\";\nimport { OpenAICompletionsCompatSchema } from \"../../core/model-config.ts\";\n\nexport type CompatValueKind = \"boolean\" | \"enum\" | \"number\" | \"stringMap\" | \"json\";\n\nexport type CompatField<Key extends string = string> = {\n\tkey: Key;\n\tnote?: string;\n} & ({ kind: \"enum\"; options: readonly string[] } | { kind: Exclude<CompatValueKind, \"enum\"> });\n\nexport const THINKING_VARIABLES = [\n\t\"thinking.enabled\",\n\t\"thinking.effort\",\n\t\"thinking.budget\",\n] as const satisfies readonly Extract<ChatTemplateKwargValue, { $var: string }>[\"$var\"][];\n\nconst SESSION_AFFINITY = [\"openai\", \"openai-nosession\", \"openrouter\"] as const;\n\nconst OPENAI_COMPLETIONS_FIELDS: readonly CompatField<keyof OpenAICompletionsCompat>[] = [\n\t{ key: \"supportsStore\", kind: \"boolean\", note: \"Accepts the `store` parameter\" },\n\t{ key: \"supportsDeveloperRole\", kind: \"boolean\", note: \"Accepts `developer` role messages\" },\n\t{ key: \"supportsReasoningEffort\", kind: \"boolean\", note: \"Accepts `reasoning_effort`\" },\n\t{ key: \"supportsUsageInStreaming\", kind: \"boolean\", note: \"Streams usage chunks\" },\n\t{ key: \"supportsFinishReason\", kind: \"boolean\", note: \"Reports finish reasons\" },\n\t{\n\t\tkey: \"maxTokensField\",\n\t\tkind: \"enum\",\n\t\toptions: [\"max_completion_tokens\", \"max_tokens\"],\n\t\tnote: \"Token limit field name\",\n\t},\n\t{ key: \"requiresToolResultName\", kind: \"boolean\", note: \"Tool results need a `name`\" },\n\t{ key: \"requiresAssistantAfterToolResult\", kind: \"boolean\", note: \"Needs assistant message after tool results\" },\n\t{ key: \"requiresThinkingAsText\", kind: \"boolean\", note: \"Thinking must be plain text\" },\n\t{\n\t\tkey: \"requiresReasoningContentOnAssistantMessages\",\n\t\tkind: \"boolean\",\n\t\tnote: \"Assistant messages must carry reasoning content\",\n\t},\n\t{\n\t\tkey: \"thinkingFormat\",\n\t\tkind: \"enum\",\n\t\toptions: [\n\t\t\t\"openai\",\n\t\t\t\"openrouter\",\n\t\t\t\"together\",\n\t\t\t\"baseten\",\n\t\t\t\"deepseek\",\n\t\t\t\"zai\",\n\t\t\t\"qwen\",\n\t\t\t\"chat-template\",\n\t\t\t\"qwen-chat-template\",\n\t\t\t\"string-thinking\",\n\t\t\t\"ant-ling\",\n\t\t],\n\t\tnote: \"Reasoning payload format\",\n\t},\n\t{ key: \"chatTemplateKwargs\", kind: \"stringMap\", note: \"Extra chat-template kwargs (open dictionary)\" },\n\t{ key: \"chatTemplateArgs\", kind: \"stringMap\", note: \"Extra chat-template args (open dictionary)\" },\n\t{ key: \"cacheControlFormat\", kind: \"enum\", options: [\"anthropic\"], note: \"Cache-control payload format\" },\n\t{ key: \"openRouterRouting\", kind: \"json\", note: \"OpenRouter routing preferences object\" },\n\t{ key: \"vercelGatewayRouting\", kind: \"json\", note: \"Vercel AI Gateway routing object\" },\n\t{ key: \"supportsOpenAIGrammarTools\", kind: \"boolean\", note: \"Grammar-constrained tool calls\" },\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"sendSessionAffinityHeaders\", kind: \"boolean\", note: \"Send session affinity headers\" },\n\t{ key: \"supportsMidConvoSystemMessages\", kind: \"boolean\", note: \"Accepts mid-conversation system messages\" },\n\t{ key: \"supportsMidConvoToolAdditions\", kind: \"boolean\", note: \"System messages can add tools mid-conversation\" },\n\t{ key: \"sessionAffinityFormat\", kind: \"enum\", options: SESSION_AFFINITY, note: \"Affinity header format\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"vllmPriority\", kind: \"number\", note: \"vLLM scheduling priority\" },\n\t{ key: \"zaiToolStream\", kind: \"boolean\", note: \"Z.AI streaming tool calls\" },\n\t{ key: \"supportsThinkingTokenBudget\", kind: \"boolean\", note: \"Enable the thinking-token budget alias\" },\n\t{\n\t\tkey: \"thinkingTokenBudgetField\",\n\t\tkind: \"enum\",\n\t\toptions: [\"thinking_token_budget\", \"thinking_budget\", \"thinking_budget_tokens\"],\n\t\tnote: \"Thinking budget field\",\n\t},\n];\n\nconst OPENAI_RESPONSES_FIELDS: readonly CompatField<keyof OpenAIResponsesCompat>[] = [\n\t{ key: \"supportsDeveloperRole\", kind: \"boolean\", note: \"Accepts `developer` role messages\" },\n\t{ key: \"sessionAffinityFormat\", kind: \"enum\", options: SESSION_AFFINITY, note: \"Affinity header format\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"supportsOpenAIGrammarTools\", kind: \"boolean\", note: \"Grammar-constrained tool calls\" },\n\t{ key: \"supportsAdditionalTools\", kind: \"boolean\", note: \"Accepts additional hosted tools\" },\n\t{ key: \"supportsToolSearch\", kind: \"boolean\", note: \"Tool search support\" },\n\t{ key: \"supportsMaxOutputTokens\", kind: \"boolean\", note: \"Accepts `max_output_tokens`\" },\n\t{ key: \"supportsExplicitPromptCacheMode\", kind: \"boolean\", note: \"Explicit prompt caching\" },\n];\n\nconst ANTHROPIC_MESSAGES_FIELDS: readonly CompatField<keyof AnthropicMessagesCompat>[] = [\n\t{ key: \"supportsEagerToolInputStreaming\", kind: \"boolean\", note: \"Streams tool input eagerly\" },\n\t{ key: \"supportsLongCacheRetention\", kind: \"boolean\", note: \"Long-lived prompt cache retention\" },\n\t{ key: \"sendSessionAffinityHeaders\", kind: \"boolean\", note: \"Send session affinity headers\" },\n\t{ key: \"supportsCacheControlOnTools\", kind: \"boolean\", note: \"Cache control on tool definitions\" },\n\t{ key: \"supportsTemperature\", kind: \"boolean\", note: \"Accepts `temperature`\" },\n\t{ key: \"forceAdaptiveThinking\", kind: \"boolean\", note: \"Force adaptive thinking mode\" },\n\t{ key: \"allowEmptySignature\", kind: \"boolean\", note: \"Tolerate empty thinking signatures\" },\n\t{ key: \"supportsStrictTools\", kind: \"boolean\", note: \"Strict tool schemas\" },\n\t{ key: \"supportsMidConvoEffort\", kind: \"boolean\", note: \"Effort changes mid-conversation\" },\n\t{ key: \"supportsMidConvoSystemMessages\", kind: \"boolean\", note: \"Accepts mid-conversation system messages\" },\n\t{ key: \"supportsMidConvoToolChanges\", kind: \"boolean\", note: \"Accepts mid-conversation tool changes\" },\n\t{ key: \"allowedFallbackModels\", kind: \"json\", note: \"Server-side refusal fallback models\" },\n];\n\nconst BEDROCK_FIELDS: readonly CompatField<keyof BedrockCompat>[] = [\n\t{ key: \"supportsStrictMode\", kind: \"boolean\", note: \"Strict tool schemas\" },\n];\n\n/** Compat fields known for the given effective api; empty when the API consumes no compat object. */\nexport function compatFieldsForApi(api: string): readonly CompatField[] {\n\tswitch (api) {\n\t\tcase \"openai-completions\":\n\t\t\treturn OPENAI_COMPLETIONS_FIELDS;\n\t\tcase \"openai-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS;\n\t\tcase \"azure-openai-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS.filter((field) =>\n\t\t\t\t[\"supportsDeveloperRole\", \"supportsStrictMode\", \"supportsOpenAIGrammarTools\"].includes(field.key),\n\t\t\t);\n\t\tcase \"openai-codex-responses\":\n\t\t\treturn OPENAI_RESPONSES_FIELDS.filter((field) =>\n\t\t\t\t[\n\t\t\t\t\t\"supportsStrictMode\",\n\t\t\t\t\t\"supportsOpenAIGrammarTools\",\n\t\t\t\t\t\"supportsAdditionalTools\",\n\t\t\t\t\t\"supportsToolSearch\",\n\t\t\t\t].includes(field.key),\n\t\t\t);\n\t\tcase \"anthropic-messages\":\n\t\t\treturn ANTHROPIC_MESSAGES_FIELDS;\n\t\tcase \"bedrock-converse-stream\":\n\t\t\treturn BEDROCK_FIELDS;\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nexport function compatFieldFor(api: string, key: string): CompatField | undefined {\n\treturn compatFieldsForApi(api).find((field) => field.key === key);\n}\n\nconst completionsCompatValidator = Compile(OpenAICompletionsCompatSchema);\n\n/** Validate against models.json's openai-completions compat schema; returns the first errors, if any. */\nfunction validateCompletionsCompat(value: unknown): string | undefined {\n\tif (completionsCompatValidator.Check(value)) return undefined;\n\treturn completionsCompatValidator\n\t\t.Errors(value)\n\t\t.slice(0, 5)\n\t\t.map((error) => {\n\t\t\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\t// Name the missing property itself, as models.json load errors do.\n\t\t\tconst required =\n\t\t\t\terror.keyword === \"required\"\n\t\t\t\t\t? (error.params as { requiredProperties?: string[] }).requiredProperties?.[0]\n\t\t\t\t\t: undefined;\n\t\t\tconst field = required ? (path ? `${path}.${required}` : required) : path || \"root\";\n\t\t\treturn `${field}: ${error.message}`;\n\t\t})\n\t\t.join(\"; \");\n}\n\n/** Parse JSON values and reuse the canonical models.json schema, including nested validation. */\nexport function validateJsonCompatValue(key: string, text: string): string | undefined {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {\n\t\treturn \"Value is not valid JSON.\";\n\t}\n\treturn validateCompletionsCompat({ [key]: value });\n}\n\n/** Chat-template values share the core schema and the published pi-ai value contract. */\nexport function validateChatTemplateKwarg(value: unknown): string | undefined {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === \"object\" &&\n\t\t!Array.isArray(value) &&\n\t\t!Object.keys(value).every((key) => key === \"$var\" || key === \"omitWhenOff\")\n\t) {\n\t\treturn 'Only \"$var\" and \"omitWhenOff\" are allowed.';\n\t}\n\tconst error = validateCompletionsCompat({ chatTemplateKwargs: { value } });\n\treturn error ? `Value must be a scalar or valid $var reference: ${error}` : undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/connection.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAE7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAuB,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,yBAAyB;IACzC,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,uBAAuB,CAAC,CAAC;CACjE;AAED,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,WAAW,CAAC,CA0CtB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA2B7B"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/connection.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAE7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAuB,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,yBAAyB;IACzC,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,uBAAuB,CAAC,CAAC;CACjE;AAED,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,WAAW,CAAC,CA0CtB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA0B7B"}
@@ -70,7 +70,7 @@ export async function importProviderModels(options, models, signal) {
70
70
  signal.throwIfAborted();
71
71
  store.batch(() => {
72
72
  for (const model of fresh)
73
- store.addModel(providerId, model.name ? { id: model.id, name: model.name } : { id: model.id });
73
+ store.addModel(providerId, model);
74
74
  });
75
75
  refresher.touch(providerId);
76
76
  // These edits were confirmed. Finish the write even if the originating pane closes.
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/extensions/provider/connection.ts"],"names":[],"mappings":"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","sourcesContent":["/** Saved provider configuration, canonical authentication, and catalog import operations. */\n\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { raceWithAbortSignal } from \"../../utils/abort.ts\";\nimport { effectiveModelSettings } from \"./configuration.ts\";\nimport { formatError, PROBE_LIMITS } from \"./constants.ts\";\nimport { type ProbeModel, type ProbeResult, probeProviderModels } from \"./probe.ts\";\nimport type { RefreshCoordinator } from \"./refresh.ts\";\nimport type { ModelsJsonStore } from \"./store.ts\";\n\nexport interface ProviderConnectionOptions {\n\tstore: ModelsJsonStore;\n\trefresher: RefreshCoordinator;\n\tproviderId: string;\n\truntime: Pick<ModelRuntime, \"getAuth\" | \"getProviderAuthStatus\">;\n}\n\nexport async function fetchProviderModels(\n\toptions: ProviderConnectionOptions,\n\tsignal: AbortSignal,\n): Promise<ProbeResult> {\n\tconst { store, refresher, runtime, providerId } = options;\n\tconst deadline = AbortSignal.any([signal, AbortSignal.timeout(PROBE_LIMITS.timeoutMs)]);\n\ttry {\n\t\tawait raceWithAbortSignal(store.flush(), deadline);\n\t\tconst unsaved = store.getPendingError(providerId);\n\t\tif (unsaved) return { ok: false, error: `Save the provider changes before fetching: ${unsaved}` };\n\t\tconst provider = store.getProvider(providerId);\n\t\tconst settings = effectiveModelSettings(providerId, provider);\n\t\tif (!settings.baseUrl) return { ok: false, error: \"Set a baseUrl under API Auth first.\" };\n\t\tconst sync = await refresher.refreshNow(providerId, deadline);\n\t\tdeadline.throwIfAborted();\n\t\tif (!sync.ok) return { ok: false, error: `The provider did not reload: ${sync.errors.join(\"; \")}` };\n\t\tconst resolved = await raceWithAbortSignal(runtime.getAuth(providerId, { signal: deadline }), deadline);\n\t\tconst configured =\n\t\t\tprovider?.apiKey !== undefined ||\n\t\t\tprovider?.authHeader === true ||\n\t\t\tObject.keys(provider?.headers ?? {}).length > 0 ||\n\t\t\truntime.getProviderAuthStatus(providerId).configured;\n\t\tif (!resolved && configured) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"Configured credentials or headers did not resolve; check the provider authentication.\",\n\t\t\t};\n\t\t}\n\t\tconst result = await probeProviderModels({\n\t\t\tbaseUrl: resolved?.auth.baseUrl ?? settings.baseUrl,\n\t\t\tauth: resolved?.auth,\n\t\t\tapi: settings.api,\n\t\t\tsignal: deadline,\n\t\t});\n\t\tdeadline.throwIfAborted();\n\t\treturn result;\n\t} catch (error) {\n\t\tif (deadline.aborted) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: signal.aborted ? \"Cancelled.\" : \"Timed out while preparing or fetching the model catalog.\",\n\t\t\t};\n\t\t}\n\t\treturn { ok: false, error: formatError(error) };\n\t}\n}\n\nexport async function importProviderModels(\n\toptions: ProviderConnectionOptions,\n\tmodels: readonly ProbeModel[],\n\tsignal: AbortSignal,\n): Promise<string | undefined> {\n\tconst { store, refresher, providerId } = options;\n\tawait raceWithAbortSignal(store.flush(), signal);\n\tconst unsaved = store.getPendingError(providerId);\n\tif (unsaved) return unsaved;\n\tconst settings = effectiveModelSettings(providerId, store.getProvider(providerId));\n\tif (!settings.api || !settings.baseUrl) return \"Set baseUrl and API Type under API Auth before importing models.\";\n\tconst existing = new Set(store.getModels(providerId).map((model) => model.id));\n\tconst fresh = models.filter((model) => {\n\t\tif (existing.has(model.id)) return false;\n\t\texisting.add(model.id);\n\t\treturn true;\n\t});\n\tif (fresh.length === 0) return undefined;\n\tsignal.throwIfAborted();\n\tstore.batch(() => {\n\t\tfor (const model of fresh)\n\t\t\tstore.addModel(providerId, model.name ? { id: model.id, name: model.name } : { id: model.id });\n\t});\n\trefresher.touch(providerId);\n\t// These edits were confirmed. Finish the write even if the originating pane closes.\n\tawait store.flush();\n\tconst saveError = store.getPendingError(providerId);\n\tif (saveError) return saveError;\n\tconst outcome = await refresher.refreshNow(providerId, signal);\n\tif (!outcome.ok) return `Models were saved, but refresh failed: ${outcome.errors.join(\"; \")}`;\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/extensions/provider/connection.ts"],"names":[],"mappings":"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","sourcesContent":["/** Saved provider configuration, canonical authentication, and catalog import operations. */\n\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { raceWithAbortSignal } from \"../../utils/abort.ts\";\nimport { effectiveModelSettings } from \"./configuration.ts\";\nimport { formatError, PROBE_LIMITS } from \"./constants.ts\";\nimport { type ProbeModel, type ProbeResult, probeProviderModels } from \"./probe.ts\";\nimport type { RefreshCoordinator } from \"./refresh.ts\";\nimport type { ModelsJsonStore } from \"./store.ts\";\n\nexport interface ProviderConnectionOptions {\n\tstore: ModelsJsonStore;\n\trefresher: RefreshCoordinator;\n\tproviderId: string;\n\truntime: Pick<ModelRuntime, \"getAuth\" | \"getProviderAuthStatus\">;\n}\n\nexport async function fetchProviderModels(\n\toptions: ProviderConnectionOptions,\n\tsignal: AbortSignal,\n): Promise<ProbeResult> {\n\tconst { store, refresher, runtime, providerId } = options;\n\tconst deadline = AbortSignal.any([signal, AbortSignal.timeout(PROBE_LIMITS.timeoutMs)]);\n\ttry {\n\t\tawait raceWithAbortSignal(store.flush(), deadline);\n\t\tconst unsaved = store.getPendingError(providerId);\n\t\tif (unsaved) return { ok: false, error: `Save the provider changes before fetching: ${unsaved}` };\n\t\tconst provider = store.getProvider(providerId);\n\t\tconst settings = effectiveModelSettings(providerId, provider);\n\t\tif (!settings.baseUrl) return { ok: false, error: \"Set a baseUrl under API Auth first.\" };\n\t\tconst sync = await refresher.refreshNow(providerId, deadline);\n\t\tdeadline.throwIfAborted();\n\t\tif (!sync.ok) return { ok: false, error: `The provider did not reload: ${sync.errors.join(\"; \")}` };\n\t\tconst resolved = await raceWithAbortSignal(runtime.getAuth(providerId, { signal: deadline }), deadline);\n\t\tconst configured =\n\t\t\tprovider?.apiKey !== undefined ||\n\t\t\tprovider?.authHeader === true ||\n\t\t\tObject.keys(provider?.headers ?? {}).length > 0 ||\n\t\t\truntime.getProviderAuthStatus(providerId).configured;\n\t\tif (!resolved && configured) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"Configured credentials or headers did not resolve; check the provider authentication.\",\n\t\t\t};\n\t\t}\n\t\tconst result = await probeProviderModels({\n\t\t\tbaseUrl: resolved?.auth.baseUrl ?? settings.baseUrl,\n\t\t\tauth: resolved?.auth,\n\t\t\tapi: settings.api,\n\t\t\tsignal: deadline,\n\t\t});\n\t\tdeadline.throwIfAborted();\n\t\treturn result;\n\t} catch (error) {\n\t\tif (deadline.aborted) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: signal.aborted ? \"Cancelled.\" : \"Timed out while preparing or fetching the model catalog.\",\n\t\t\t};\n\t\t}\n\t\treturn { ok: false, error: formatError(error) };\n\t}\n}\n\nexport async function importProviderModels(\n\toptions: ProviderConnectionOptions,\n\tmodels: readonly ProbeModel[],\n\tsignal: AbortSignal,\n): Promise<string | undefined> {\n\tconst { store, refresher, providerId } = options;\n\tawait raceWithAbortSignal(store.flush(), signal);\n\tconst unsaved = store.getPendingError(providerId);\n\tif (unsaved) return unsaved;\n\tconst settings = effectiveModelSettings(providerId, store.getProvider(providerId));\n\tif (!settings.api || !settings.baseUrl) return \"Set baseUrl and API Type under API Auth before importing models.\";\n\tconst existing = new Set(store.getModels(providerId).map((model) => model.id));\n\tconst fresh = models.filter((model) => {\n\t\tif (existing.has(model.id)) return false;\n\t\texisting.add(model.id);\n\t\treturn true;\n\t});\n\tif (fresh.length === 0) return undefined;\n\tsignal.throwIfAborted();\n\tstore.batch(() => {\n\t\tfor (const model of fresh) store.addModel(providerId, model);\n\t});\n\trefresher.touch(providerId);\n\t// These edits were confirmed. Finish the write even if the originating pane closes.\n\tawait store.flush();\n\tconst saveError = store.getPendingError(providerId);\n\tif (saveError) return saveError;\n\tconst outcome = await refresher.refreshNow(providerId, signal);\n\tif (!outcome.ok) return `Models were saved, but refresh failed: ${outcome.errors.join(\"; \")}`;\n\treturn undefined;\n}\n"]}
@@ -21,6 +21,8 @@ export declare const PROBE_LIMITS: {
21
21
  readonly maxErrorBytes: 4096;
22
22
  readonly maxErrorChars: 400;
23
23
  readonly maxModels: 2000;
24
+ /** Anthropic catalog pages followed through `has_more`, the first page included. */
25
+ readonly maxPages: 5;
24
26
  };
25
27
  /** Maximum reference candidates offered by Use Built-in Data. */
26
28
  export declare const MAX_CANDIDATES = 8;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/constants.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAErE,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,mBAAmB,mEAAmE,CAAC;AACpG,eAAO,MAAM,aAAa,6CAA6C,CAAC;AACxE,eAAO,MAAM,sBAAsB,sGACiE,CAAC;AAErG;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,GAAG,EAWnC,CAAC;AAEF,sHAAsH;AACtH,eAAO,MAAM,WAAW,4BAA6B,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,eAAe,EAAE,SAAS,kBAAkB,EAQxD,CAAC;AAEF,mCAAmC;AACnC,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,iEAAiE;AACjE,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElD;AAED,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/constants.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAErE,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,mBAAmB,mEAAmE,CAAC;AACpG,eAAO,MAAM,aAAa,6CAA6C,CAAC;AACxE,eAAO,MAAM,sBAAsB,sGACiE,CAAC;AAErG;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,GAAG,EAWnC,CAAC;AAEF,sHAAsH;AACtH,eAAO,MAAM,WAAW,4BAA6B,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,eAAe,EAAE,SAAS,kBAAkB,EAQxD,CAAC;AAEF,mCAAmC;AACnC,eAAO,MAAM,YAAY;;;;;;IAMxB,oFAAoF;;CAE3E,CAAC;AAEX,iEAAiE;AACjE,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElD;AAED,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD"}
@@ -38,6 +38,8 @@ export const PROBE_LIMITS = {
38
38
  maxErrorBytes: 4_096,
39
39
  maxErrorChars: 400,
40
40
  maxModels: 2_000,
41
+ /** Anthropic catalog pages followed through `has_more`, the first page included. */
42
+ maxPages: 5,
41
43
  };
42
44
  /** Maximum reference candidates offered by Use Built-in Data. */
43
45
  export const MAX_CANDIDATES = 8;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/provider/constants.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAIpD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,gEAAgE,CAAC;AACpG,MAAM,CAAC,MAAM,aAAa,GAAG,0CAA0C,CAAC;AACxE,MAAM,CAAC,MAAM,sBAAsB,GAClC,mGAAmG,CAAC;AAErG;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAmB;IACxC,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,wBAAwB;IACxB,wBAAwB;IACxB,uBAAuB;IACvB,eAAe;IACf,yBAAyB;IACzB,aAAa;CACb,CAAC;AAEF,sHAAsH;AACtH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AAGtD,MAAM,CAAC,MAAM,eAAe,GAAkC;IAC7D,KAAK;IACL,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACL,CAAC;AAEF,mCAAmC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,SAAS,EAAE,MAAM;IACjB,YAAY,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAC7B,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,GAAG;IAClB,SAAS,EAAE,KAAK;CACP,CAAC;AAEX,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,MAAM,UAAU,WAAW,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAAY;IACjD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;AACpE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,GAAW;IAClD,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACnD,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvC,OAAO,SAAS,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC","sourcesContent":["/** Shared constants for the /provider extension. */\n\nimport type { Api, ModelThinkingLevel } from \"@earendil-works/pi-ai\";\n\nexport const COMMAND_NAME = \"provider\";\nexport const COMMAND_DESCRIPTION = \"Manage models.json providers: connection, API type, and models\";\nexport const NO_UI_WARNING = \"/provider requires interactive TUI mode.\";\nexport const NO_MODELS_FILE_WARNING =\n\t\"models.json is disabled for this runtime (custom SDK configuration), so /provider is unavailable.\";\n\n/**\n * API types offered in the single-select list. The four common custom-endpoint\n * protocols come first; the rest follow in stable order. Custom api strings\n * already present in models.json are preserved and appended at render time.\n */\nexport const API_TYPES: readonly Api[] = [\n\t\"openai-responses\",\n\t\"openai-completions\",\n\t\"anthropic-messages\",\n\t\"google-generative-ai\",\n\t\"azure-openai-responses\",\n\t\"openai-codex-responses\",\n\t\"mistral-conversations\",\n\t\"google-vertex\",\n\t\"bedrock-converse-stream\",\n\t\"pi-messages\",\n];\n\n/** Input modality options. Adding a type also requires pi-ai Model.input and the models.json schema to support it. */\nexport const INPUT_TYPES = [\"text\", \"image\"] as const;\nexport type InputType = (typeof INPUT_TYPES)[number];\n\nexport const THINKING_LEVELS: readonly ModelThinkingLevel[] = [\n\t\"off\",\n\t\"minimal\",\n\t\"low\",\n\t\"medium\",\n\t\"high\",\n\t\"xhigh\",\n\t\"max\",\n];\n\n/** GET {baseUrl}/models limits. */\nexport const PROBE_LIMITS = {\n\ttimeoutMs: 10_000,\n\tmaxBodyBytes: 4 * 1024 * 1024,\n\tmaxErrorBytes: 4_096,\n\tmaxErrorChars: 400,\n\tmaxModels: 2_000,\n} as const;\n\n/** Maximum reference candidates offered by Use Built-in Data. */\nexport const MAX_CANDIDATES = 8;\n\n/** Runtime refresh deadline when leaving /provider or after a fetch import. */\nexport const REFRESH_TIMEOUT_MS = 15_000;\n\nexport function formatError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\n/** `1 entry` / `2 entries` — handles the -y → -ies case. */\nexport function plural(count: number, word: string): string {\n\tif (count === 1) return word;\n\treturn word.endsWith(\"y\") ? `${word.slice(0, -1)}ies` : `${word}s`;\n}\n\n/** Display truncate by characters (rows are width-truncated again at render time). */\nexport function truncate(value: string, max: number): string {\n\tif (value.length <= max) return value;\n\treturn `${value.slice(0, Math.max(0, max - 1))}…`;\n}\n\n/** Mask a literal API key for display. Env/command references stay verbatim; the mask is never saved. */\nexport function maskApiKey(value: string): string {\n\tif (!value) return value;\n\tif (value.startsWith(\"$\") || value.startsWith(\"!\")) return value;\n\tif (value.length <= 8) return \"••••••\";\n\treturn `••••••${value.slice(-4)}`;\n}\n\n/** True when the raw apiKey value is an env/command reference rather than a literal secret. */\nexport function isApiKeyReference(value: string): boolean {\n\treturn value.startsWith(\"$\") || value.startsWith(\"!\");\n}\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/provider/constants.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAIpD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,gEAAgE,CAAC;AACpG,MAAM,CAAC,MAAM,aAAa,GAAG,0CAA0C,CAAC;AACxE,MAAM,CAAC,MAAM,sBAAsB,GAClC,mGAAmG,CAAC;AAErG;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAmB;IACxC,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,wBAAwB;IACxB,wBAAwB;IACxB,uBAAuB;IACvB,eAAe;IACf,yBAAyB;IACzB,aAAa;CACb,CAAC;AAEF,sHAAsH;AACtH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AAGtD,MAAM,CAAC,MAAM,eAAe,GAAkC;IAC7D,KAAK;IACL,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACL,CAAC;AAEF,mCAAmC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,SAAS,EAAE,MAAM;IACjB,YAAY,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAC7B,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,GAAG;IAClB,SAAS,EAAE,KAAK;IAChB,oFAAoF;IACpF,QAAQ,EAAE,CAAC;CACF,CAAC;AAEX,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,MAAM,UAAU,WAAW,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAAY;IACjD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;AACpE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,GAAW;IAClD,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACnD,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvC,OAAO,SAAS,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC","sourcesContent":["/** Shared constants for the /provider extension. */\n\nimport type { Api, ModelThinkingLevel } from \"@earendil-works/pi-ai\";\n\nexport const COMMAND_NAME = \"provider\";\nexport const COMMAND_DESCRIPTION = \"Manage models.json providers: connection, API type, and models\";\nexport const NO_UI_WARNING = \"/provider requires interactive TUI mode.\";\nexport const NO_MODELS_FILE_WARNING =\n\t\"models.json is disabled for this runtime (custom SDK configuration), so /provider is unavailable.\";\n\n/**\n * API types offered in the single-select list. The four common custom-endpoint\n * protocols come first; the rest follow in stable order. Custom api strings\n * already present in models.json are preserved and appended at render time.\n */\nexport const API_TYPES: readonly Api[] = [\n\t\"openai-responses\",\n\t\"openai-completions\",\n\t\"anthropic-messages\",\n\t\"google-generative-ai\",\n\t\"azure-openai-responses\",\n\t\"openai-codex-responses\",\n\t\"mistral-conversations\",\n\t\"google-vertex\",\n\t\"bedrock-converse-stream\",\n\t\"pi-messages\",\n];\n\n/** Input modality options. Adding a type also requires pi-ai Model.input and the models.json schema to support it. */\nexport const INPUT_TYPES = [\"text\", \"image\"] as const;\nexport type InputType = (typeof INPUT_TYPES)[number];\n\nexport const THINKING_LEVELS: readonly ModelThinkingLevel[] = [\n\t\"off\",\n\t\"minimal\",\n\t\"low\",\n\t\"medium\",\n\t\"high\",\n\t\"xhigh\",\n\t\"max\",\n];\n\n/** GET {baseUrl}/models limits. */\nexport const PROBE_LIMITS = {\n\ttimeoutMs: 10_000,\n\tmaxBodyBytes: 4 * 1024 * 1024,\n\tmaxErrorBytes: 4_096,\n\tmaxErrorChars: 400,\n\tmaxModels: 2_000,\n\t/** Anthropic catalog pages followed through `has_more`, the first page included. */\n\tmaxPages: 5,\n} as const;\n\n/** Maximum reference candidates offered by Use Built-in Data. */\nexport const MAX_CANDIDATES = 8;\n\n/** Runtime refresh deadline when leaving /provider or after a fetch import. */\nexport const REFRESH_TIMEOUT_MS = 15_000;\n\nexport function formatError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\n/** `1 entry` / `2 entries` — handles the -y → -ies case. */\nexport function plural(count: number, word: string): string {\n\tif (count === 1) return word;\n\treturn word.endsWith(\"y\") ? `${word.slice(0, -1)}ies` : `${word}s`;\n}\n\n/** Display truncate by characters (rows are width-truncated again at render time). */\nexport function truncate(value: string, max: number): string {\n\tif (value.length <= max) return value;\n\treturn `${value.slice(0, Math.max(0, max - 1))}…`;\n}\n\n/** Mask a literal API key for display. Env/command references stay verbatim; the mask is never saved. */\nexport function maskApiKey(value: string): string {\n\tif (!value) return value;\n\tif (value.startsWith(\"$\") || value.startsWith(\"!\")) return value;\n\tif (value.length <= 8) return \"••••••\";\n\treturn `••••••${value.slice(-4)}`;\n}\n\n/** True when the raw apiKey value is an env/command reference rather than a literal secret. */\nexport function isApiKeyReference(value: string): boolean {\n\treturn value.startsWith(\"$\") || value.startsWith(\"!\");\n}\n"]}
@@ -0,0 +1,9 @@
1
+ declare module "../../core/keybindings.ts" {
2
+ interface AppKeybindings {
3
+ "app.provider.switchPaneLeft": true;
4
+ "app.provider.switchPaneRight": true;
5
+ "app.provider.removeEntry": true;
6
+ }
7
+ }
8
+ export {};
9
+ //# sourceMappingURL=keybindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,2BAA2B,CAAC;IAC1C,UAAU,cAAc;QACvB,6BAA6B,EAAE,IAAI,CAAC;QACpC,8BAA8B,EAAE,IAAI,CAAC;QACrC,0BAA0B,EAAE,IAAI,CAAC;KACjC;CACD"}
@@ -0,0 +1,12 @@
1
+ import { registerKeybindings } from "../../core/keybinding-registry.js";
2
+ import { registerListKeybindings } from "../list-keybindings.js";
3
+ registerListKeybindings();
4
+ registerKeybindings({
5
+ "app.provider.switchPaneLeft": { defaultKeys: "left", description: "/provider: focus the left pane" },
6
+ "app.provider.switchPaneRight": { defaultKeys: "right", description: "/provider: focus the right pane" },
7
+ "app.provider.removeEntry": {
8
+ defaultKeys: "ctrl+x",
9
+ description: "/provider: remove the selected compat or dictionary entry",
10
+ },
11
+ });
12
+ //# sourceMappingURL=keybindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAUjE,uBAAuB,EAAE,CAAC;AAC1B,mBAAmB,CAAC;IACnB,6BAA6B,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACrG,8BAA8B,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACxG,0BAA0B,EAAE;QAC3B,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,2DAA2D;KACxE;CACD,CAAC,CAAC","sourcesContent":["import { registerKeybindings } from \"../../core/keybinding-registry.ts\";\nimport { registerListKeybindings } from \"../list-keybindings.ts\";\n\ndeclare module \"../../core/keybindings.ts\" {\n\tinterface AppKeybindings {\n\t\t\"app.provider.switchPaneLeft\": true;\n\t\t\"app.provider.switchPaneRight\": true;\n\t\t\"app.provider.removeEntry\": true;\n\t}\n}\n\nregisterListKeybindings();\nregisterKeybindings({\n\t\"app.provider.switchPaneLeft\": { defaultKeys: \"left\", description: \"/provider: focus the left pane\" },\n\t\"app.provider.switchPaneRight\": { defaultKeys: \"right\", description: \"/provider: focus the right pane\" },\n\t\"app.provider.removeEntry\": {\n\t\tdefaultKeys: \"ctrl+x\",\n\t\tdescription: \"/provider: remove the selected compat or dictionary entry\",\n\t},\n});\n"]}
@@ -5,12 +5,16 @@
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 type { FetchFunction, ModelAuth } from "@earendil-works/pi-ai";
10
- export interface ProbeModel {
11
- id: string;
12
- name?: string;
13
- }
15
+ import type { ModelsJsonModel } from "../../core/model-config.ts";
16
+ /** A catalog entry: its id plus the metadata it declared, already valid as a models.json model. */
17
+ export type ProbeModel = Pick<ModelsJsonModel, "id" | "name" | "contextWindow" | "maxTokens" | "input" | "reasoning">;
14
18
  export type ProbeResult = {
15
19
  ok: true;
16
20
  models: ProbeModel[];
@@ -1 +1 @@
1
- {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/probe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAmB,MAAM,uBAAuB,CAAC;AAKvF,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAmEvB;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAK5D"}
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAmB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAIlE,mGAAmG;AACnG,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,MAAM,GAAG,eAAe,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;AAEtH,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAIhH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6GvB;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAK5D"}