@code-yeongyu/senpi 2026.7.14 → 2026.7.16-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 (455) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/README.md +6 -6
  3. package/dist/bun/cli.js +2 -0
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.js +1 -1
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/list-models.d.ts +2 -2
  8. package/dist/cli/list-models.d.ts.map +1 -1
  9. package/dist/cli/list-models.js +3 -3
  10. package/dist/cli/list-models.js.map +1 -1
  11. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  12. package/dist/core/agent-session-runtime.js +3 -0
  13. package/dist/core/agent-session-runtime.js.map +1 -1
  14. package/dist/core/agent-session-services.d.ts +4 -3
  15. package/dist/core/agent-session-services.d.ts.map +1 -1
  16. package/dist/core/agent-session-services.js +14 -5
  17. package/dist/core/agent-session-services.js.map +1 -1
  18. package/dist/core/agent-session.d.ts +8 -4
  19. package/dist/core/agent-session.d.ts.map +1 -1
  20. package/dist/core/agent-session.js +81 -30
  21. package/dist/core/agent-session.js.map +1 -1
  22. package/dist/core/auth-providers.js +1 -1
  23. package/dist/core/auth-providers.js.map +1 -1
  24. package/dist/core/auth-storage.d.ts +32 -87
  25. package/dist/core/auth-storage.d.ts.map +1 -1
  26. package/dist/core/auth-storage.js +158 -221
  27. package/dist/core/auth-storage.js.map +1 -1
  28. package/dist/core/cache-stats.d.ts +2 -2
  29. package/dist/core/cache-stats.d.ts.map +1 -1
  30. package/dist/core/cache-stats.js +1 -1
  31. package/dist/core/cache-stats.js.map +1 -1
  32. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  33. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  34. package/dist/core/compaction/branch-summarization.js.map +1 -1
  35. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  36. package/dist/core/dynamic-prompt/build.js +6 -1
  37. package/dist/core/dynamic-prompt/build.js.map +1 -1
  38. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  39. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  40. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +22 -13
  42. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  43. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +1 -1
  44. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/terminal/runtime-session.js +3 -2
  46. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  47. package/dist/core/extensions/loader.d.ts.map +1 -1
  48. package/dist/core/extensions/loader.js +8 -2
  49. package/dist/core/extensions/loader.js.map +1 -1
  50. package/dist/core/extensions/runner.d.ts +1 -0
  51. package/dist/core/extensions/runner.d.ts.map +1 -1
  52. package/dist/core/extensions/runner.js +3 -0
  53. package/dist/core/extensions/runner.js.map +1 -1
  54. package/dist/core/extensions/types.d.ts +15 -2
  55. package/dist/core/extensions/types.d.ts.map +1 -1
  56. package/dist/core/extensions/types.js.map +1 -1
  57. package/dist/core/model-config.d.ts +589 -0
  58. package/dist/core/model-config.d.ts.map +1 -0
  59. package/dist/core/model-config.js +288 -0
  60. package/dist/core/model-config.js.map +1 -0
  61. package/dist/core/model-registry.d.ts +17 -146
  62. package/dist/core/model-registry.d.ts.map +1 -1
  63. package/dist/core/model-registry.js +69 -943
  64. package/dist/core/model-registry.js.map +1 -1
  65. package/dist/core/model-resolver.d.ts +8 -5
  66. package/dist/core/model-resolver.d.ts.map +1 -1
  67. package/dist/core/model-resolver.js +19 -18
  68. package/dist/core/model-resolver.js.map +1 -1
  69. package/dist/core/model-runtime.d.ts +81 -0
  70. package/dist/core/model-runtime.d.ts.map +1 -0
  71. package/dist/core/model-runtime.js +442 -0
  72. package/dist/core/model-runtime.js.map +1 -0
  73. package/dist/core/models-store.d.ts +17 -0
  74. package/dist/core/models-store.d.ts.map +1 -0
  75. package/dist/core/models-store.js +46 -0
  76. package/dist/core/models-store.js.map +1 -0
  77. package/dist/core/package-manager.d.ts.map +1 -1
  78. package/dist/core/package-manager.js +7 -2
  79. package/dist/core/package-manager.js.map +1 -1
  80. package/dist/core/provider-composer.d.ts +64 -0
  81. package/dist/core/provider-composer.d.ts.map +1 -0
  82. package/dist/core/provider-composer.js +406 -0
  83. package/dist/core/provider-composer.js.map +1 -0
  84. package/dist/core/provider-display-names.d.ts.map +1 -1
  85. package/dist/core/provider-display-names.js +2 -1
  86. package/dist/core/provider-display-names.js.map +1 -1
  87. package/dist/core/radius.d.ts +2 -0
  88. package/dist/core/radius.d.ts.map +1 -0
  89. package/dist/core/radius.js +2 -0
  90. package/dist/core/radius.js.map +1 -0
  91. package/dist/core/remote-catalog-provider.d.ts +5 -0
  92. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  93. package/dist/core/remote-catalog-provider.js +83 -0
  94. package/dist/core/remote-catalog-provider.js.map +1 -0
  95. package/dist/core/runtime-credentials.d.ts +15 -0
  96. package/dist/core/runtime-credentials.d.ts.map +1 -0
  97. package/dist/core/runtime-credentials.js +35 -0
  98. package/dist/core/runtime-credentials.js.map +1 -0
  99. package/dist/core/sdk.d.ts +11 -20
  100. package/dist/core/sdk.d.ts.map +1 -1
  101. package/dist/core/sdk.js +61 -89
  102. package/dist/core/sdk.js.map +1 -1
  103. package/dist/core/skills.js +1 -1
  104. package/dist/core/skills.js.map +1 -1
  105. package/dist/core/system-prompt.d.ts.map +1 -1
  106. package/dist/core/system-prompt.js +1 -11
  107. package/dist/core/system-prompt.js.map +1 -1
  108. package/dist/index.d.ts +2 -1
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +2 -2
  111. package/dist/index.js.map +1 -1
  112. package/dist/main.d.ts.map +1 -1
  113. package/dist/main.js +10 -13
  114. package/dist/main.js.map +1 -1
  115. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  116. package/dist/modes/interactive/components/assistant-message.js +22 -10
  117. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  118. package/dist/modes/interactive/components/footer.js +1 -1
  119. package/dist/modes/interactive/components/footer.js.map +1 -1
  120. package/dist/modes/interactive/components/login-dialog.d.ts +4 -8
  121. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  122. package/dist/modes/interactive/components/login-dialog.js +14 -12
  123. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  124. package/dist/modes/interactive/components/model-selector.d.ts +13 -4
  125. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  126. package/dist/modes/interactive/components/model-selector.js +84 -41
  127. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  128. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  129. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  130. package/dist/modes/interactive/components/oauth-selector.js +14 -25
  131. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  132. package/dist/modes/interactive/interactive-mode.d.ts +5 -1
  133. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.js +155 -129
  135. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  136. package/dist/package-manager-cli.d.ts.map +1 -1
  137. package/dist/package-manager-cli.js +70 -8
  138. package/dist/package-manager-cli.js.map +1 -1
  139. package/docs/custom-provider.md +8 -11
  140. package/docs/extensions.md +78 -555
  141. package/docs/models.md +4 -0
  142. package/docs/packages.md +1 -0
  143. package/docs/providers.md +23 -11
  144. package/docs/sdk.md +79 -105
  145. package/docs/usage.md +1 -0
  146. package/examples/AGENTS.md +34 -0
  147. package/examples/extensions/README.md +1 -0
  148. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  149. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  150. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  151. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  152. package/examples/extensions/gondolin/package-lock.json +2 -2
  153. package/examples/extensions/gondolin/package.json +1 -1
  154. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  155. package/examples/extensions/sandbox/package-lock.json +2 -2
  156. package/examples/extensions/sandbox/package.json +1 -1
  157. package/examples/extensions/with-deps/package-lock.json +2 -2
  158. package/examples/extensions/with-deps/package.json +1 -1
  159. package/examples/sdk/02-custom-model.ts +5 -8
  160. package/examples/sdk/09-api-keys-and-oauth.ts +13 -31
  161. package/examples/sdk/12-full-control.ts +8 -13
  162. package/examples/sdk/README.md +14 -18
  163. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +32 -0
  164. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  165. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/local-module-loader.ts +2 -2
  166. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/rewrite-imports.ts +4 -4
  167. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +32 -32
  168. package/node_modules/@earendil-works/pi-agent-core/package.json +4 -4
  169. package/node_modules/@earendil-works/pi-ai/README.md +80 -25
  170. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  171. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +23 -42
  172. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  173. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  174. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +10 -6
  175. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  176. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.d.ts.map +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js +9 -10
  178. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +1 -0
  180. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +4 -3
  182. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +2 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +54 -5
  186. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +23 -0
  189. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +1 -0
  191. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +24 -6
  193. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.d.ts +97 -0
  195. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.d.ts.map +1 -0
  196. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js +307 -0
  197. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js.map +1 -0
  198. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.d.ts +3 -0
  199. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.d.ts.map +1 -0
  200. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.js +3 -0
  201. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.js.map +1 -0
  202. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +3 -0
  205. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts +1 -0
  207. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js +4 -3
  209. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +9 -0
  211. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -0
  212. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/anthropic.js +51 -116
  213. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -0
  214. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.d.ts.map +1 -0
  215. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.js.map +1 -0
  216. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts +6 -0
  217. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -0
  218. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/github-copilot.js +18 -77
  219. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -0
  220. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +23 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -0
  222. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +49 -0
  223. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -0
  224. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/oauth-page.d.ts.map +1 -0
  225. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/oauth-page.js.map +1 -0
  226. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts +9 -0
  227. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts.map +1 -0
  228. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/openai-codex.js +61 -155
  229. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js.map +1 -0
  230. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/pkce.d.ts.map +1 -0
  231. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/pkce.js.map +1 -0
  232. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts +16 -0
  233. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts.map +1 -0
  234. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js +316 -0
  235. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js.map +1 -0
  236. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.d.ts +6 -0
  237. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.d.ts.map +1 -0
  238. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.js +189 -0
  239. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.js.map +1 -0
  240. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +2 -4
  241. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +9 -7
  243. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +49 -10
  245. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts +3 -0
  248. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -0
  249. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +17 -0
  250. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -0
  251. package/node_modules/@earendil-works/pi-ai/dist/cli.js +58 -76
  252. package/node_modules/@earendil-works/pi-ai/dist/cli.js.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts +42 -0
  254. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts.map +1 -0
  255. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js +2 -0
  256. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js.map +1 -0
  257. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +2 -0
  258. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/compat.js +49 -22
  260. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -0
  263. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/images-models.d.ts +4 -2
  265. package/node_modules/@earendil-works/pi-ai/dist/images-models.d.ts.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/images-models.js +5 -4
  267. package/node_modules/@earendil-works/pi-ai/dist/images-models.js.map +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +3 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  271. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts +25 -0
  273. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts.map +1 -0
  274. package/node_modules/@earendil-works/pi-ai/dist/models-store.js +16 -0
  275. package/node_modules/@earendil-works/pi-ai/dist/models-store.js.map +1 -0
  276. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +69 -30
  277. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +328 -120
  279. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/models.js +217 -31
  281. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts +2 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/oauth.js +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/oauth.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts +11 -6
  287. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +3 -0
  289. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  290. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +51 -10
  292. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -1
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.js +4 -3
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js +13 -20
  301. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.d.ts +8 -0
  303. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.d.ts.map +1 -0
  304. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.js +21 -0
  305. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.js.map +1 -0
  306. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  307. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.js +2 -1
  308. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.d.ts.map +1 -1
  310. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js +11 -1
  311. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js.map +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +1 -6
  313. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +1 -2
  315. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
  317. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +56 -5
  318. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  319. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +66 -0
  320. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
  321. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +42 -0
  322. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
  323. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts +36 -0
  324. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  325. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js +19 -0
  326. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js.map +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts +36 -0
  328. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts.map +1 -1
  329. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js +19 -0
  330. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js.map +1 -1
  331. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.d.ts.map +1 -1
  332. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.js +1 -1
  333. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +57 -0
  335. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  336. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +19 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  338. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +42 -0
  339. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  340. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +175 -139
  341. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  342. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.d.ts +26 -0
  343. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.d.ts.map +1 -0
  344. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.js +59 -0
  345. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.js.map +1 -0
  346. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.d.ts +9 -0
  347. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.d.ts.map +1 -0
  348. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.js +54 -0
  349. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.js.map +1 -0
  350. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +84 -0
  351. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  352. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +74 -2
  353. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  354. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts +1 -1
  355. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts.map +1 -1
  356. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js +15 -3
  357. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js.map +1 -1
  358. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts +6 -114
  359. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts.map +1 -1
  360. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js +3 -92
  361. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js.map +1 -1
  362. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.d.ts.map +1 -1
  363. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js +9 -0
  364. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js.map +1 -1
  365. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts +1 -1
  366. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
  367. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +6 -2
  368. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
  369. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts +8 -0
  370. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts.map +1 -0
  371. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js +92 -0
  372. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js.map +1 -0
  373. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts +6 -0
  374. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts.map +1 -0
  375. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js +54 -0
  376. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js.map +1 -0
  377. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts +4 -0
  378. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts.map +1 -0
  379. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js +4 -0
  380. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js.map +1 -0
  381. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts +7 -0
  382. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts.map +1 -0
  383. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js +16 -0
  384. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js.map +1 -0
  385. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts +19 -0
  386. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts.map +1 -0
  387. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js +217 -0
  388. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js.map +1 -0
  389. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts +4 -0
  390. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts.map +1 -0
  391. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js +46 -0
  392. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js.map +1 -0
  393. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts +13 -0
  394. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts.map +1 -0
  395. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js +144 -0
  396. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js.map +1 -0
  397. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts +5 -0
  398. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts.map +1 -0
  399. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js +208 -0
  400. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js.map +1 -0
  401. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts +4 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts.map +1 -0
  403. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js +17 -0
  404. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js.map +1 -0
  405. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts +5 -0
  406. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts.map +1 -0
  407. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js +34 -0
  408. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js.map +1 -0
  409. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts +3 -1
  410. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.js.map +1 -1
  412. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +12 -5
  413. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  414. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/package.json +6 -1
  416. package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
  417. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  418. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-tui/dist/utils.js +22 -4
  420. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  422. package/package.json +6 -6
  423. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts +0 -27
  424. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts.map +0 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.js.map +0 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +0 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +0 -1
  428. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts +0 -32
  429. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +0 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +0 -1
  431. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +0 -58
  432. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +0 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +0 -122
  434. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +0 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.d.ts +0 -5
  436. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.d.ts.map +0 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.js +0 -22
  438. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.js.map +0 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/oauth-page.d.ts.map +0 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/oauth-page.js.map +0 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +0 -45
  442. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +0 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +0 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/pkce.d.ts.map +0 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/pkce.js.map +0 -1
  446. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts +0 -64
  447. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts.map +0 -1
  448. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.js +0 -2
  449. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.js.map +0 -1
  450. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/device-code.d.ts +0 -0
  451. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/device-code.js +0 -0
  452. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/oauth-page.d.ts +0 -0
  453. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/oauth-page.js +0 -0
  454. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/pkce.d.ts +0 -0
  455. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/pkce.js +0 -0
