@code-yeongyu/senpi 2026.8.26 → 2026.8.28

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 (297) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +3 -3
  3. package/dist/cli/args.d.ts +3 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -1
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +10 -1
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/bash-executor.d.ts.map +1 -1
  11. package/dist/core/bash-executor.js +67 -29
  12. package/dist/core/bash-executor.js.map +1 -1
  13. package/dist/core/credential-accounts.d.ts +31 -0
  14. package/dist/core/credential-accounts.d.ts.map +1 -0
  15. package/dist/core/credential-accounts.js +125 -0
  16. package/dist/core/credential-accounts.js.map +1 -0
  17. package/dist/core/credential-pool/classify.d.ts +42 -0
  18. package/dist/core/credential-pool/classify.d.ts.map +1 -0
  19. package/dist/core/credential-pool/classify.js +75 -0
  20. package/dist/core/credential-pool/classify.js.map +1 -0
  21. package/dist/core/credential-pool/env-slots.d.ts +22 -0
  22. package/dist/core/credential-pool/env-slots.d.ts.map +1 -0
  23. package/dist/core/credential-pool/env-slots.js +37 -0
  24. package/dist/core/credential-pool/env-slots.js.map +1 -0
  25. package/dist/core/credential-pool/failover.d.ts +54 -0
  26. package/dist/core/credential-pool/failover.d.ts.map +1 -0
  27. package/dist/core/credential-pool/failover.js +106 -0
  28. package/dist/core/credential-pool/failover.js.map +1 -0
  29. package/dist/core/credential-pool/rotation-stream.d.ts +43 -0
  30. package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -0
  31. package/dist/core/credential-pool/rotation-stream.js +96 -0
  32. package/dist/core/credential-pool/rotation-stream.js.map +1 -0
  33. package/dist/core/credential-pool/state-store.d.ts +89 -0
  34. package/dist/core/credential-pool/state-store.d.ts.map +1 -0
  35. package/dist/core/credential-pool/state-store.js +166 -0
  36. package/dist/core/credential-pool/state-store.js.map +1 -0
  37. package/dist/core/extensions/builtin/account/index.d.ts +9 -0
  38. package/dist/core/extensions/builtin/account/index.d.ts.map +1 -0
  39. package/dist/core/extensions/builtin/account/index.js +69 -0
  40. package/dist/core/extensions/builtin/account/index.js.map +1 -0
  41. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/index.js +67 -0
  43. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  45. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/compaction/log.js +1 -0
  47. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  48. package/dist/core/extensions/builtin/config-reload/index.js +14 -22
  49. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  50. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
  51. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  52. package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
  53. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  54. package/dist/core/extensions/builtin/goal/continuation.d.ts +8 -1
  55. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  56. package/dist/core/extensions/builtin/goal/continuation.js +15 -0
  57. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  58. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -2
  59. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/format.d.ts +6 -1
  61. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/goal/format.js +6 -0
  63. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  64. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +5 -2
  66. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  67. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/goal/monitor-continuation.js +31 -7
  69. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  70. package/dist/core/extensions/builtin/goal/persistence.js +2 -0
  71. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  72. package/dist/core/extensions/builtin/goal/renderers.d.ts +14 -0
  73. package/dist/core/extensions/builtin/goal/renderers.d.ts.map +1 -0
  74. package/dist/core/extensions/builtin/goal/renderers.js +153 -0
  75. package/dist/core/extensions/builtin/goal/renderers.js.map +1 -0
  76. package/dist/core/extensions/builtin/goal/store.d.ts +6 -2
  77. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/store.js +8 -2
  79. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  80. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/goal/tool-registration.js +16 -6
  82. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/types.d.ts +1 -0
  84. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  86. package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/imagegen/index.js +10 -3
  88. package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
  89. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/index.js +4 -0
  91. package/dist/core/extensions/builtin/index.js.map +1 -1
  92. package/dist/core/extensions/builtin/todotools/index.js +1 -1
  93. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  94. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +1 -1
  95. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -1
  96. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +1 -1
  97. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -1
  98. package/dist/core/hidden-stdout-log.d.ts +10 -0
  99. package/dist/core/hidden-stdout-log.d.ts.map +1 -1
  100. package/dist/core/hidden-stdout-log.js +36 -5
  101. package/dist/core/hidden-stdout-log.js.map +1 -1
  102. package/dist/core/model-config-schema.d.ts +85 -12
  103. package/dist/core/model-config-schema.d.ts.map +1 -1
  104. package/dist/core/model-config-schema.js +25 -0
  105. package/dist/core/model-config-schema.js.map +1 -1
  106. package/dist/core/model-runtime.d.ts +34 -1
  107. package/dist/core/model-runtime.d.ts.map +1 -1
  108. package/dist/core/model-runtime.js +98 -5
  109. package/dist/core/model-runtime.js.map +1 -1
  110. package/dist/core/tools/output-accumulator.d.ts +2 -0
  111. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  112. package/dist/core/tools/output-accumulator.js +32 -7
  113. package/dist/core/tools/output-accumulator.js.map +1 -1
  114. package/dist/index.d.ts +1 -1
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +1 -1
  117. package/dist/index.js.map +1 -1
  118. package/dist/main.d.ts.map +1 -1
  119. package/dist/main.js +38 -3
  120. package/dist/main.js.map +1 -1
  121. package/dist/modes/app-server/server/account.d.ts.map +1 -1
  122. package/dist/modes/app-server/server/account.js +5 -5
  123. package/dist/modes/app-server/server/account.js.map +1 -1
  124. package/dist/modes/index.d.ts +1 -0
  125. package/dist/modes/index.d.ts.map +1 -1
  126. package/dist/modes/index.js +1 -0
  127. package/dist/modes/index.js.map +1 -1
  128. package/dist/modes/interactive/components/footer.d.ts +11 -3
  129. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  130. package/dist/modes/interactive/components/footer.js +31 -1
  131. package/dist/modes/interactive/components/footer.js.map +1 -1
  132. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -1
  133. package/dist/modes/interactive/components/tool-execution-fallback.js +82 -1
  134. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -1
  135. package/dist/modes/interactive/grok/chrome.d.ts +4 -4
  136. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
  137. package/dist/modes/interactive/grok/chrome.js.map +1 -1
  138. package/dist/modes/interactive/grok/footer.d.ts +3 -3
  139. package/dist/modes/interactive/grok/footer.d.ts.map +1 -1
  140. package/dist/modes/interactive/grok/footer.js.map +1 -1
  141. package/dist/modes/interactive/interactive-host-runtime.d.ts +44 -0
  142. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -0
  143. package/dist/modes/interactive/interactive-host-runtime.js +271 -0
  144. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -0
  145. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  146. package/dist/modes/interactive/interactive-mode.js +65 -21
  147. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  148. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  149. package/dist/modes/rpc/connection-handler.js +19 -6
  150. package/dist/modes/rpc/connection-handler.js.map +1 -1
  151. package/dist/modes/rpc/host-ensure.d.ts +41 -0
  152. package/dist/modes/rpc/host-ensure.d.ts.map +1 -0
  153. package/dist/modes/rpc/host-ensure.js +245 -0
  154. package/dist/modes/rpc/host-ensure.js.map +1 -0
  155. package/dist/modes/rpc/host-lifecycle.d.ts +57 -0
  156. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -0
  157. package/dist/modes/rpc/host-lifecycle.js +491 -0
  158. package/dist/modes/rpc/host-lifecycle.js.map +1 -0
  159. package/dist/modes/rpc/host-watchdog.d.ts +33 -0
  160. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -0
  161. package/dist/modes/rpc/host-watchdog.js +142 -0
  162. package/dist/modes/rpc/host-watchdog.js.map +1 -0
  163. package/dist/modes/rpc/multi-session-host.d.ts +7 -1
  164. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  165. package/dist/modes/rpc/multi-session-host.js +206 -32
  166. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  167. package/dist/modes/rpc/rpc-client.d.ts +41 -3
  168. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  169. package/dist/modes/rpc/rpc-client.js +125 -14
  170. package/dist/modes/rpc/rpc-client.js.map +1 -1
  171. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  172. package/dist/modes/rpc/rpc-mode.js +1 -1
  173. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  174. package/dist/modes/rpc/rpc-types.d.ts +6 -2
  175. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  176. package/dist/modes/rpc/rpc-types.js.map +1 -1
  177. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  178. package/dist/modes/rpc/session-command-router.js +24 -6
  179. package/dist/modes/rpc/session-command-router.js.map +1 -1
  180. package/dist/modes/rpc/session-event-writer.d.ts +13 -2
  181. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  182. package/dist/modes/rpc/session-event-writer.js +65 -25
  183. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  184. package/dist/modes/rpc/session-registry.d.ts +9 -0
  185. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  186. package/dist/modes/rpc/session-registry.js +31 -3
  187. package/dist/modes/rpc/session-registry.js.map +1 -1
  188. package/docs/providers.md +48 -0
  189. package/docs/rpc.md +59 -5
  190. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +44 -0
  191. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  192. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +13 -1
  193. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +15 -1
  194. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +711 -1
  195. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +14 -1
  196. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -10
  197. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +9 -3
  198. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -1
  199. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +20 -4
  201. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts +1 -1
  203. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts +21 -0
  206. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts.map +1 -0
  207. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js +27 -0
  208. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js.map +1 -0
  209. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts +24 -0
  210. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.d.ts.map +1 -1
  213. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js +7 -2
  214. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js.map +1 -1
  215. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  216. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js +46 -14
  219. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +11 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +30 -16
  223. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +2 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts +16 -0
  229. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts.map +1 -0
  230. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js +75 -0
  231. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js.map +1 -0
  232. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +45 -0
  233. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -0
  234. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +81 -0
  235. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -0
  236. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts +31 -0
  237. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts.map +1 -0
  238. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js +65 -0
  239. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js.map +1 -0
  240. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +12 -0
  241. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +37 -0
  243. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
  245. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +32 -6
  247. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +3 -2
  249. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +6 -0
  252. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +6 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +75 -0
  256. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +75 -0
  258. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +4 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  287. package/node_modules/@earendil-works/pi-ai/package.json +5 -5
  288. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  289. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  290. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +5 -0
  291. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  292. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +90 -1
  293. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  294. package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
  295. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  297. package/package.json +7 -7
@@ -1,6 +1,6 @@
1
1
  import { operationSignal, raceWithAbortSignal } from "../utils/abort.js";
2
2
  import { formatThrownValue } from "../utils/diagnostics.js";