@@ -143,7 +143,7 @@ function isDeadTerminalError(error) {
143
143
  const code = error.code;
144
144
  return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
145
145
  }
146
- const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
146
+ const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
147
147
  function isAnthropicSubscriptionAuthKey(apiKey) {
148
148
  return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
149
149
  }
@@ -393,11 +393,11 @@ export class InteractiveMode {
393
393
  }));
394
394
  const modelCommand = slashCommands.find((command) => command.name === "model");
395
395
  if (modelCommand) {
396
- modelCommand.getArgumentCompletions = (prefix) => {
396
+ modelCommand.getArgumentCompletions = async (prefix) => {
397
397
  // Get available models (scoped or from registry)
398
398
  const models = this.session.scopedModels.length > 0
399
399
  ? this.session.scopedModels.map((s) => s.model)
400
- : this.session.modelRegistry.getAvailable();
400
+ : await this.session.modelRuntime.getAvailable();
401
401
  if (models.length === 0)
402
402
  return null;
403
403
  // Create items with provider/id format
@@ -644,10 +644,18 @@ export class InteractiveMode {
644
644
  }
645
645
  });
646
646
  // Start package update check asynchronously
647
- this.checkForPackageUpdates().then((updates) => {
647
+ this.checkForPackageUpdates()
648
+ .then((updates) => {
648
649
  if (updates.length > 0) {
649
650
  this.showPackageUpdateNotification(updates);
650
651
  }
652
+ })
653
+ .finally(() => {
654
+ // On Windows, npm can overwrite the shared console title while checking
655
+ // extension package versions. Restore Pi's title after the startup check.
656
+ if (process.platform === "win32" && this.isInitialized) {
657
+ this.updateTerminalTitle();
658
+ }
651
659
  });
652
660
  // Check tmux keyboard setup asynchronously
653
661
  this.checkTmuxKeyboardSetup().then((warning) => {
@@ -660,7 +668,7 @@ export class InteractiveMode {
660
668
  if (migratedProviders && migratedProviders.length > 0) {
661
669
  this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
662
670
  }
663
- const modelsJsonError = this.session.modelRegistry.getError();
671
+ const modelsJsonError = this.session.modelRuntime.getError();
664
672
  if (modelsJsonError) {
665
673
  this.showError(`models.json error: ${modelsJsonError}`);
666
674
  }
@@ -1401,7 +1409,7 @@ export class InteractiveMode {
1401
1409
  hasUI: true,
1402
1410
  cwd: this.sessionManager.getCwd(),
1403
1411
  sessionManager: this.sessionManager,
1404
- modelRegistry: this.session.modelRegistry,
1412
+ modelRegistry: extensionRunner.getModelRegistry(),
1405
1413
  model: this.session.model,
1406
1414
  serviceTier: this.session.serviceTier,
1407
1415
  isIdle: () => this.session.isIdle,
@@ -2939,7 +2947,7 @@ export class InteractiveMode {
2939
2947
  // Cache-miss notices are not persisted; re-derive them from the full entry
2940
2948
  // list and re-inject them after the assistant messages that paid for them.
2941
2949
  const cacheMisses = this.settingsManager.getShowCacheMissNotices()
2942
- ? collectCacheMisses(this.sessionManager.getEntries(), this.session.modelRegistry)
2950
+ ? collectCacheMisses(this.sessionManager.getEntries(), this.session.modelRuntime)
2943
2951
  : new Map();
2944
2952
  if (options.updateFooter) {
2945
2953
  this.footer.invalidate();
@@ -3026,7 +3034,7 @@ export class InteractiveMode {
3026
3034
  if (!this.settingsManager.getShowCacheMissNotices())
3027
3035
  return;
3028
3036
  // Entries don't contain `message` yet: message_end fires before persistence.
3029
- const miss = detectCacheMiss(this.sessionManager.getEntries(), message, this.session.modelRegistry);
3037
+ const miss = detectCacheMiss(this.sessionManager.getEntries(), message, this.session.modelRuntime);
3030
3038
  if (miss)
3031
3039
  this.addCacheMissNotice(miss);
3032
3040
  }
@@ -3873,9 +3881,9 @@ export class InteractiveMode {
3873
3881
  return findExactModelReferenceMatch(searchTerm, models);
3874
3882
  }
3875
3883
  async getModelCandidates() {
3876
- this.session.modelRegistry.refresh();
3877
3884
  try {
3878
- const availableModels = this.session.modelRegistry.getAvailable();
3885
+ await this.session.modelRuntime.refresh();
3886
+ const availableModels = [...(await this.session.modelRuntime.getAvailable())];
3879
3887
  if (this.session.scopedModels.length === 0) {
3880
3888
  return availableModels;
3881
3889
  }
@@ -3910,7 +3918,7 @@ export class InteractiveMode {
3910
3918
  async resolveFavoriteModelsForUi(patterns, candidateModels) {
3911
3919
  const candidateIds = new Set(candidateModels.map(getModelFullId));
3912
3920
  const warnings = [];
3913
- const resolvedModels = await resolveModelScope(patterns, this.session.modelRegistry, {
3921
+ const resolvedModels = await resolveModelScope(patterns, this.session.modelRuntime, {
3914
3922
  onWarning: (message) => warnings.push(message),
3915
3923
  });
3916
3924
  for (const warning of warnings) {
@@ -3962,14 +3970,13 @@ export class InteractiveMode {
3962
3970
  if (model?.provider !== "anthropic") {
3963
3971
  return;
3964
3972
  }
3965
- const storedCredential = this.session.modelRegistry.authStorage.get("anthropic");
3966
- if (storedCredential?.type === "oauth") {
3967
- this.anthropicSubscriptionWarningShown = true;
3968
- this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
3969
- return;
3970
- }
3971
3973
  try {
3972
- const apiKey = await this.session.modelRegistry.getApiKeyForProvider(model.provider);
3974
+ if ((await this.session.modelRuntime.checkAuth("anthropic"))?.type === "oauth") {
3975
+ this.anthropicSubscriptionWarningShown = true;
3976
+ this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
3977
+ return;
3978
+ }
3979
+ const apiKey = (await this.session.modelRuntime.getAuth(model.provider))?.auth.apiKey;
3973
3980
  if (!isAnthropicSubscriptionAuthKey(apiKey)) {
3974
3981
  return;
3975
3982
  }
@@ -4028,7 +4035,7 @@ export class InteractiveMode {
4028
4035
  showModelSelector(initialSearchInput) {
4029
4036
  this.showSelector((done) => {
4030
4037
  const favoriteModelIds = this.session.favoriteModels.map((favorite) => getModelFullId(favorite.model));
4031
- const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, (model) => {
4038
+ const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRuntime, this.session.scopedModels, (model) => {
4032
4039
  void this.selectModelFromUi(model, done);
4033
4040
  }, () => {
4034
4041
  done();
@@ -4299,44 +4306,46 @@ export class InteractiveMode {
4299
4306
  }
4300
4307
  }
4301
4308
  getLoginProviderOptions(authType) {
4302
- const authStorage = this.session.modelRegistry.authStorage;
4303
- const oauthProviders = authStorage.getOAuthProviders();
4304
- const oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));
4305
- const options = oauthProviders.map((provider) => ({
4306
- id: provider.id,
4307
- name: provider.name,
4308
- authType: "oauth",
4309
- }));
4310
- const modelProviders = new Set(this.session.modelRegistry.getAll().map((model) => model.provider));
4311
- for (const providerId of modelProviders) {
4312
- if (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {
4313
- continue;
4314
- }
4315
- options.push({
4316
- id: providerId,
4317
- name: this.session.modelRegistry.getProviderDisplayName(providerId),
4318
- authType: "api_key",
4319
- });
4320
- }
4321
- const filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;
4322
- return filteredOptions.sort((a, b) => a.name.localeCompare(b.name));
4323
- }
4324
- getLogoutProviderOptions() {
4325
- const authStorage = this.session.modelRegistry.authStorage;
4326
4309
  const options = [];
4327
- for (const providerId of authStorage.list()) {
4328
- const credential = authStorage.get(providerId);
4329
- if (!credential) {
4330
- continue;
4310
+ for (const provider of this.session.modelRuntime.getProviders()) {
4311
+ const authStatus = this.session.modelRuntime.getProviderAuthStatus(provider.id);
4312
+ const status = authStatus.configured
4313
+ ? {
4314
+ type: this.session.modelRuntime.isUsingOAuth(provider.id) ? "oauth" : "api_key",
4315
+ source: authStatus.label ?? authStatus.source,
4316
+ }
4317
+ : undefined;
4318
+ if ((!authType || authType === "oauth") && provider.auth.oauth) {
4319
+ options.push({
4320
+ id: provider.id,
4321
+ name: provider.name,
4322
+ authType: "oauth",
4323
+ method: provider.auth.oauth,
4324
+ status,
4325
+ });
4326
+ }
4327
+ if ((!authType || authType === "api_key") && provider.auth.apiKey) {
4328
+ options.push({
4329
+ id: provider.id,
4330
+ name: provider.name,
4331
+ authType: "api_key",
4332
+ method: provider.auth.apiKey,
4333
+ status,
4334
+ });
4331
4335
  }
4332
- options.push({
4333
- id: providerId,
4334
- name: this.session.modelRegistry.getProviderDisplayName(providerId),
4335
- authType: credential.type,
4336
- });
4337
4336
  }
4338
4337
  return options.sort((a, b) => a.name.localeCompare(b.name));
4339
4338
  }
4339
+ async getLogoutProviderOptions() {
4340
+ return (await this.session.modelRuntime.listCredentials())
4341
+ .map(({ providerId, type }) => ({
4342
+ id: providerId,
4343
+ name: this.session.modelRuntime.getProvider(providerId)?.name ?? providerId,
4344
+ authType: type,
4345
+ status: { type, source: "stored credential" },
4346
+ }))
4347
+ .sort((a, b) => a.name.localeCompare(b.name));
4348
+ }
4340
4349
  findLoginProviderOptions(providerRef) {
4341
4350
  const normalizedProviderRef = providerRef.trim().toLowerCase();
4342
4351
  if (!normalizedProviderRef) {
@@ -4346,6 +4355,7 @@ export class InteractiveMode {
4346
4355
  provider.name.toLowerCase() === normalizedProviderRef);
4347
4356
  }
4348
4357
  async handleLoginCommand(providerRef) {
4358
+ await this.session.modelRuntime.getAvailable();
4349
4359
  if (!providerRef) {
4350
4360
  this.showLoginAuthTypeSelector();
4351
4361
  return;
@@ -4368,13 +4378,18 @@ export class InteractiveMode {
4368
4378
  if (providerOption.authType === "oauth") {
4369
4379
  await this.showLoginDialog(providerOption.id, providerOption.name);
4370
4380
  }
4371
- else {
4381
+ else if (providerOption.method?.login) {
4372
4382
  await this.showApiKeyLoginDialog(providerOption.id, providerOption.name);
4373
4383
  }
4384
+ else {
4385
+ this.showAmbientAuthDialog(providerOption);
4386
+ }
4374
4387
  }
4375
4388
  showLoginAuthTypeSelector(providerOptions) {
4376
- const subscriptionLabel = "Use a subscription";
4377
- const apiKeyLabel = "Use an API key";
4389
+ const oauthProvider = providerOptions?.find((provider) => provider.authType === "oauth");
4390
+ const oauthLoginLabel = oauthProvider?.method && "loginLabel" in oauthProvider.method ? oauthProvider.method.loginLabel : undefined;
4391
+ const subscriptionLabel = oauthLoginLabel ?? "Sign in with an account";
4392
+ const apiKeyLabel = "Sign in with an API key";
4378
4393
  const availableAuthTypes = providerOptions
4379
4394
  ? new Set(providerOptions.map((provider) => provider.authType))
4380
4395
  : new Set(["oauth", "api_key"]);
@@ -4430,7 +4445,7 @@ export class InteractiveMode {
4430
4445
  return;
4431
4446
  }
4432
4447
  this.showSelector((done) => {
4433
- const selector = new OAuthSelectorComponent("login", this.session.modelRegistry.authStorage, providerOptions, async (providerId, selectedAuthType) => {
4448
+ const selector = new OAuthSelectorComponent("login", providerOptions, async (providerId, selectedAuthType) => {
4434
4449
  done();
4435
4450
  const providerOption = providerOptions.find((provider) => provider.id === providerId && provider.authType === selectedAuthType);
4436
4451
  if (!providerOption) {
@@ -4445,7 +4460,7 @@ export class InteractiveMode {
4445
4460
  else {
4446
4461
  this.ui.requestRender();
4447
4462
  }
4448
- }, (providerId) => this.session.modelRegistry.getProviderAuthStatus(providerId), initialSearchInput);
4463
+ }, initialSearchInput);
4449
4464
  return { component: selector, focus: selector };
4450
4465
  });
4451
4466
  }
@@ -4454,21 +4469,20 @@ export class InteractiveMode {
4454
4469
  this.showLoginAuthTypeSelector();
4455
4470
  return;
4456
4471
  }
4457
- const providerOptions = this.getLogoutProviderOptions();
4472
+ const providerOptions = await this.getLogoutProviderOptions();
4458
4473
  if (providerOptions.length === 0) {
4459
4474
  this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
4460
4475
  return;
4461
4476
  }
4462
4477
  this.showSelector((done) => {
4463
- const selector = new OAuthSelectorComponent(mode, this.session.modelRegistry.authStorage, providerOptions, async (providerId) => {
4478
+ const selector = new OAuthSelectorComponent(mode, providerOptions, async (providerId) => {
4464
4479
  done();
4465
4480
  const providerOption = providerOptions.find((provider) => provider.id === providerId);
4466
4481
  if (!providerOption) {
4467
4482
  return;
4468
4483
  }
4469
4484
  try {
4470
- this.session.modelRegistry.authStorage.logout(providerOption.id);
4471
- this.session.modelRegistry.refresh();
4485
+ await this.session.modelRuntime.logout(providerOption.id);
4472
4486
  await this.updateAvailableProviderCount();
4473
4487
  const message = providerOption.authType === "oauth"
4474
4488
  ? `Logged out of ${providerOption.name}`
@@ -4486,13 +4500,13 @@ export class InteractiveMode {
4486
4500
  });
4487
4501
  }
4488
4502
  async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
4489
- this.session.modelRegistry.refresh();
4503
+ await this.session.modelRuntime.getAvailable();
4490
4504
  const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
4491
4505
  let selectedModel;
4492
4506
  let systemPromptName;
4493
4507
  let selectionError;
4494
4508
  if (isUnknownModel(previousModel)) {
4495
- const availableModels = this.session.modelRegistry.getAvailable();
4509
+ const availableModels = await this.session.modelRuntime.getAvailable();
4496
4510
  const providerModels = availableModels.filter((model) => model.provider === providerId);
4497
4511
  if (!hasDefaultModelProvider(providerId)) {
4498
4512
  selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
@@ -4537,6 +4551,20 @@ export class InteractiveMode {
4537
4551
  }
4538
4552
  }
4539
4553
  }
4554
+ showAmbientAuthDialog(providerOption) {
4555
+ const restoreEditor = () => {
4556
+ this.editorContainer.clear();
4557
+ this.editorContainer.addChild(this.editor);
4558
+ this.ui.setFocus(this.editor);
4559
+ this.ui.requestRender();
4560
+ };
4561
+ const dialog = new LoginDialogComponent(this.ui, providerOption.id, () => restoreEditor(), providerOption.name, `${providerOption.name} setup`);
4562
+ dialog.showInfo(`${providerOption.method?.name ?? "Authentication"} is configured outside pi.`, [], true);
4563
+ this.editorContainer.clear();
4564
+ this.editorContainer.addChild(dialog);
4565
+ this.ui.setFocus(dialog);
4566
+ this.ui.requestRender();
4567
+ }
4540
4568
  async showApiKeyLoginDialog(providerId, providerName) {
4541
4569
  const previousModel = this.session.model;
4542
4570
  const dialog = new LoginDialogComponent(this.ui, providerId, (_success, _message) => {
@@ -4560,11 +4588,7 @@ export class InteractiveMode {
4560
4588
  this.ui.requestRender();
4561
4589
  };
4562
4590
  try {
4563
- const apiKey = (await dialog.showPrompt("Enter API key:")).trim();
4564
- if (!apiKey) {
4565
- throw new Error("API key cannot be empty.");
4566
- }
4567
- this.session.modelRegistry.authStorage.set(providerId, { type: "api_key", key: apiKey });
4591
+ await this.loginProvider(dialog, providerId, "api_key");
4568
4592
  restoreEditor();
4569
4593
  await this.completeProviderAuthentication(providerId, providerName, "api_key", previousModel);
4570
4594
  }
@@ -4576,8 +4600,8 @@ export class InteractiveMode {
4576
4600
  }
4577
4601
  }
4578
4602
  }
4579
- showOAuthLoginSelect(dialog, prompt) {
4580
- return new Promise((resolve) => {
4603
+ showAuthSelect(dialog, prompt) {
4604
+ return new Promise((resolve, reject) => {
4581
4605
  const restoreDialog = () => {
4582
4606
  this.editorContainer.clear();
4583
4607
  this.editorContainer.addChild(dialog);
@@ -4587,10 +4611,14 @@ export class InteractiveMode {
4587
4611
  const labels = prompt.options.map((option) => option.label);
4588
4612
  const selector = new ExtensionSelectorComponent(prompt.message, labels, (optionLabel) => {
4589
4613
  restoreDialog();
4590
- resolve(prompt.options.find((option) => option.label === optionLabel)?.id);
4614
+ const id = prompt.options.find((option) => option.label === optionLabel)?.id;
4615
+ if (id)
4616
+ resolve(id);
4617
+ else
4618
+ reject(new Error("Login cancelled"));
4591
4619
  }, () => {
4592
4620
  restoreDialog();
4593
- resolve(undefined);
4621
+ reject(new Error("Login cancelled"));
4594
4622
  });
4595
4623
  this.editorContainer.clear();
4596
4624
  this.editorContainer.addChild(selector);
@@ -4598,30 +4626,64 @@ export class InteractiveMode {
4598
4626
  this.ui.requestRender();
4599
4627
  });
4600
4628
  }
4629
+ async showAuthPrompt(dialog, prompt) {
4630
+ let response;
4631
+ if (prompt.type === "select") {
4632
+ response = this.showAuthSelect(dialog, prompt);
4633
+ }
4634
+ else if (prompt.type === "manual_code") {
4635
+ response = dialog.showManualInput(prompt.message);
4636
+ }
4637
+ else {
4638
+ response = dialog.showPrompt(prompt.message, prompt.placeholder);
4639
+ }
4640
+ if (!prompt.signal)
4641
+ return response;
4642
+ if (prompt.signal.aborted)
4643
+ throw new Error("Login cancelled");
4644
+ const signal = prompt.signal;
4645
+ let onAbort;
4646
+ const aborted = new Promise((_resolve, reject) => {
4647
+ onAbort = () => reject(new Error("Login cancelled"));
4648
+ signal.addEventListener("abort", onAbort, { once: true });
4649
+ });
4650
+ try {
4651
+ return await Promise.race([response, aborted]);
4652
+ }
4653
+ finally {
4654
+ if (onAbort)
4655
+ signal.removeEventListener("abort", onAbort);
4656
+ }
4657
+ }
4658
+ notifyAuthDialog(dialog, event) {
4659
+ if (event.type === "auth_url") {
4660
+ dialog.showAuth(event.url, event.instructions);
4661
+ }
4662
+ else if (event.type === "device_code") {
4663
+ dialog.showDeviceCode(event);
4664
+ dialog.showWaiting("Waiting for authentication...");
4665
+ }
4666
+ else if (event.type === "info") {
4667
+ dialog.showInfo(event.message, event.links);
4668
+ }
4669
+ else {
4670
+ dialog.showProgress(event.message);
4671
+ }
4672
+ }
4673
+ async loginProvider(dialog, providerId, method) {
4674
+ await this.session.modelRuntime.login(providerId, method, {
4675
+ signal: dialog.signal,
4676
+ prompt: (prompt) => this.showAuthPrompt(dialog, prompt),
4677
+ notify: (event) => this.notifyAuthDialog(dialog, event),
4678
+ });
4679
+ }
4601
4680
  async showLoginDialog(providerId, providerName) {
4602
- const providerInfo = this.session.modelRegistry.authStorage
4603
- .getOAuthProviders()
4604
- .find((provider) => provider.id === providerId);
4605
4681
  const previousModel = this.session.model;
4606
- // Providers that use callback servers (can paste redirect URL)
4607
- const usesCallbackServer = providerInfo?.usesCallbackServer ?? false;
4608
- // Create login dialog component
4609
- const dialog = new LoginDialogComponent(this.ui, providerId, (_success, _message) => {
4610
- // Completion handled below
4611
- }, providerName);
4612
- // Show dialog in editor container
4682
+ const dialog = new LoginDialogComponent(this.ui, providerId, (_success, _message) => { }, providerName);
4613
4683
  this.editorContainer.clear();
4614
4684
  this.editorContainer.addChild(dialog);
4615
4685
  this.ui.setFocus(dialog);
4616
4686
  this.ui.requestRender();
4617
- // Promise for manual code input (racing with callback server)
4618
- let manualCodeResolve;
4619
- let manualCodeReject;
4620
- const manualCodePromise = new Promise((resolve, reject) => {
4621
- manualCodeResolve = resolve;
4622
- manualCodeReject = reject;
4623
- });
4624
- // Restore editor helper
4625
4687
  const restoreEditor = () => {
4626
4688
  this.editorContainer.clear();
4627
4689
  this.editorContainer.addChild(this.editor);
@@ -4629,43 +4691,7 @@ export class InteractiveMode {
4629
4691
  this.ui.requestRender();
4630
4692
  };
4631
4693
  try {
4632
- await this.session.modelRegistry.authStorage.login(providerId, {
4633
- onAuth: (info) => {
4634
- dialog.showAuth(info.url, info.instructions);
4635
- if (usesCallbackServer) {
4636
- // Show input for manual paste, racing with callback
4637
- dialog
4638
- .showManualInput("Paste redirect URL below, or complete login in browser:")
4639
- .then((value) => {
4640
- if (value && manualCodeResolve) {
4641
- manualCodeResolve(value);
4642
- manualCodeResolve = undefined;
4643
- }
4644
- })
4645
- .catch(() => {
4646
- if (manualCodeReject) {
4647
- manualCodeReject(new Error("Login cancelled"));
4648
- manualCodeReject = undefined;
4649
- }
4650
- });
4651
- }
4652
- // For Anthropic: onPrompt is called immediately after
4653
- },
4654
- onDeviceCode: (info) => {
4655
- dialog.showDeviceCode(info);
4656
- dialog.showWaiting("Waiting for authentication...");
4657
- },
4658
- onPrompt: async (prompt) => {
4659
- return dialog.showPrompt(prompt.message, prompt.placeholder);
4660
- },
4661
- onProgress: (message) => {
4662
- dialog.showProgress(message);
4663
- },
4664
- onSelect: (prompt) => this.showOAuthLoginSelect(dialog, prompt),
4665
- onManualCodeInput: () => manualCodePromise,
4666
- signal: dialog.signal,
4667
- });
4668
- // Success
4694
+ await this.loginProvider(dialog, providerId, "oauth");
4669
4695
  restoreEditor();
4670
4696
  await this.completeProviderAuthentication(providerId, providerName, "oauth", previousModel);
4671
4697
  }
@@ -4753,7 +4779,7 @@ export class InteractiveMode {
4753
4779
  showDiagnosticsWhenQuiet: true,
4754
4780
  });
4755
4781
  const savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();
4756
- const modelsJsonError = this.session.modelRegistry.getError();
4782
+ const modelsJsonError = this.session.modelRuntime.getError();
4757
4783
  if (modelsJsonError) {
4758
4784
  this.showError(`models.json error: ${modelsJsonError}`);
4759
4785
  }
@@ -4981,7 +5007,7 @@ export class InteractiveMode {
4981
5007
  const stats = this.session.getSessionStats();
4982
5008
  const sessionName = this.sessionManager.getSessionName();
4983
5009
  const entries = this.sessionManager.getEntries();
4984
- const cacheWaste = computeCacheWaste(entries, this.session.modelRegistry);
5010
+ const cacheWaste = computeCacheWaste(entries, this.session.modelRuntime);
4985
5011
  // Cost/token totals per provider/model actually used (e.g. OpenRouter `auto`
4986
5012
  // resolves to a concrete responseModel), sorted by cost descending.
4987
5013
  const perModelMap = new Map();