3
- import { mergeRefreshed } from "./pool/slots.js";
3
+ import { mergeRefreshed, mergeRefreshedSlot, projectSlot } from "./pool/slots.js";
4
4
  export class ModelsError extends Error {
5
5
  constructor(code, message, options) {
6
6
  super(withCauseDetail(message, options?.cause), options);
@@ -39,6 +39,20 @@ async function resolveProviderAuthWithSignal(provider, credentials, authContext,
39
39
  }, signal);
40
40
  }
41
41
  const stored = await readCredential(credentials, provider.id, signal);
42
+ const slotName = overrides?.slotName;
43
+ if (slotName !== undefined) {
44
+ const projected = stored === undefined ? undefined : projectSlot(stored, slotName);
45
+ if (!projected)
46
+ return undefined;
47
+ if (projected.type === "oauth" && provider.auth.oauth) {
48
+ return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, projected, requestAuthContext, overrides?.env, signal, overrides?.minOAuthValidityMs, slotName);
49
+ }
50
+ if (projected.type === "api_key" && provider.auth.apiKey) {
51
+ const credential = overrides?.env ? { ...projected, env: { ...projected.env, ...overrides.env } } : projected;
52
+ return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);
53
+ }
54
+ return undefined;
55
+ }
42
56
  if (stored) {
43
57
  if (stored.type === "oauth" && provider.auth.oauth) {
44
58
  return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, stored, requestAuthContext, overrides?.env, signal, overrides?.minOAuthValidityMs);
@@ -73,7 +87,11 @@ const DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;
73
87
  * minutes remaining lock, re-check expiry under the lock, refresh once
74
88
  * globally, and persist the rotated credential before release.
75
89
  */
76
- async function resolveStoredOAuth(credentials, providerId, oauth, stored, authContext, requestEnv, signal, minOAuthValidityMs) {
90
+ function projectOAuthSlot(credential, name) {
91
+ const projected = projectSlot(credential, name);
92
+ return projected?.type === "oauth" ? projected : undefined;
93
+ }
94
+ async function resolveStoredOAuth(credentials, providerId, oauth, stored, authContext, requestEnv, signal, minOAuthValidityMs, slotName) {
77
95
  const minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);
78
96
  const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;
79
97
  let credential = stored;
@@ -84,15 +102,20 @@ async function resolveStoredOAuth(credentials, providerId, oauth, stored, authCo
84
102
  post = await credentials.modify(providerId, async (current) => {
85
103
  if (current?.type !== "oauth")
86
104
  return undefined; // logged out meanwhile
87
- if (!expiresSoon(current))
105
+ const view = slotName === undefined ? current : projectOAuthSlot(current, slotName);
106
+ if (!view)
107
+ return undefined; // slot removed meanwhile
108
+ if (!expiresSoon(view))
88
109
  return undefined; // another process/request refreshed
89
110
  try {
90
111
  const refreshSignal = AbortSignal.any([
91
112
  signal,
92
113
  AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS),
93
114
  ]);
94
- const refreshed = await oauth.refresh(current, refreshSignal);
95
- return mergeRefreshed(current, refreshed);
115
+ const refreshed = await oauth.refresh(view, refreshSignal);
116
+ return slotName === undefined
117
+ ? mergeRefreshed(current, refreshed)
118
+ : mergeRefreshedSlot(current, slotName, refreshed);
96
119
  }
97
120
  catch (error) {
98
121
  throw new ModelsError("oauth", `OAuth refresh failed for ${providerId}`, { cause: error });
@@ -106,7 +129,10 @@ async function resolveStoredOAuth(credentials, providerId, oauth, stored, authCo
106
129
  }
107
130
  if (post?.type !== "oauth")
108
131
  return undefined; // logged out meanwhile
109
- credential = post;
132
+ const postView = slotName === undefined ? post : projectOAuthSlot(post, slotName);
133
+ if (!postView)
134
+ return undefined; // slot removed meanwhile
135
+ credential = postView;
110
136
  // The normal five-minute window triggers a refresh but does not impose a
111
137
  // provider contract. Explicit callers (such as bearer-token export) do
112
138
  // require the requested minimum after the refresh.
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProviderEnv } from \"../types.ts\";\nimport { operationSignal, raceWithAbortSignal } from \"../utils/abort.ts\";\nimport { formatThrownValue } from \"../utils/diagnostics.ts\";\nimport { mergeRefreshed } from \"./pool/slots.ts\";\nimport type {\n\tApiKeyAuth,\n\tApiKeyCredential,\n\tAuthContext,\n\tAuthResult,\n\tCredential,\n\tCredentialStore,\n\tOAuthAuth,\n\tOAuthCredential,\n\tProviderAuth,\n} from \"./types.ts\";\n\nexport type ModelsErrorCode = \"model_source\" | \"model_validation\" | \"provider\" | \"stream\" | \"auth\" | \"oauth\";\n\nexport interface AuthResolutionOverrides {\n\tapiKey?: string;\n\tenv?: ProviderEnv;\n\t/** Require this much remaining OAuth-token validity; defaults to five minutes. */\n\tminOAuthValidityMs?: number;\n\tsignal?: AbortSignal;\n}\n\nexport class ModelsError extends Error {\n\treadonly code: ModelsErrorCode;\n\n\tconstructor(code: ModelsErrorCode, message: string, options?: { cause?: unknown }) {\n\t\tsuper(withCauseDetail(message, options?.cause), options);\n\t\tthis.name = \"ModelsError\";\n\t\tthis.code = code;\n\t}\n}\n\n/** Callers surface `error.message` only, so keep the underlying reason in it. */\nfunction withCauseDetail(message: string, cause: unknown): string {\n\tif (cause === undefined || cause === null) return message;\n\tconst detail = formatThrownValue(cause).trim();\n\tif (!detail || message.includes(detail)) return message;\n\treturn `${message}: ${detail}`;\n}\n\n/**\n * Auth resolution shared by the `Models` and `ImagesModels` collections.\n * A stored credential owns the provider: ambient/env is consulted only when\n * nothing is stored. No silent env fallback after a failed refresh or for a\n * credential type without a matching handler.\n */\nexport function resolveProviderAuth(\n\tprovider: { id: string; auth: ProviderAuth },\n\tcredentials: CredentialStore,\n\tauthContext: AuthContext,\n\toverrides?: AuthResolutionOverrides,\n): Promise<AuthResult | undefined> {\n\tconst signal = operationSignal(overrides?.signal);\n\treturn raceWithAbortSignal(\n\t\tresolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal),\n\t\tsignal,\n\t);\n}\n\nasync function resolveProviderAuthWithSignal(\n\tprovider: { id: string; auth: ProviderAuth },\n\tcredentials: CredentialStore,\n\tauthContext: AuthContext,\n\toverrides: AuthResolutionOverrides | undefined,\n\tsignal: AbortSignal,\n): Promise<AuthResult | undefined> {\n\tsignal.throwIfAborted();\n\tconst requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;\n\tconst apiKey = provider.auth.apiKey;\n\n\tif (overrides?.apiKey !== undefined && apiKey && !apiKey.ambientOnly) {\n\t\treturn resolveApiKey(\n\t\t\trequestAuthContext,\n\t\t\tapiKey,\n\t\t\tprovider.id,\n\t\t\t{\n\t\t\t\ttype: \"api_key\",\n\t\t\t\tkey: overrides.apiKey,\n\t\t\t\tenv: overrides.env,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tconst stored = await readCredential(credentials, provider.id, signal);\n\tif (stored) {\n\t\tif (stored.type === \"oauth\" && provider.auth.oauth) {\n\t\t\treturn resolveStoredOAuth(\n\t\t\t\tcredentials,\n\t\t\t\tprovider.id,\n\t\t\t\tprovider.auth.oauth,\n\t\t\t\tstored,\n\t\t\t\trequestAuthContext,\n\t\t\t\toverrides?.env,\n\t\t\t\tsignal,\n\t\t\t\toverrides?.minOAuthValidityMs,\n\t\t\t);\n\t\t}\n\t\tif (stored.type === \"api_key\" && provider.auth.apiKey) {\n\t\t\tconst credential = overrides?.env ? { ...stored, env: { ...stored.env, ...overrides.env } } : stored;\n\t\t\treturn resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tif (overrides?.apiKey !== undefined && apiKey) {\n\t\treturn resolveApiKey(\n\t\t\trequestAuthContext,\n\t\t\tapiKey,\n\t\t\tprovider.id,\n\t\t\t{\n\t\t\t\ttype: \"api_key\",\n\t\t\t\tkey: overrides.apiKey,\n\t\t\t\tenv: overrides.env,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t}\n\n\t// Ambient (env vars, AWS profiles, ADC files).\n\tconst ambientCredential =\n\t\tapiKey?.ambientOnly && overrides?.env ? { type: \"api_key\" as const, key: \"\", env: overrides.env } : undefined;\n\treturn apiKey ? resolveApiKey(requestAuthContext, apiKey, provider.id, ambientCredential, signal) : undefined;\n}\n\nfunction overlayEnvAuthContext(base: AuthContext, env: ProviderEnv): AuthContext {\n\treturn {\n\t\tenv: async (name) => (env[name] !== undefined ? env[name] : await base.env(name)),\n\t\tfileExists: (path) => base.fileExists(path),\n\t};\n}\n\nconst DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 5 * 60 * 1000;\nconst DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;\n\n/**\n * OAuth resolution with double-checked locking: tokens with less than five\n * minutes remaining lock, re-check expiry under the lock, refresh once\n * globally, and persist the rotated credential before release.\n */\nasync function resolveStoredOAuth(\n\tcredentials: CredentialStore,\n\tproviderId: string,\n\toauth: OAuthAuth,\n\tstored: OAuthCredential,\n\tauthContext: AuthContext,\n\trequestEnv: ProviderEnv | undefined,\n\tsignal: AbortSignal,\n\tminOAuthValidityMs?: number,\n): Promise<AuthResult | undefined> {\n\tconst minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);\n\tconst expiresSoon = (credential: OAuthCredential) => Date.now() + minimumValidityMs >= credential.expires;\n\tlet credential = stored;\n\n\tif (expiresSoon(credential)) {\n\t\t// Optimistic check said expired; the authoritative check runs under the lock.\n\t\tlet post: Credential | undefined;\n\t\ttry {\n\t\t\tpost = await credentials.modify(\n\t\t\t\tproviderId,\n\t\t\t\tasync (current) => {\n\t\t\t\t\tif (current?.type !== \"oauth\") return undefined; // logged out meanwhile\n\t\t\t\t\tif (!expiresSoon(current)) return undefined; // another process/request refreshed\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst refreshSignal = AbortSignal.any([\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\tAbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS),\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tconst refreshed = await oauth.refresh(current, refreshSignal);\n\t\t\t\t\t\treturn mergeRefreshed(current, refreshed);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow new ModelsError(\"oauth\", `OAuth refresh failed for ${providerId}`, { cause: error });\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ signal },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ModelsError) throw error;\n\t\t\tthrow new ModelsError(\"auth\", `Credential store modify failed for ${providerId}`, { cause: error });\n\t\t}\n\t\tif (post?.type !== \"oauth\") return undefined; // logged out meanwhile\n\t\tcredential = post;\n\t\t// The normal five-minute window triggers a refresh but does not impose a\n\t\t// provider contract. Explicit callers (such as bearer-token export) do\n\t\t// require the requested minimum after the refresh.\n\t\tif (minOAuthValidityMs !== undefined && expiresSoon(credential)) {\n\t\t\tthrow new ModelsError(\"oauth\", `OAuth refresh returned a token that expires too soon for ${providerId}`);\n\t\t}\n\t}\n\n\tconst storedEnv = credentialEnvironment(credential);\n\tconst effectiveEnv = requestEnv ? { ...storedEnv, ...requestEnv } : storedEnv;\n\tconst effectiveCredential = effectiveEnv ? { ...credential, env: effectiveEnv } : credential;\n\n\tif (oauth.check) {\n\t\ttry {\n\t\t\tif (!(await oauth.check({ ctx: authContext, credential: effectiveCredential, signal }))) return undefined;\n\t\t} catch (error) {\n\t\t\tthrow new ModelsError(\"auth\", `OAuth auth check failed for provider ${providerId}`, { cause: error });\n\t\t}\n\t}\n\n\ttry {\n\t\treturn {\n\t\t\tauth: await oauth.toAuth(effectiveCredential),\n\t\t\t...(effectiveEnv ? { env: effectiveEnv } : {}),\n\t\t\tsource: \"OAuth\",\n\t\t};\n\t} catch (error) {\n\t\tthrow new ModelsError(\"oauth\", `OAuth auth derivation failed for ${providerId}`, { cause: error });\n\t}\n}\n\nfunction credentialEnvironment(credential: OAuthCredential): ProviderEnv | undefined {\n\tconst value = credential.env;\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n\tconst environment: ProviderEnv = {};\n\tfor (const [name, entry] of Object.entries(value)) {\n\t\tif (typeof entry !== \"string\") return undefined;\n\t\tenvironment[name] = entry;\n\t}\n\treturn environment;\n}\n\nasync function resolveApiKey(\n\tauthContext: AuthContext,\n\tapiKey: ApiKeyAuth,\n\tproviderId: string,\n\tcredential: ApiKeyCredential | undefined,\n\tsignal: AbortSignal,\n): Promise<AuthResult | undefined> {\n\ttry {\n\t\treturn await apiKey.resolve({ ctx: authContext, credential, signal });\n\t} catch (error) {\n\t\tthrow new ModelsError(\"auth\", `API key auth failed for provider ${providerId}`, { cause: error });\n\t}\n}\n\nasync function readCredential(\n\tcredentials: CredentialStore,\n\tproviderId: string,\n\tsignal: AbortSignal,\n): Promise<Credential | undefined> {\n\ttry {\n\t\treturn await credentials.read(providerId, { signal });\n\t} catch (error) {\n\t\tthrow new ModelsError(\"auth\", `Credential store read failed for ${providerId}`, { cause: error });\n\t}\n}\n"]}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProviderEnv } from \"../types.ts\";\nimport { operationSignal, raceWithAbortSignal } from \"../utils/abort.ts\";\nimport { formatThrownValue } from \"../utils/diagnostics.ts\";\nimport { mergeRefreshed, mergeRefreshedSlot, projectSlot } from \"./pool/slots.ts\";\nimport type {\n\tApiKeyAuth,\n\tApiKeyCredential,\n\tAuthContext,\n\tAuthResult,\n\tCredential,\n\tCredentialStore,\n\tOAuthAuth,\n\tOAuthCredential,\n\tProviderAuth,\n} from \"./types.ts\";\n\nexport type ModelsErrorCode = \"model_source\" | \"model_validation\" | \"provider\" | \"stream\" | \"auth\" | \"oauth\";\n\nexport interface AuthResolutionOverrides {\n\tapiKey?: string;\n\tenv?: ProviderEnv;\n\t/** Require this much remaining OAuth-token validity; defaults to five minutes. */\n\tminOAuthValidityMs?: number;\n\t/**\n\t * Resolve against one named slot of a pooled credential. A missing entry or\n\t * slot resolves to undefined rather than falling back to another account or\n\t * ambient env, so a slot-scoped request can never silently switch identities.\n\t */\n\tslotName?: string;\n\tsignal?: AbortSignal;\n}\n\nexport class ModelsError extends Error {\n\treadonly code: ModelsErrorCode;\n\n\tconstructor(code: ModelsErrorCode, message: string, options?: { cause?: unknown }) {\n\t\tsuper(withCauseDetail(message, options?.cause), options);\n\t\tthis.name = \"ModelsError\";\n\t\tthis.code = code;\n\t}\n}\n\n/** Callers surface `error.message` only, so keep the underlying reason in it. */\nfunction withCauseDetail(message: string, cause: unknown): string {\n\tif (cause === undefined || cause === null) return message;\n\tconst detail = formatThrownValue(cause).trim();\n\tif (!detail || message.includes(detail)) return message;\n\treturn `${message}: ${detail}`;\n}\n\n/**\n * Auth resolution shared by the `Models` and `ImagesModels` collections.\n * A stored credential owns the provider: ambient/env is consulted only when\n * nothing is stored. No silent env fallback after a failed refresh or for a\n * credential type without a matching handler.\n */\nexport function resolveProviderAuth(\n\tprovider: { id: string; auth: ProviderAuth },\n\tcredentials: CredentialStore,\n\tauthContext: AuthContext,\n\toverrides?: AuthResolutionOverrides,\n): Promise<AuthResult | undefined> {\n\tconst signal = operationSignal(overrides?.signal);\n\treturn raceWithAbortSignal(\n\t\tresolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal),\n\t\tsignal,\n\t);\n}\n\nasync function resolveProviderAuthWithSignal(\n\tprovider: { id: string; auth: ProviderAuth },\n\tcredentials: CredentialStore,\n\tauthContext: AuthContext,\n\toverrides: AuthResolutionOverrides | undefined,\n\tsignal: AbortSignal,\n): Promise<AuthResult | undefined> {\n\tsignal.throwIfAborted();\n\tconst requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;\n\tconst apiKey = provider.auth.apiKey;\n\n\tif (overrides?.apiKey !== undefined && apiKey && !apiKey.ambientOnly) {\n\t\treturn resolveApiKey(\n\t\t\trequestAuthContext,\n\t\t\tapiKey,\n\t\t\tprovider.id,\n\t\t\t{\n\t\t\t\ttype: \"api_key\",\n\t\t\t\tkey: overrides.apiKey,\n\t\t\t\tenv: overrides.env,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tconst stored = await readCredential(credentials, provider.id, signal);\n\tconst slotName = overrides?.slotName;\n\tif (slotName !== undefined) {\n\t\tconst projected = stored === undefined ? undefined : projectSlot(stored, slotName);\n\t\tif (!projected) return undefined;\n\t\tif (projected.type === \"oauth\" && provider.auth.oauth) {\n\t\t\treturn resolveStoredOAuth(\n\t\t\t\tcredentials,\n\t\t\t\tprovider.id,\n\t\t\t\tprovider.auth.oauth,\n\t\t\t\tprojected,\n\t\t\t\trequestAuthContext,\n\t\t\t\toverrides?.env,\n\t\t\t\tsignal,\n\t\t\t\toverrides?.minOAuthValidityMs,\n\t\t\t\tslotName,\n\t\t\t);\n\t\t}\n\t\tif (projected.type === \"api_key\" && provider.auth.apiKey) {\n\t\t\tconst credential = overrides?.env ? { ...projected, env: { ...projected.env, ...overrides.env } } : projected;\n\t\t\treturn resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (stored) {\n\t\tif (stored.type === \"oauth\" && provider.auth.oauth) {\n\t\t\treturn resolveStoredOAuth(\n\t\t\t\tcredentials,\n\t\t\t\tprovider.id,\n\t\t\t\tprovider.auth.oauth,\n\t\t\t\tstored,\n\t\t\t\trequestAuthContext,\n\t\t\t\toverrides?.env,\n\t\t\t\tsignal,\n\t\t\t\toverrides?.minOAuthValidityMs,\n\t\t\t);\n\t\t}\n\t\tif (stored.type === \"api_key\" && provider.auth.apiKey) {\n\t\t\tconst credential = overrides?.env ? { ...stored, env: { ...stored.env, ...overrides.env } } : stored;\n\t\t\treturn resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tif (overrides?.apiKey !== undefined && apiKey) {\n\t\treturn resolveApiKey(\n\t\t\trequestAuthContext,\n\t\t\tapiKey,\n\t\t\tprovider.id,\n\t\t\t{\n\t\t\t\ttype: \"api_key\",\n\t\t\t\tkey: overrides.apiKey,\n\t\t\t\tenv: overrides.env,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t}\n\n\t// Ambient (env vars, AWS profiles, ADC files).\n\tconst ambientCredential =\n\t\tapiKey?.ambientOnly && overrides?.env ? { type: \"api_key\" as const, key: \"\", env: overrides.env } : undefined;\n\treturn apiKey ? resolveApiKey(requestAuthContext, apiKey, provider.id, ambientCredential, signal) : undefined;\n}\n\nfunction overlayEnvAuthContext(base: AuthContext, env: ProviderEnv): AuthContext {\n\treturn {\n\t\tenv: async (name) => (env[name] !== undefined ? env[name] : await base.env(name)),\n\t\tfileExists: (path) => base.fileExists(path),\n\t};\n}\n\nconst DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 5 * 60 * 1000;\nconst DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;\n\n/**\n * OAuth resolution with double-checked locking: tokens with less than five\n * minutes remaining lock, re-check expiry under the lock, refresh once\n * globally, and persist the rotated credential before release.\n */\nfunction projectOAuthSlot(credential: OAuthCredential, name: string): OAuthCredential | undefined {\n\tconst projected = projectSlot(credential, name);\n\treturn projected?.type === \"oauth\" ? projected : undefined;\n}\n\nasync function resolveStoredOAuth(\n\tcredentials: CredentialStore,\n\tproviderId: string,\n\toauth: OAuthAuth,\n\tstored: OAuthCredential,\n\tauthContext: AuthContext,\n\trequestEnv: ProviderEnv | undefined,\n\tsignal: AbortSignal,\n\tminOAuthValidityMs?: number,\n\tslotName?: string,\n): Promise<AuthResult | undefined> {\n\tconst minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);\n\tconst expiresSoon = (credential: OAuthCredential) => Date.now() + minimumValidityMs >= credential.expires;\n\tlet credential = stored;\n\n\tif (expiresSoon(credential)) {\n\t\t// Optimistic check said expired; the authoritative check runs under the lock.\n\t\tlet post: Credential | undefined;\n\t\ttry {\n\t\t\tpost = await credentials.modify(\n\t\t\t\tproviderId,\n\t\t\t\tasync (current) => {\n\t\t\t\t\tif (current?.type !== \"oauth\") return undefined; // logged out meanwhile\n\t\t\t\t\tconst view = slotName === undefined ? current : projectOAuthSlot(current, slotName);\n\t\t\t\t\tif (!view) return undefined; // slot removed meanwhile\n\t\t\t\t\tif (!expiresSoon(view)) return undefined; // another process/request refreshed\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst refreshSignal = AbortSignal.any([\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\tAbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS),\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tconst refreshed = await oauth.refresh(view, refreshSignal);\n\t\t\t\t\t\treturn slotName === undefined\n\t\t\t\t\t\t\t? mergeRefreshed(current, refreshed)\n\t\t\t\t\t\t\t: mergeRefreshedSlot(current, slotName, refreshed);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow new ModelsError(\"oauth\", `OAuth refresh failed for ${providerId}`, { cause: error });\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ signal },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ModelsError) throw error;\n\t\t\tthrow new ModelsError(\"auth\", `Credential store modify failed for ${providerId}`, { cause: error });\n\t\t}\n\t\tif (post?.type !== \"oauth\") return undefined; // logged out meanwhile\n\t\tconst postView = slotName === undefined ? post : projectOAuthSlot(post, slotName);\n\t\tif (!postView) return undefined; // slot removed meanwhile\n\t\tcredential = postView;\n\t\t// The normal five-minute window triggers a refresh but does not impose a\n\t\t// provider contract. Explicit callers (such as bearer-token export) do\n\t\t// require the requested minimum after the refresh.\n\t\tif (minOAuthValidityMs !== undefined && expiresSoon(credential)) {\n\t\t\tthrow new ModelsError(\"oauth\", `OAuth refresh returned a token that expires too soon for ${providerId}`);\n\t\t}\n\t}\n\n\tconst storedEnv = credentialEnvironment(credential);\n\tconst effectiveEnv = requestEnv ? { ...storedEnv, ...requestEnv } : storedEnv;\n\tconst effectiveCredential = effectiveEnv ? { ...credential, env: effectiveEnv } : credential;\n\n\tif (oauth.check) {\n\t\ttry {\n\t\t\tif (!(await oauth.check({ ctx: authContext, credential: effectiveCredential, signal }))) return undefined;\n\t\t} catch (error) {\n\t\t\tthrow new ModelsError(\"auth\", `OAuth auth check failed for provider ${providerId}`, { cause: error });\n\t\t}\n\t}\n\n\ttry {\n\t\treturn {\n\t\t\tauth: await oauth.toAuth(effectiveCredential),\n\t\t\t...(effectiveEnv ? { env: effectiveEnv } : {}),\n\t\t\tsource: \"OAuth\",\n\t\t};\n\t} catch (error) {\n\t\tthrow new ModelsError(\"oauth\", `OAuth auth derivation failed for ${providerId}`, { cause: error });\n\t}\n}\n\nfunction credentialEnvironment(credential: OAuthCredential): ProviderEnv | undefined {\n\tconst value = credential.env;\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n\tconst environment: ProviderEnv = {};\n\tfor (const [name, entry] of Object.entries(value)) {\n\t\tif (typeof entry !== \"string\") return undefined;\n\t\tenvironment[name] = entry;\n\t}\n\treturn environment;\n}\n\nasync function resolveApiKey(\n\tauthContext: AuthContext,\n\tapiKey: ApiKeyAuth,\n\tproviderId: string,\n\tcredential: ApiKeyCredential | undefined,\n\tsignal: AbortSignal,\n): Promise<AuthResult | undefined> {\n\ttry {\n\t\treturn await apiKey.resolve({ ctx: authContext, credential, signal });\n\t} catch (error) {\n\t\tthrow new ModelsError(\"auth\", `API key auth failed for provider ${providerId}`, { cause: error });\n\t}\n}\n\nasync function readCredential(\n\tcredentials: CredentialStore,\n\tproviderId: string,\n\tsignal: AbortSignal,\n): Promise<Credential | undefined> {\n\ttry {\n\t\treturn await credentials.read(providerId, { signal });\n\t} catch (error) {\n\t\tthrow new ModelsError(\"auth\", `Credential store read failed for ${providerId}`, { cause: error });\n\t}\n}\n"]}
@@ -40,8 +40,9 @@ export interface AuthOperationOptions {
40
40
  signal?: AbortSignal;
41
41
  }
42
42
  /**
43
- * App-owned credential storage, keyed by `Provider.id`, one credential per
44
- * provider. `modify` is the only write path, so every mutation is a
43
+ * App-owned credential storage, keyed by `Provider.id`, one entry per
44
+ * provider; an entry may pool sibling slots under `accounts` while its flat
45
+ * fields remain a valid credential. `modify` is the only write path, so every mutation is a
45
46
  * serialized read-modify-write; `Models.getAuth()` runs OAuth refresh inside
46
47
  * `modify` so concurrent requests cannot double-refresh a rotated token. The
47
48
  * app persists a credential after login via
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProviderEnv, ProviderHeaders } from \"../types.ts\";\n\n/**\n * Request auth for a single model request. If a value cannot be expressed as\n * `apiKey`, `headers`, or `baseUrl`, it is provider config, not auth.\n */\nexport interface ModelAuth {\n\tapiKey?: string;\n\theaders?: ProviderHeaders;\n\tbaseUrl?: string;\n}\n\n/**\n * Stored api-key credential. `env` holds provider-scoped environment/config\n * values such as Cloudflare account/gateway ids.\n */\nexport interface ApiKeyCredential {\n\ttype: \"api_key\";\n\tkey?: string;\n\tenv?: ProviderEnv;\n}\n\n/** OAuth token data returned by extension compatibility flows. */\nexport interface OAuthCredentials {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\t[key: string]: unknown;\n}\n\n/** Stored canonical OAuth credential. */\nexport interface OAuthCredential extends OAuthCredentials {\n\ttype: \"oauth\";\n}\n\n/** One type-tagged credential per provider — the shape of today's auth.json. */\nexport type Credential = ApiKeyCredential | OAuthCredential;\n\n/** Non-secret credential metadata for account/status enumeration. */\nexport interface CredentialInfo {\n\tproviderId: string;\n\ttype: Credential[\"type\"];\n}\n\n/** Optional cancellation for public auth and credential operations. */\nexport interface AuthOperationOptions {\n\tsignal?: AbortSignal;\n}\n\n/**\n * App-owned credential storage, keyed by `Provider.id`, one credential per\n * provider. `modify` is the only write path, so every mutation is a\n * serialized read-modify-write; `Models.getAuth()` runs OAuth refresh inside\n * `modify` so concurrent requests cannot double-refresh a rotated token. The\n * app persists a credential after login via\n * `modify(provider.id, async () => credential)`. Login/logout orchestration\n * is app-owned.\n *\n * Error semantics: `read` resolves `undefined` for missing entries. Methods\n * reject only on storage failure; `Models` wraps such rejections in\n * `ModelsError` with code \"auth\". Best-effort stores that serve an in-memory\n * view and record persistence errors internally (like coding-agent's\n * AuthStorage) are valid implementations.\n */\nexport interface CredentialStore {\n\t/**\n\t * Read the stored credential, possibly expired. Display/status use;\n\t * resolved request auth comes from `Models.getAuth()`.\n\t */\n\tread(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined>;\n\n\t/**\n\t * List stored credential metadata without resolving or exposing secrets.\n\t * Implementations must not execute configured API-key commands while listing.\n\t */\n\tlist(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;\n\n\t/**\n\t * Serialized write — the only write path. `fn` sees the current credential\n\t * because correct writes (refresh, login-during-refresh) depend on it;\n\t * return the new credential, or undefined to leave the entry unchanged.\n\t * Mutual exclusion per provider id, cross-process too where the backing\n\t * store supports it (e.g. a file lock). Resolves with the post-write\n\t * credential. Rejections from `fn` propagate.\n\t */\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined>;\n\n\t/** Remove a credential (logout). Implementations serialize this against `modify`. */\n\tdelete(providerId: string, options?: AuthOperationOptions): Promise<void>;\n}\n\n/** Environment access for auth resolution. Injectable for tests and browsers. */\nexport interface AuthContext {\n\tenv(name: string): Promise<string | undefined>;\n\t/** Check whether a file exists. Supports a leading `~`. Always false in browsers. */\n\tfileExists(path: string): Promise<boolean>;\n}\n\n/** Result of resolving auth for a model. */\nexport interface AuthResult {\n\tauth: ModelAuth;\n\t/** Provider-scoped environment/config values resolved from credentials and ambient context. */\n\tenv?: ProviderEnv;\n\t/** Human-readable label for status UI: \"ANTHROPIC_API_KEY\", \"OAuth\", \"~/.aws/credentials\". */\n\tsource?: string;\n}\n\nexport interface AuthCheck {\n\tsource?: string;\n\ttype: \"api_key\" | \"oauth\";\n}\n\nexport type AuthType = \"api_key\" | \"oauth\";\n\n/**\n * Prompt shown to the user during login. `signal` lets the flow cancel a\n * pending prompt when an out-of-band event resolves the step, e.g. a\n * `manual_code` prompt raced against a callback server, aborted when the\n * callback wins.\n */\nexport type AuthPrompt = { signal?: AbortSignal } & (\n\t| { type: \"text\"; message: string; placeholder?: string }\n\t| { type: \"secret\"; message: string; placeholder?: string }\n\t| { type: \"select\"; message: string; options: readonly { id: string; label: string; description?: string }[] }\n\t| { type: \"manual_code\"; message: string; placeholder?: string }\n);\n\nexport interface AuthInfoLink {\n\turl: string;\n\tlabel?: string;\n}\n\nexport type AuthEvent =\n\t| { type: \"info\"; message: string; links?: readonly AuthInfoLink[] }\n\t| { type: \"auth_url\"; url: string; instructions?: string }\n\t| {\n\t\t\ttype: \"device_code\";\n\t\t\tuserCode: string;\n\t\t\tverificationUri: string;\n\t\t\tintervalSeconds?: number;\n\t\t\texpiresInSeconds?: number;\n\t }\n\t| { type: \"progress\"; message: string };\n\n/**\n * Login interaction callbacks serving both api-key and OAuth flows.\n *\n * `prompt()` returns the entered/selected string (`select` returns the option\n * id). Rejects on cancel/abort. `signal` aborts the whole login flow;\n * per-prompt cancellation uses `AuthPrompt.signal`.\n */\nexport interface AuthInteraction {\n\tsignal?: AbortSignal;\n\n\tprompt(prompt: AuthPrompt): Promise<string>;\n\tnotify(event: AuthEvent): void;\n}\n\n/** Normalized interaction passed to provider login implementations. */\nexport type ProviderAuthInteraction = AuthInteraction & { signal: AbortSignal };\n\n/**\n * Api-key auth: stored key/provider env plus ambient sources (env vars, AWS\n * profiles, ADC files). Ambient-only providers omit `login`.\n */\nexport interface ApiKeyAuth {\n\t/** Display name, e.g. \"Anthropic API key\". */\n\tname: string;\n\n\t/** Ambient compatibility adapter that must not outrank a stored OAuth credential. */\n\tambientOnly?: boolean;\n\n\t/** Interactive setup (prompt for key/provider env). Absent = ambient-only. */\n\tlogin?(interaction: ProviderAuthInteraction): Promise<ApiKeyCredential>;\n\n\t/**\n\t * Optional side-effect-free availability check. Use this when `resolve()` may\n\t * execute commands or perform other request-time work. Missing means Models\n\t * checks availability by resolving auth.\n\t */\n\tcheck?(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: ApiKeyCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\n\t/**\n\t * Resolve auth from the stored credential and/or ambient sources, merging\n\t * per field (`credential.key ?? env(\"...\")`, `credential.env?.NAME ?? env(\"...\")`).\n\t * undefined = not configured. Resolution is provider-scoped; model-specific\n\t * endpoint preparation happens after auth has been resolved.\n\t */\n\tresolve(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: ApiKeyCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthResult | undefined>;\n}\n\n/**\n * OAuth auth. The `refresh`/`toAuth` split lets `Models` own the locked\n * refresh pattern: `refresh` produces a credential, `toAuth` derives request\n * auth from whatever credential ends up stored.\n */\nexport interface OAuthAuth {\n\t/** Display name, e.g. \"Anthropic (Claude Pro/Max)\". */\n\tname: string;\n\n\t/** Whether access through this auth method is backed by a provider subscription. */\n\tisSubscription?: boolean;\n\n\t/** Selector label for the OAuth login option, e.g. \"Sign in with SuperGrok or X Premium\". */\n\tloginLabel?: string;\n\n\tlogin(interaction: ProviderAuthInteraction): Promise<OAuthCredential>;\n\n\t/**\n\t * Exchange the refresh token. Network call; throws on failure\n\t * (invalid_grant etc.). `Models` runs this under the store lock.\n\t */\n\trefresh(credential: OAuthCredential, signal: AbortSignal): Promise<OAuthCredential>;\n\n\t/**\n\t * Optional side-effect-free availability check, mirroring `ApiKeyAuth.check`.\n\t * Supply this when a stored OAuth credential does not by itself imply the\n\t * provider is usable — for example a sentinel envelope that carries zero\n\t * accounts. When absent, any stored OAuth credential counts as configured.\n\t */\n\tcheck?(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: OAuthCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\n\t/**\n\t * Side-effect-free derivation of request auth from a valid credential.\n\t * Covers per-credential baseUrl (GitHub Copilot). Async so lazy wrappers\n\t * can load the implementation on first use.\n\t */\n\ttoAuth(credential: OAuthCredential): Promise<ModelAuth>;\n}\n\n/**\n * Provider auth. At least one of `apiKey`/`oauth` must be present: even\n * ambient-credential providers and keyless local servers provide `apiKey`\n * auth whose `resolve()` reports whether the provider is configured.\n */\nexport interface ProviderAuth {\n\tapiKey?: ApiKeyAuth;\n\toauth?: OAuthAuth;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProviderEnv, ProviderHeaders } from \"../types.ts\";\n\n/**\n * Request auth for a single model request. If a value cannot be expressed as\n * `apiKey`, `headers`, or `baseUrl`, it is provider config, not auth.\n */\nexport interface ModelAuth {\n\tapiKey?: string;\n\theaders?: ProviderHeaders;\n\tbaseUrl?: string;\n}\n\n/**\n * Stored api-key credential. `env` holds provider-scoped environment/config\n * values such as Cloudflare account/gateway ids.\n */\nexport interface ApiKeyCredential {\n\ttype: \"api_key\";\n\tkey?: string;\n\tenv?: ProviderEnv;\n}\n\n/** OAuth token data returned by extension compatibility flows. */\nexport interface OAuthCredentials {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\t[key: string]: unknown;\n}\n\n/** Stored canonical OAuth credential. */\nexport interface OAuthCredential extends OAuthCredentials {\n\ttype: \"oauth\";\n}\n\n/** One type-tagged credential per provider — the shape of today's auth.json. */\nexport type Credential = ApiKeyCredential | OAuthCredential;\n\n/** Non-secret credential metadata for account/status enumeration. */\nexport interface CredentialInfo {\n\tproviderId: string;\n\ttype: Credential[\"type\"];\n}\n\n/** Optional cancellation for public auth and credential operations. */\nexport interface AuthOperationOptions {\n\tsignal?: AbortSignal;\n}\n\n/**\n * App-owned credential storage, keyed by `Provider.id`, one entry per\n * provider; an entry may pool sibling slots under `accounts` while its flat\n * fields remain a valid credential. `modify` is the only write path, so every mutation is a\n * serialized read-modify-write; `Models.getAuth()` runs OAuth refresh inside\n * `modify` so concurrent requests cannot double-refresh a rotated token. The\n * app persists a credential after login via\n * `modify(provider.id, async () => credential)`. Login/logout orchestration\n * is app-owned.\n *\n * Error semantics: `read` resolves `undefined` for missing entries. Methods\n * reject only on storage failure; `Models` wraps such rejections in\n * `ModelsError` with code \"auth\". Best-effort stores that serve an in-memory\n * view and record persistence errors internally (like coding-agent's\n * AuthStorage) are valid implementations.\n */\nexport interface CredentialStore {\n\t/**\n\t * Read the stored credential, possibly expired. Display/status use;\n\t * resolved request auth comes from `Models.getAuth()`.\n\t */\n\tread(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined>;\n\n\t/**\n\t * List stored credential metadata without resolving or exposing secrets.\n\t * Implementations must not execute configured API-key commands while listing.\n\t */\n\tlist(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;\n\n\t/**\n\t * Serialized write — the only write path. `fn` sees the current credential\n\t * because correct writes (refresh, login-during-refresh) depend on it;\n\t * return the new credential, or undefined to leave the entry unchanged.\n\t * Mutual exclusion per provider id, cross-process too where the backing\n\t * store supports it (e.g. a file lock). Resolves with the post-write\n\t * credential. Rejections from `fn` propagate.\n\t */\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined>;\n\n\t/** Remove a credential (logout). Implementations serialize this against `modify`. */\n\tdelete(providerId: string, options?: AuthOperationOptions): Promise<void>;\n}\n\n/** Environment access for auth resolution. Injectable for tests and browsers. */\nexport interface AuthContext {\n\tenv(name: string): Promise<string | undefined>;\n\t/** Check whether a file exists. Supports a leading `~`. Always false in browsers. */\n\tfileExists(path: string): Promise<boolean>;\n}\n\n/** Result of resolving auth for a model. */\nexport interface AuthResult {\n\tauth: ModelAuth;\n\t/** Provider-scoped environment/config values resolved from credentials and ambient context. */\n\tenv?: ProviderEnv;\n\t/** Human-readable label for status UI: \"ANTHROPIC_API_KEY\", \"OAuth\", \"~/.aws/credentials\". */\n\tsource?: string;\n}\n\nexport interface AuthCheck {\n\tsource?: string;\n\ttype: \"api_key\" | \"oauth\";\n}\n\nexport type AuthType = \"api_key\" | \"oauth\";\n\n/**\n * Prompt shown to the user during login. `signal` lets the flow cancel a\n * pending prompt when an out-of-band event resolves the step, e.g. a\n * `manual_code` prompt raced against a callback server, aborted when the\n * callback wins.\n */\nexport type AuthPrompt = { signal?: AbortSignal } & (\n\t| { type: \"text\"; message: string; placeholder?: string }\n\t| { type: \"secret\"; message: string; placeholder?: string }\n\t| { type: \"select\"; message: string; options: readonly { id: string; label: string; description?: string }[] }\n\t| { type: \"manual_code\"; message: string; placeholder?: string }\n);\n\nexport interface AuthInfoLink {\n\turl: string;\n\tlabel?: string;\n}\n\nexport type AuthEvent =\n\t| { type: \"info\"; message: string; links?: readonly AuthInfoLink[] }\n\t| { type: \"auth_url\"; url: string; instructions?: string }\n\t| {\n\t\t\ttype: \"device_code\";\n\t\t\tuserCode: string;\n\t\t\tverificationUri: string;\n\t\t\tintervalSeconds?: number;\n\t\t\texpiresInSeconds?: number;\n\t }\n\t| { type: \"progress\"; message: string };\n\n/**\n * Login interaction callbacks serving both api-key and OAuth flows.\n *\n * `prompt()` returns the entered/selected string (`select` returns the option\n * id). Rejects on cancel/abort. `signal` aborts the whole login flow;\n * per-prompt cancellation uses `AuthPrompt.signal`.\n */\nexport interface AuthInteraction {\n\tsignal?: AbortSignal;\n\n\tprompt(prompt: AuthPrompt): Promise<string>;\n\tnotify(event: AuthEvent): void;\n}\n\n/** Normalized interaction passed to provider login implementations. */\nexport type ProviderAuthInteraction = AuthInteraction & { signal: AbortSignal };\n\n/**\n * Api-key auth: stored key/provider env plus ambient sources (env vars, AWS\n * profiles, ADC files). Ambient-only providers omit `login`.\n */\nexport interface ApiKeyAuth {\n\t/** Display name, e.g. \"Anthropic API key\". */\n\tname: string;\n\n\t/** Ambient compatibility adapter that must not outrank a stored OAuth credential. */\n\tambientOnly?: boolean;\n\n\t/** Interactive setup (prompt for key/provider env). Absent = ambient-only. */\n\tlogin?(interaction: ProviderAuthInteraction): Promise<ApiKeyCredential>;\n\n\t/**\n\t * Optional side-effect-free availability check. Use this when `resolve()` may\n\t * execute commands or perform other request-time work. Missing means Models\n\t * checks availability by resolving auth.\n\t */\n\tcheck?(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: ApiKeyCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\n\t/**\n\t * Resolve auth from the stored credential and/or ambient sources, merging\n\t * per field (`credential.key ?? env(\"...\")`, `credential.env?.NAME ?? env(\"...\")`).\n\t * undefined = not configured. Resolution is provider-scoped; model-specific\n\t * endpoint preparation happens after auth has been resolved.\n\t */\n\tresolve(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: ApiKeyCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthResult | undefined>;\n}\n\n/**\n * OAuth auth. The `refresh`/`toAuth` split lets `Models` own the locked\n * refresh pattern: `refresh` produces a credential, `toAuth` derives request\n * auth from whatever credential ends up stored.\n */\nexport interface OAuthAuth {\n\t/** Display name, e.g. \"Anthropic (Claude Pro/Max)\". */\n\tname: string;\n\n\t/** Whether access through this auth method is backed by a provider subscription. */\n\tisSubscription?: boolean;\n\n\t/** Selector label for the OAuth login option, e.g. \"Sign in with SuperGrok or X Premium\". */\n\tloginLabel?: string;\n\n\tlogin(interaction: ProviderAuthInteraction): Promise<OAuthCredential>;\n\n\t/**\n\t * Exchange the refresh token. Network call; throws on failure\n\t * (invalid_grant etc.). `Models` runs this under the store lock.\n\t */\n\trefresh(credential: OAuthCredential, signal: AbortSignal): Promise<OAuthCredential>;\n\n\t/**\n\t * Optional side-effect-free availability check, mirroring `ApiKeyAuth.check`.\n\t * Supply this when a stored OAuth credential does not by itself imply the\n\t * provider is usable — for example a sentinel envelope that carries zero\n\t * accounts. When absent, any stored OAuth credential counts as configured.\n\t */\n\tcheck?(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: OAuthCredential;\n\t\tsignal: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\n\t/**\n\t * Side-effect-free derivation of request auth from a valid credential.\n\t * Covers per-credential baseUrl (GitHub Copilot). Async so lazy wrappers\n\t * can load the implementation on first use.\n\t */\n\ttoAuth(credential: OAuthCredential): Promise<ModelAuth>;\n}\n\n/**\n * Provider auth. At least one of `apiKey`/`oauth` must be present: even\n * ambient-credential providers and keyless local servers provide `apiKey`\n * auth whose `resolve()` reports whether the provider is configured.\n */\nexport interface ProviderAuth {\n\tapiKey?: ApiKeyAuth;\n\toauth?: OAuthAuth;\n}\n"]}
@@ -2,6 +2,12 @@ import type { KnownProvider, ProviderEnv } from "./types.ts";
2
2
  export declare const ANTHROPIC_AUTH_TOKEN_ENV = "ANTHROPIC_AUTH_TOKEN";
3
3
  export declare const ANTHROPIC_OAUTH_TOKEN_ENV = "ANTHROPIC_OAUTH_TOKEN";
4
4
  export declare const ANTHROPIC_API_KEY_ENV = "ANTHROPIC_API_KEY";
5
+ /**
6
+ * The canonical provider-id to API-key env-var mapping. Exported so numbered
7
+ * env credential slots (`OPENAI_API_KEY_2`, ...) can generalize over the same
8
+ * source of truth instead of duplicating it.
9
+ */
10
+ export declare function getApiKeyEnvVars(provider: string): readonly string[] | undefined;
5
11
  /**
6
12
  * Find configured environment variables that can provide an API key for a provider.
7
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"env-api-keys.d.ts","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG7D,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AACjE,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AA8FzD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAC9F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AASvF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAC7F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"env-api-keys.d.ts","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG7D,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AACjE,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAqCzD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAuDhF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAC9F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AASvF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAC7F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC"}
@@ -60,7 +60,12 @@ function hasVertexAdcCredentials(env) {
60
60
  }
61
61
  return cachedVertexAdcCredentialsExists;
62
62
  }
63
- function getApiKeyEnvVars(provider) {
63
+ /**
64
+ * The canonical provider-id to API-key env-var mapping. Exported so numbered
65
+ * env credential slots (`OPENAI_API_KEY_2`, ...) can generalize over the same
66
+ * source of truth instead of duplicating it.
67
+ */
68
+ export function getApiKeyEnvVars(provider) {
64
69
  if (provider === "github-copilot") {
65
70
  return ["COPILOT_GITHUB_TOKEN"];
66
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"env-api-keys.js","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"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","sourcesContent":["// NEVER convert to top-level imports - breaks browser/Vite builds\nlet _existsSync: typeof import(\"node:fs\").existsSync | null = null;\nlet _homedir: typeof import(\"node:os\").homedir | null = null;\nlet _join: typeof import(\"node:path\").join | null = null;\n\ntype DynamicImport = (specifier: string) => Promise<unknown>;\n\nconst dynamicImport: DynamicImport = (specifier) => import(specifier);\nconst NODE_FS_SPECIFIER = \"node:\" + \"fs\";\nconst NODE_OS_SPECIFIER = \"node:\" + \"os\";\nconst NODE_PATH_SPECIFIER = \"node:\" + \"path\";\n\n// Eagerly load in Node.js/Bun environment only\nif (typeof process !== \"undefined\" && (process.versions?.node || process.versions?.bun)) {\n\tdynamicImport(NODE_FS_SPECIFIER).then((m) => {\n\t\t_existsSync = (m as typeof import(\"node:fs\")).existsSync;\n\t});\n\tdynamicImport(NODE_OS_SPECIFIER).then((m) => {\n\t\t_homedir = (m as typeof import(\"node:os\")).homedir;\n\t});\n\tdynamicImport(NODE_PATH_SPECIFIER).then((m) => {\n\t\t_join = (m as typeof import(\"node:path\")).join;\n\t});\n}\n\nimport type { KnownProvider, ProviderEnv } from \"./types.ts\";\nimport { getProviderEnvValue } from \"./utils/provider-env.ts\";\n\nexport const ANTHROPIC_AUTH_TOKEN_ENV = \"ANTHROPIC_AUTH_TOKEN\";\nexport const ANTHROPIC_OAUTH_TOKEN_ENV = \"ANTHROPIC_OAUTH_TOKEN\";\nexport const ANTHROPIC_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\nlet cachedVertexAdcCredentialsExists: boolean | null = null;\n\nfunction hasVertexAdcCredentials(env?: ProviderEnv): boolean {\n\tconst explicitCredentialsPath = env?.GOOGLE_APPLICATION_CREDENTIALS;\n\tif (explicitCredentialsPath) {\n\t\treturn _existsSync ? _existsSync(explicitCredentialsPath) : false;\n\t}\n\n\tif (cachedVertexAdcCredentialsExists === null) {\n\t\t// If node modules haven't loaded yet (async import race at startup),\n\t\t// return false WITHOUT caching so the next call retries once they're ready.\n\t\t// Only cache false permanently in a browser environment where fs is never available.\n\t\tif (!_existsSync || !_homedir || !_join) {\n\t\t\tconst isNode = typeof process !== \"undefined\" && (process.versions?.node || process.versions?.bun);\n\t\t\tif (!isNode) {\n\t\t\t\t// Definitively in a browser — safe to cache false permanently\n\t\t\t\tcachedVertexAdcCredentialsExists = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)\n\t\tconst gacPath = getProviderEnvValue(\"GOOGLE_APPLICATION_CREDENTIALS\", env);\n\t\tif (gacPath) {\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(gacPath);\n\t\t} else {\n\t\t\t// Fall back to default ADC path (lazy evaluation)\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(\n\t\t\t\t_join(_homedir(), \".config\", \"gcloud\", \"application_default_credentials.json\"),\n\t\t\t);\n\t\t}\n\t}\n\treturn cachedVertexAdcCredentialsExists;\n}\n\nfunction getApiKeyEnvVars(provider: string): readonly string[] | undefined {\n\tif (provider === \"github-copilot\") {\n\t\treturn [\"COPILOT_GITHUB_TOKEN\"];\n\t}\n\n\t// ANTHROPIC_AUTH_TOKEN participates in env discovery/status, but\n\t// getEnvApiKey() skips it because requests must pass it as Authorization: Bearer.\n\tif (provider === \"anthropic\") {\n\t\treturn [ANTHROPIC_AUTH_TOKEN_ENV, ANTHROPIC_OAUTH_TOKEN_ENV, ANTHROPIC_API_KEY_ENV];\n\t}\n\n\tconst envMap: Record<string, string> = {\n\t\t\"alibaba-token-plan\": \"ALIBABA_TOKEN_PLAN_API_KEY\",\n\t\t\"ant-ling\": \"ANT_LING_API_KEY\",\n\t\t\"qwen-token-plan\": \"QWEN_TOKEN_PLAN_API_KEY\",\n\t\t\"qwen-token-plan-cn\": \"QWEN_TOKEN_PLAN_CN_API_KEY\",\n\t\t\"qwen-token-plan-individual\": \"QWEN_TOKEN_PLAN_API_KEY\",\n\t\topenai: \"OPENAI_API_KEY\",\n\t\tollama: \"OLLAMA_API_KEY\",\n\t\t\"azure-openai-responses\": \"AZURE_OPENAI_API_KEY\",\n\t\tnvidia: \"NVIDIA_API_KEY\",\n\t\tdeepseek: \"DEEPSEEK_API_KEY\",\n\t\tgoogle: \"GEMINI_API_KEY\",\n\t\t\"google-vertex\": \"GOOGLE_CLOUD_API_KEY\",\n\t\tgroq: \"GROQ_API_KEY\",\n\t\tcerebras: \"CEREBRAS_API_KEY\",\n\t\txai: \"XAI_API_KEY\",\n\t\tradius: \"RADIUS_API_KEY\",\n\t\topenrouter: \"OPENROUTER_API_KEY\",\n\t\t\"vercel-ai-gateway\": \"AI_GATEWAY_API_KEY\",\n\t\topengateway: \"OPENGATEWAY_API_KEY\",\n\t\tzai: \"ZAI_API_KEY\",\n\t\t\"zai-coding-cn\": \"ZAI_CODING_CN_API_KEY\",\n\t\tmistral: \"MISTRAL_API_KEY\",\n\t\tminimax: \"MINIMAX_API_KEY\",\n\t\t\"minimax-cn\": \"MINIMAX_CN_API_KEY\",\n\t\tmoonshotai: \"MOONSHOT_API_KEY\",\n\t\t\"moonshotai-cn\": \"MOONSHOT_API_KEY\",\n\t\thuggingface: \"HF_TOKEN\",\n\t\tfireworks: \"FIREWORKS_API_KEY\",\n\t\ttogether: \"TOGETHER_API_KEY\",\n\t\tbaseten: \"BASETEN_API_KEY\",\n\t\topencode: \"OPENCODE_API_KEY\",\n\t\t\"opencode-go\": \"OPENCODE_API_KEY\",\n\t\t\"kimi-coding\": \"KIMI_API_KEY\",\n\t\t\"cloudflare-workers-ai\": \"CLOUDFLARE_API_KEY\",\n\t\t\"cloudflare-ai-gateway\": \"CLOUDFLARE_API_KEY\",\n\t\txiaomi: \"XIAOMI_API_KEY\",\n\t\t\"xiaomi-token-plan-cn\": \"XIAOMI_TOKEN_PLAN_CN_API_KEY\",\n\t\t\"xiaomi-token-plan-ams\": \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\",\n\t\t\"xiaomi-token-plan-sgp\": \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\",\n\t};\n\n\tconst envVar = envMap[provider];\n\treturn envVar ? [envVar] : undefined;\n}\n\n/**\n * Find configured environment variables that can provide an API key for a provider.\n *\n * This only reports actual API key variables. It intentionally excludes ambient\n * credential sources such as AWS profiles, AWS IAM credentials, and Google\n * Application Default Credentials.\n */\nexport function findEnvKeys(provider: KnownProvider, env?: ProviderEnv): string[] | undefined;\nexport function findEnvKeys(provider: string, env?: ProviderEnv): string[] | undefined;\nexport function findEnvKeys(provider: string, env?: ProviderEnv): string[] | undefined {\n\tconst envVars = getApiKeyEnvVars(provider);\n\tif (!envVars) return undefined;\n\n\tconst found = envVars.filter((envVar) => !!getProviderEnvValue(envVar, env));\n\treturn found.length > 0 ? found : undefined;\n}\n\n/**\n * Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.\n *\n * Will not return API keys for providers that require OAuth tokens.\n */\nexport function getEnvApiKey(provider: KnownProvider, env?: ProviderEnv): string | undefined;\nexport function getEnvApiKey(provider: string, env?: ProviderEnv): string | undefined;\nexport function getEnvApiKey(provider: string, env?: ProviderEnv): string | undefined {\n\tconst envKeys = findEnvKeys(provider, env);\n\tif (envKeys?.[0]) {\n\t\tconst apiKeyEnv = provider === \"anthropic\" ? envKeys.find((key) => key !== ANTHROPIC_AUTH_TOKEN_ENV) : envKeys[0];\n\t\tif (apiKeyEnv) return getProviderEnvValue(apiKeyEnv, env);\n\t}\n\n\t// Vertex AI supports either an explicit API key or Application Default Credentials.\n\t// Auth is configured via `gcloud auth application-default login`.\n\tif (provider === \"google-vertex\") {\n\t\tconst hasCredentials = hasVertexAdcCredentials(env);\n\t\tconst hasProject = !!(\n\t\t\tgetProviderEnvValue(\"GOOGLE_CLOUD_PROJECT\", env) || getProviderEnvValue(\"GCLOUD_PROJECT\", env)\n\t\t);\n\t\tconst hasLocation = !!getProviderEnvValue(\"GOOGLE_CLOUD_LOCATION\", env);\n\n\t\tif (hasCredentials && hasProject && hasLocation) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\tif (provider === \"amazon-bedrock\") {\n\t\t// Amazon Bedrock supports multiple credential sources:\n\t\t// 1. AWS_PROFILE - named profile from ~/.aws/credentials\n\t\t// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys\n\t\t// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock bearer token\n\t\t// 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles\n\t\t// 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)\n\t\t// 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)\n\t\tif (\n\t\t\tgetProviderEnvValue(\"AWS_PROFILE\", env) ||\n\t\t\t(getProviderEnvValue(\"AWS_ACCESS_KEY_ID\", env) && getProviderEnvValue(\"AWS_SECRET_ACCESS_KEY\", env)) ||\n\t\t\tgetProviderEnvValue(\"AWS_BEARER_TOKEN_BEDROCK\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_CONTAINER_CREDENTIALS_FULL_URI\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_WEB_IDENTITY_TOKEN_FILE\", env)\n\t\t) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"env-api-keys.js","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"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","sourcesContent":["// NEVER convert to top-level imports - breaks browser/Vite builds\nlet _existsSync: typeof import(\"node:fs\").existsSync | null = null;\nlet _homedir: typeof import(\"node:os\").homedir | null = null;\nlet _join: typeof import(\"node:path\").join | null = null;\n\ntype DynamicImport = (specifier: string) => Promise<unknown>;\n\nconst dynamicImport: DynamicImport = (specifier) => import(specifier);\nconst NODE_FS_SPECIFIER = \"node:\" + \"fs\";\nconst NODE_OS_SPECIFIER = \"node:\" + \"os\";\nconst NODE_PATH_SPECIFIER = \"node:\" + \"path\";\n\n// Eagerly load in Node.js/Bun environment only\nif (typeof process !== \"undefined\" && (process.versions?.node || process.versions?.bun)) {\n\tdynamicImport(NODE_FS_SPECIFIER).then((m) => {\n\t\t_existsSync = (m as typeof import(\"node:fs\")).existsSync;\n\t});\n\tdynamicImport(NODE_OS_SPECIFIER).then((m) => {\n\t\t_homedir = (m as typeof import(\"node:os\")).homedir;\n\t});\n\tdynamicImport(NODE_PATH_SPECIFIER).then((m) => {\n\t\t_join = (m as typeof import(\"node:path\")).join;\n\t});\n}\n\nimport type { KnownProvider, ProviderEnv } from \"./types.ts\";\nimport { getProviderEnvValue } from \"./utils/provider-env.ts\";\n\nexport const ANTHROPIC_AUTH_TOKEN_ENV = \"ANTHROPIC_AUTH_TOKEN\";\nexport const ANTHROPIC_OAUTH_TOKEN_ENV = \"ANTHROPIC_OAUTH_TOKEN\";\nexport const ANTHROPIC_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\nlet cachedVertexAdcCredentialsExists: boolean | null = null;\n\nfunction hasVertexAdcCredentials(env?: ProviderEnv): boolean {\n\tconst explicitCredentialsPath = env?.GOOGLE_APPLICATION_CREDENTIALS;\n\tif (explicitCredentialsPath) {\n\t\treturn _existsSync ? _existsSync(explicitCredentialsPath) : false;\n\t}\n\n\tif (cachedVertexAdcCredentialsExists === null) {\n\t\t// If node modules haven't loaded yet (async import race at startup),\n\t\t// return false WITHOUT caching so the next call retries once they're ready.\n\t\t// Only cache false permanently in a browser environment where fs is never available.\n\t\tif (!_existsSync || !_homedir || !_join) {\n\t\t\tconst isNode = typeof process !== \"undefined\" && (process.versions?.node || process.versions?.bun);\n\t\t\tif (!isNode) {\n\t\t\t\t// Definitively in a browser — safe to cache false permanently\n\t\t\t\tcachedVertexAdcCredentialsExists = false;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)\n\t\tconst gacPath = getProviderEnvValue(\"GOOGLE_APPLICATION_CREDENTIALS\", env);\n\t\tif (gacPath) {\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(gacPath);\n\t\t} else {\n\t\t\t// Fall back to default ADC path (lazy evaluation)\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(\n\t\t\t\t_join(_homedir(), \".config\", \"gcloud\", \"application_default_credentials.json\"),\n\t\t\t);\n\t\t}\n\t}\n\treturn cachedVertexAdcCredentialsExists;\n}\n\n/**\n * The canonical provider-id to API-key env-var mapping. Exported so numbered\n * env credential slots (`OPENAI_API_KEY_2`, ...) can generalize over the same\n * source of truth instead of duplicating it.\n */\nexport function getApiKeyEnvVars(provider: string): readonly string[] | undefined {\n\tif (provider === \"github-copilot\") {\n\t\treturn [\"COPILOT_GITHUB_TOKEN\"];\n\t}\n\n\t// ANTHROPIC_AUTH_TOKEN participates in env discovery/status, but\n\t// getEnvApiKey() skips it because requests must pass it as Authorization: Bearer.\n\tif (provider === \"anthropic\") {\n\t\treturn [ANTHROPIC_AUTH_TOKEN_ENV, ANTHROPIC_OAUTH_TOKEN_ENV, ANTHROPIC_API_KEY_ENV];\n\t}\n\n\tconst envMap: Record<string, string> = {\n\t\t\"alibaba-token-plan\": \"ALIBABA_TOKEN_PLAN_API_KEY\",\n\t\t\"ant-ling\": \"ANT_LING_API_KEY\",\n\t\t\"qwen-token-plan\": \"QWEN_TOKEN_PLAN_API_KEY\",\n\t\t\"qwen-token-plan-cn\": \"QWEN_TOKEN_PLAN_CN_API_KEY\",\n\t\t\"qwen-token-plan-individual\": \"QWEN_TOKEN_PLAN_API_KEY\",\n\t\topenai: \"OPENAI_API_KEY\",\n\t\tollama: \"OLLAMA_API_KEY\",\n\t\t\"azure-openai-responses\": \"AZURE_OPENAI_API_KEY\",\n\t\tnvidia: \"NVIDIA_API_KEY\",\n\t\tdeepseek: \"DEEPSEEK_API_KEY\",\n\t\tgoogle: \"GEMINI_API_KEY\",\n\t\t\"google-vertex\": \"GOOGLE_CLOUD_API_KEY\",\n\t\tgroq: \"GROQ_API_KEY\",\n\t\tcerebras: \"CEREBRAS_API_KEY\",\n\t\txai: \"XAI_API_KEY\",\n\t\tradius: \"RADIUS_API_KEY\",\n\t\topenrouter: \"OPENROUTER_API_KEY\",\n\t\t\"vercel-ai-gateway\": \"AI_GATEWAY_API_KEY\",\n\t\topengateway: \"OPENGATEWAY_API_KEY\",\n\t\tzai: \"ZAI_API_KEY\",\n\t\t\"zai-coding-cn\": \"ZAI_CODING_CN_API_KEY\",\n\t\tmistral: \"MISTRAL_API_KEY\",\n\t\tminimax: \"MINIMAX_API_KEY\",\n\t\t\"minimax-cn\": \"MINIMAX_CN_API_KEY\",\n\t\tmoonshotai: \"MOONSHOT_API_KEY\",\n\t\t\"moonshotai-cn\": \"MOONSHOT_API_KEY\",\n\t\thuggingface: \"HF_TOKEN\",\n\t\tfireworks: \"FIREWORKS_API_KEY\",\n\t\ttogether: \"TOGETHER_API_KEY\",\n\t\tbaseten: \"BASETEN_API_KEY\",\n\t\topencode: \"OPENCODE_API_KEY\",\n\t\t\"opencode-go\": \"OPENCODE_API_KEY\",\n\t\t\"kimi-coding\": \"KIMI_API_KEY\",\n\t\t\"cloudflare-workers-ai\": \"CLOUDFLARE_API_KEY\",\n\t\t\"cloudflare-ai-gateway\": \"CLOUDFLARE_API_KEY\",\n\t\txiaomi: \"XIAOMI_API_KEY\",\n\t\t\"xiaomi-token-plan-cn\": \"XIAOMI_TOKEN_PLAN_CN_API_KEY\",\n\t\t\"xiaomi-token-plan-ams\": \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\",\n\t\t\"xiaomi-token-plan-sgp\": \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\",\n\t};\n\n\tconst envVar = envMap[provider];\n\treturn envVar ? [envVar] : undefined;\n}\n\n/**\n * Find configured environment variables that can provide an API key for a provider.\n *\n * This only reports actual API key variables. It intentionally excludes ambient\n * credential sources such as AWS profiles, AWS IAM credentials, and Google\n * Application Default Credentials.\n */\nexport function findEnvKeys(provider: KnownProvider, env?: ProviderEnv): string[] | undefined;\nexport function findEnvKeys(provider: string, env?: ProviderEnv): string[] | undefined;\nexport function findEnvKeys(provider: string, env?: ProviderEnv): string[] | undefined {\n\tconst envVars = getApiKeyEnvVars(provider);\n\tif (!envVars) return undefined;\n\n\tconst found = envVars.filter((envVar) => !!getProviderEnvValue(envVar, env));\n\treturn found.length > 0 ? found : undefined;\n}\n\n/**\n * Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.\n *\n * Will not return API keys for providers that require OAuth tokens.\n */\nexport function getEnvApiKey(provider: KnownProvider, env?: ProviderEnv): string | undefined;\nexport function getEnvApiKey(provider: string, env?: ProviderEnv): string | undefined;\nexport function getEnvApiKey(provider: string, env?: ProviderEnv): string | undefined {\n\tconst envKeys = findEnvKeys(provider, env);\n\tif (envKeys?.[0]) {\n\t\tconst apiKeyEnv = provider === \"anthropic\" ? envKeys.find((key) => key !== ANTHROPIC_AUTH_TOKEN_ENV) : envKeys[0];\n\t\tif (apiKeyEnv) return getProviderEnvValue(apiKeyEnv, env);\n\t}\n\n\t// Vertex AI supports either an explicit API key or Application Default Credentials.\n\t// Auth is configured via `gcloud auth application-default login`.\n\tif (provider === \"google-vertex\") {\n\t\tconst hasCredentials = hasVertexAdcCredentials(env);\n\t\tconst hasProject = !!(\n\t\t\tgetProviderEnvValue(\"GOOGLE_CLOUD_PROJECT\", env) || getProviderEnvValue(\"GCLOUD_PROJECT\", env)\n\t\t);\n\t\tconst hasLocation = !!getProviderEnvValue(\"GOOGLE_CLOUD_LOCATION\", env);\n\n\t\tif (hasCredentials && hasProject && hasLocation) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\tif (provider === \"amazon-bedrock\") {\n\t\t// Amazon Bedrock supports multiple credential sources:\n\t\t// 1. AWS_PROFILE - named profile from ~/.aws/credentials\n\t\t// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys\n\t\t// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock bearer token\n\t\t// 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles\n\t\t// 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)\n\t\t// 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)\n\t\tif (\n\t\t\tgetProviderEnvValue(\"AWS_PROFILE\", env) ||\n\t\t\t(getProviderEnvValue(\"AWS_ACCESS_KEY_ID\", env) && getProviderEnvValue(\"AWS_SECRET_ACCESS_KEY\", env)) ||\n\t\t\tgetProviderEnvValue(\"AWS_BEARER_TOKEN_BEDROCK\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_CONTAINER_CREDENTIALS_FULL_URI\", env) ||\n\t\t\tgetProviderEnvValue(\"AWS_WEB_IDENTITY_TOKEN_FILE\", env)\n\t\t) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"]}
@@ -272,6 +272,21 @@ export declare const IMAGE_MODELS: {
272
272
  cacheWrite: number;
273
273
  };
274
274
  };
275
+ readonly "meta/muse-image": {
276
+ id: string;
277
+ name: string;
278
+ api: "openrouter-images";
279
+ provider: string;
280
+ baseUrl: string;
281
+ input: ("text" | "image")[];
282
+ output: "image"[];
283
+ cost: {
284
+ input: number;
285
+ output: number;
286
+ cacheRead: number;
287
+ cacheWrite: number;
288
+ };
289
+ };
275
290
  readonly "microsoft/mai-image-2.5": {
276
291
  id: string;
277
292
  name: string;
@@ -512,6 +527,66 @@ export declare const IMAGE_MODELS: {
512
527
  cacheWrite: number;
513
528
  };
514
529
  };
530
+ readonly "recraft/recraft-v4-styles": {
531
+ id: string;
532
+ name: string;
533
+ api: "openrouter-images";
534
+ provider: string;
535
+ baseUrl: string;
536
+ input: ("text" | "image")[];
537
+ output: "image"[];
538
+ cost: {
539
+ input: number;
540
+ output: number;
541
+ cacheRead: number;
542
+ cacheWrite: number;
543
+ };
544
+ };
545
+ readonly "recraft/recraft-v4-styles-pro": {
546
+ id: string;
547
+ name: string;
548
+ api: "openrouter-images";
549
+ provider: string;
550
+ baseUrl: string;
551
+ input: ("text" | "image")[];
552
+ output: "image"[];
553
+ cost: {
554
+ input: number;
555
+ output: number;
556
+ cacheRead: number;
557
+ cacheWrite: number;
558
+ };
559
+ };
560
+ readonly "recraft/recraft-v4-styles-pro-vector": {
561
+ id: string;
562
+ name: string;
563
+ api: "openrouter-images";
564
+ provider: string;
565
+ baseUrl: string;
566
+ input: ("text" | "image")[];
567
+ output: "image"[];
568
+ cost: {
569
+ input: number;
570
+ output: number;
571
+ cacheRead: number;
572
+ cacheWrite: number;
573
+ };
574
+ };
575
+ readonly "recraft/recraft-v4-styles-vector": {
576
+ id: string;
577
+ name: string;
578
+ api: "openrouter-images";
579
+ provider: string;
580
+ baseUrl: string;
581
+ input: ("text" | "image")[];
582
+ output: "image"[];
583
+ cost: {
584
+ input: number;
585
+ output: number;
586
+ cacheRead: number;
587
+ cacheWrite: number;
588
+ };
589
+ };
515
590
  readonly "recraft/recraft-v4-vector": {
516
591
  id: string;
517
592
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"image-models.generated.d.ts","sourceRoot":"","sources":["../src/image-models.generated.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAssBkD,CAAC"}
1
+ {"version":3,"file":"image-models.generated.d.ts","sourceRoot":"","sources":["../src/image-models.generated.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAixBkD,CAAC"}
@@ -274,6 +274,21 @@ export const IMAGE_MODELS = {
274
274
  cacheWrite: 0,
275
275
  },
276
276
  },
277
+ "meta/muse-image": {
278
+ id: "meta/muse-image",
279
+ name: "Meta: Muse Image",
280
+ api: "openrouter-images",
281
+ provider: "openrouter",
282
+ baseUrl: "https://openrouter.ai/api/v1",
283
+ input: ["text", "image"],
284
+ output: ["image"],
285
+ cost: {
286
+ input: 0,
287
+ output: 0,
288
+ cacheRead: 0,
289
+ cacheWrite: 0,
290
+ },
291
+ },
277
292
  "microsoft/mai-image-2.5": {
278
293
  id: "microsoft/mai-image-2.5",
279
294
  name: "Microsoft: MAI-Image-2.5",
@@ -514,6 +529,66 @@ export const IMAGE_MODELS = {
514
529
  cacheWrite: 0,
515
530
  },
516
531
  },
532
+ "recraft/recraft-v4-styles": {
533
+ id: "recraft/recraft-v4-styles",
534
+ name: "Recraft: Recraft V4 Styles",
535
+ api: "openrouter-images",
536
+ provider: "openrouter",
537
+ baseUrl: "https://openrouter.ai/api/v1",
538
+ input: ["text", "image"],
539
+ output: ["image"],
540
+ cost: {
541
+ input: 0,
542
+ output: 0,
543
+ cacheRead: 0,
544
+ cacheWrite: 0,
545
+ },
546
+ },
547
+ "recraft/recraft-v4-styles-pro": {
548
+ id: "recraft/recraft-v4-styles-pro",
549
+ name: "Recraft: Recraft V4 Styles Pro",
550
+ api: "openrouter-images",
551
+ provider: "openrouter",
552
+ baseUrl: "https://openrouter.ai/api/v1",
553
+ input: ["text", "image"],
554
+ output: ["image"],
555
+ cost: {
556
+ input: 0,
557
+ output: 0,
558
+ cacheRead: 0,
559
+ cacheWrite: 0,
560
+ },
561
+ },
562
+ "recraft/recraft-v4-styles-pro-vector": {
563
+ id: "recraft/recraft-v4-styles-pro-vector",
564
+ name: "Recraft: Recraft V4 Styles Pro Vector",
565
+ api: "openrouter-images",
566
+ provider: "openrouter",
567
+ baseUrl: "https://openrouter.ai/api/v1",
568
+ input: ["text", "image"],
569
+ output: ["image"],
570
+ cost: {
571
+ input: 0,
572
+ output: 0,
573
+ cacheRead: 0,
574
+ cacheWrite: 0,
575
+ },
576
+ },
577
+ "recraft/recraft-v4-styles-vector": {
578
+ id: "recraft/recraft-v4-styles-vector",
579
+ name: "Recraft: Recraft V4 Styles Vector",
580
+ api: "openrouter-images",
581
+ provider: "openrouter",
582
+ baseUrl: "https://openrouter.ai/api/v1",
583
+ input: ["text", "image"],
584
+ output: ["image"],
585
+ cost: {
586
+ input: 0,
587
+ output: 0,
588
+ cacheRead: 0,
589
+ cacheWrite: 0,
590
+ },
591
+ },
517
592
  "recraft/recraft-v4-vector": {
518
593
  id: "recraft/recraft-v4-vector",
519
594
  name: "Recraft: Recraft V4 Vector",