@code-yeongyu/senpi 2026.9.18 → 2026.9.19

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 (195) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/dist/bundle/chunks/{anthropic-messages-ZEJ3DPCP.js → anthropic-messages-WZCFP6BT.js} +1 -1
  3. package/dist/bundle/chunks/{app-server-command-ELSORC4D.js → app-server-command-QK7Q6XK5.js} +1 -1
  4. package/dist/bundle/chunks/bun-extension-importer-JQZRPNJH.js +10 -0
  5. package/dist/bundle/chunks/{chunk-Y6HDGVS5.js → chunk-34GCWLNV.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-XJUVWITG.js → chunk-3FRTRCR6.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-VRAYXSST.js → chunk-FDLVINNY.js} +2 -2
  8. package/dist/bundle/chunks/{chunk-QNZ24YOQ.js → chunk-HGAX6JZ7.js} +3 -1
  9. package/dist/bundle/chunks/{chunk-QGBRSL64.js → chunk-HSH674C6.js} +1 -1
  10. package/dist/bundle/chunks/chunk-IUZUN32Z.js +13 -0
  11. package/dist/bundle/chunks/chunk-IXAUDPOK.js +2 -0
  12. package/dist/bundle/chunks/{chunk-AH72FRZ2.js → chunk-KKDSBABY.js} +11 -11
  13. package/dist/bundle/chunks/{chunk-NLOZDJQX.js → chunk-LF3XTYYF.js} +3 -3
  14. package/dist/bundle/chunks/{chunk-ANTGWIGI.js → chunk-MUC3MZTV.js} +1 -1
  15. package/dist/bundle/chunks/chunk-NARL7XFO.js +8 -0
  16. package/dist/bundle/chunks/chunk-NQAVM5XL.js +2 -0
  17. package/dist/bundle/chunks/chunk-P7PWCGLJ.js +5 -0
  18. package/dist/bundle/chunks/{chunk-4C7LNOHI.js → chunk-PLZK7ABD.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-CKNRCW35.js → chunk-RLRLQRI2.js} +1 -1
  20. package/dist/bundle/chunks/{chunk-7FXIHFZU.js → chunk-UAYBYTFN.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-7A47FVQC.js → chunk-W4SRGDQ4.js} +3 -6
  22. package/dist/bundle/chunks/{chunk-QROWINIH.js → chunk-XK24AFYU.js} +1 -1
  23. package/dist/bundle/chunks/cli-main-7SG3K4K3.js +3 -0
  24. package/dist/bundle/chunks/cursor-agent.js +38 -0
  25. package/dist/bundle/chunks/cursor.js +2 -0
  26. package/dist/bundle/chunks/devin-agent.js +5 -0
  27. package/dist/bundle/chunks/devin.js +75 -0
  28. package/dist/bundle/chunks/{help-fast-path-WQCATMI4.js → help-fast-path-RQDCLDQT.js} +1 -1
  29. package/dist/bundle/chunks/host-command-3LS772D5.js +2 -0
  30. package/dist/bundle/chunks/{host-lifecycle-EAXSS3F2.js → host-lifecycle-TA5XGUW5.js} +1 -1
  31. package/dist/bundle/chunks/host-lifecycle.js +20 -0
  32. package/dist/bundle/chunks/interactive-host-runtime-AITXUDCT.js +4 -0
  33. package/dist/bundle/chunks/interactive-mode-7MN6GGCG.js +2 -0
  34. package/dist/bundle/chunks/{multi-session-host-OK6WMHB4.js → multi-session-host-WKX34SOP.js} +1 -1
  35. package/dist/bundle/chunks/{openai-completions-2RS3VSPV.js → openai-completions-TOWYKX2U.js} +1 -1
  36. package/dist/bundle/chunks/{package-manager-cli-C2K4YRGI.js → package-manager-cli-CB2X57TD.js} +1 -1
  37. package/dist/bundle/chunks/{rotation-stream-536AQTIS.js → rotation-stream-KDLA7K6X.js} +1 -1
  38. package/dist/bundle/chunks/rpc-mode-CI6V2SBW.js +2 -0
  39. package/dist/bundle/chunks/{session-picker-BUHK3FCS.js → session-picker-DXCITGLS.js} +1 -1
  40. package/dist/bundle/chunks/session-worker.js +359 -346
  41. package/dist/bundle/chunks/{state-store-OYDXEIXU.js → state-store-HBBOD7I5.js} +1 -1
  42. package/dist/bundle/cli.js +1 -1
  43. package/dist/bundle/index.js +1 -1
  44. package/dist/bundle/rpc-entry.js +1 -1
  45. package/dist/cli/args.d.ts.map +1 -1
  46. package/dist/cli/args.js +2 -0
  47. package/dist/cli/args.js.map +1 -1
  48. package/dist/cli/deferred-commands.d.ts +7 -0
  49. package/dist/cli/deferred-commands.d.ts.map +1 -1
  50. package/dist/cli/deferred-commands.js +12 -0
  51. package/dist/cli/deferred-commands.js.map +1 -1
  52. package/dist/cli/host-command.d.ts +21 -0
  53. package/dist/cli/host-command.d.ts.map +1 -0
  54. package/dist/cli/host-command.js +148 -0
  55. package/dist/cli/host-command.js.map +1 -0
  56. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts +1 -1
  57. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +2 -17
  59. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
  60. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-8.d.ts +3 -0
  61. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-8.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-8.js +5 -0
  63. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-8.js.map +1 -0
  64. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.d.ts +3 -0
  65. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.d.ts.map +1 -0
  66. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.js +28 -0
  67. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.js.map +1 -0
  68. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/prompt-preset/presets.js +21 -1
  70. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  71. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  72. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  74. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  75. package/dist/core/extensions/bun-extension-importer.d.ts.map +1 -1
  76. package/dist/core/extensions/bun-extension-importer.js +31 -5
  77. package/dist/core/extensions/bun-extension-importer.js.map +1 -1
  78. package/dist/core/extensions/bun-extension-registry.d.ts +9 -0
  79. package/dist/core/extensions/bun-extension-registry.d.ts.map +1 -1
  80. package/dist/core/extensions/bun-extension-registry.js +72 -16
  81. package/dist/core/extensions/bun-extension-registry.js.map +1 -1
  82. package/dist/core/extensions/extension-runtime-module.d.ts +5 -0
  83. package/dist/core/extensions/extension-runtime-module.d.ts.map +1 -0
  84. package/dist/core/extensions/extension-runtime-module.js +6 -0
  85. package/dist/core/extensions/extension-runtime-module.js.map +1 -0
  86. package/dist/core/model-resolver.d.ts.map +1 -1
  87. package/dist/core/model-resolver.js +1 -0
  88. package/dist/core/model-resolver.js.map +1 -1
  89. package/dist/index.d.ts +2 -1
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +3 -1
  92. package/dist/index.js.map +1 -1
  93. package/dist/main.d.ts.map +1 -1
  94. package/dist/main.js +7 -1
  95. package/dist/main.js.map +1 -1
  96. package/dist/modes/index.d.ts +3 -0
  97. package/dist/modes/index.d.ts.map +1 -1
  98. package/dist/modes/index.js +5 -0
  99. package/dist/modes/index.js.map +1 -1
  100. package/dist/modes/rpc/host-daemon-env.d.ts +18 -0
  101. package/dist/modes/rpc/host-daemon-env.d.ts.map +1 -0
  102. package/dist/modes/rpc/host-daemon-env.js +95 -0
  103. package/dist/modes/rpc/host-daemon-env.js.map +1 -0
  104. package/dist/modes/rpc/host-decision.d.ts +1 -1
  105. package/dist/modes/rpc/host-decision.d.ts.map +1 -1
  106. package/dist/modes/rpc/host-decision.js +2 -0
  107. package/dist/modes/rpc/host-decision.js.map +1 -1
  108. package/dist/modes/rpc/host-ensure.js +8 -1
  109. package/dist/modes/rpc/host-ensure.js.map +1 -1
  110. package/dist/modes/rpc/host-launch-spec.d.ts +43 -0
  111. package/dist/modes/rpc/host-launch-spec.d.ts.map +1 -0
  112. package/dist/modes/rpc/host-launch-spec.js +183 -0
  113. package/dist/modes/rpc/host-launch-spec.js.map +1 -0
  114. package/dist/modes/rpc/host-launch.d.ts +3 -1
  115. package/dist/modes/rpc/host-launch.d.ts.map +1 -1
  116. package/dist/modes/rpc/host-launch.js +24 -5
  117. package/dist/modes/rpc/host-launch.js.map +1 -1
  118. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  119. package/dist/modes/rpc/host-lifecycle.js +36 -2
  120. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  121. package/dist/modes/rpc/host-probe.d.ts +7 -0
  122. package/dist/modes/rpc/host-probe.d.ts.map +1 -1
  123. package/dist/modes/rpc/host-probe.js +15 -4
  124. package/dist/modes/rpc/host-probe.js.map +1 -1
  125. package/dist/modes/rpc/host-process-metrics.d.ts +10 -0
  126. package/dist/modes/rpc/host-process-metrics.d.ts.map +1 -0
  127. package/dist/modes/rpc/host-process-metrics.js +83 -0
  128. package/dist/modes/rpc/host-process-metrics.js.map +1 -0
  129. package/dist/modes/rpc/host-runner.d.ts +38 -0
  130. package/dist/modes/rpc/host-runner.d.ts.map +1 -0
  131. package/dist/modes/rpc/host-runner.js +195 -0
  132. package/dist/modes/rpc/host-runner.js.map +1 -0
  133. package/dist/modes/rpc/host-status.d.ts +58 -0
  134. package/dist/modes/rpc/host-status.d.ts.map +1 -0
  135. package/dist/modes/rpc/host-status.js +117 -0
  136. package/dist/modes/rpc/host-status.js.map +1 -0
  137. package/docs/extensions.md +35 -0
  138. package/docs/providers.md +30 -0
  139. package/docs/rpc.md +177 -15
  140. package/docs/settings.md +1 -1
  141. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +72 -0
  142. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  143. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  144. package/node_modules/@earendil-works/pi-ai/README.md +9 -0
  145. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  146. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -0
  147. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  148. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +2 -2
  149. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +2 -2
  151. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts +150 -7
  153. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  154. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +17 -3
  155. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  156. package/node_modules/@earendil-works/pi-ai/dist/providers/bai-stream.d.ts +13 -0
  157. package/node_modules/@earendil-works/pi-ai/dist/providers/bai-stream.d.ts.map +1 -0
  158. package/node_modules/@earendil-works/pi-ai/dist/providers/bai-stream.js +55 -0
  159. package/node_modules/@earendil-works/pi-ai/dist/providers/bai-stream.js.map +1 -0
  160. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.d.ts +11 -0
  161. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.d.ts.map +1 -0
  162. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.js +94 -0
  163. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.js.map +1 -0
  164. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.models.d.ts +4 -0
  165. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.models.d.ts.map +1 -0
  166. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.models.js +6 -0
  167. package/node_modules/@earendil-works/pi-ai/dist/providers/bai.models.js.map +1 -0
  168. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  169. package/node_modules/@earendil-works/pi-ai/dist/providers/data/bai.json +1 -0
  170. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
  171. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  172. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  173. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  174. package/node_modules/@earendil-works/pi-ai/dist/providers/data/venice.json +1 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  176. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +142 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +156 -3
  179. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  182. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  184. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  185. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  186. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  187. package/package.json +7 -7
  188. package/dist/bundle/chunks/bun-extension-importer-SW7XGNSG.js +0 -10
  189. package/dist/bundle/chunks/chunk-AGXZF7RF.js +0 -2
  190. package/dist/bundle/chunks/chunk-F5JZNLDE.js +0 -8
  191. package/dist/bundle/chunks/cli-main-4TWJXJKM.js +0 -3
  192. package/dist/bundle/chunks/interactive-host-runtime-EDXG6A5L.js +0 -4
  193. package/dist/bundle/chunks/interactive-mode-PD7S7KFZ.js +0 -2
  194. package/dist/bundle/chunks/rpc-mode-TIJFUWXS.js +0 -2
  195. package/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +0 -1
package/docs/rpc.md CHANGED
@@ -109,6 +109,17 @@ run - the wire protocol, attachment semantics and lifecycle windows are identica
109
109
  session is not isolated from the host: a session that blocks the event loop blocks every other session, and there is
110
110
  no per-session opening deadline like the worker runtime's 30-second budget.
111
111
 
112
+ What an in-process session costs is memory and host accounting, never an admission decision - but that cost is
113
+ linear, not flat. Measured on one socket host with the default builtins: about **one OS thread, two file descriptors
114
+ and 5-8 MB of RSS per open session**, with no plateau. At 1,000 concurrent sessions on one host the process went
115
+ from 20 to 1,023 threads, 14 to 2,014 descriptors and 151 MB to 4.7 GB resident, with zero errors and no refusal.
116
+ The thread is not the session runtime - the in-process runtime allocates none - it is the `config-reload` builtin,
117
+ which lazily spawns one filesystem-watch Worker per session
118
+ ([senpi#1794](https://github.com/code-yeongyu/senpi/issues/1794)); the same driver with that builtin disabled
119
+ measured 0 additional threads per session. Size a daemon from those numbers: it never refuses an `open_session` for
120
+ occupancy, so the ceiling is the machine's memory and its per-process thread and descriptor limits, not a session
121
+ count the host enforces.
122
+
112
123
  ### Host identity (`get_protocol_info`)
113
124
 
114
125
  Every `get_protocol_info` answer - classic and multi-session alike - carries the identity of the host that
@@ -181,7 +192,8 @@ upgraded, but its extension set does NOT cover what the running host loaded, so
181
192
  extensions) or `profile_mismatch_attached` (the launch profiles differ, or one of them is unknown - a client
182
193
  without a launch spec can prove nothing about extensions and therefore never initiates a handoff).
183
194
 
184
- Two invariants are encoded here, and every client is expected to keep them:
195
+ Four invariants govern every client of a shared host, and every client is expected to keep all four. The first two
196
+ are what this decision encodes; the other two are what a client must not undo elsewhere:
185
197
 
186
198
  - **I1 - never terminate, signal or replace a host this process did not start.** A missing capability or a
187
199
  foreign protocol version ends in `refuse`, never in a second host bound over an endpoint somebody else owns.
@@ -192,6 +204,18 @@ Two invariants are encoded here, and every client is expected to keep them:
192
204
  - **I2 - compatibility is protocol version + capabilities, never semver equality.** An ordinal that cannot be
193
205
  compared (a build without git metadata, a host that reports none) is EQUAL, and since a handoff requires
194
206
  STRICTLY greater, such a pair attaches instead of upgrading.
207
+ - **I3 - only the generation that owns the daemon state writes it; every other client reads.** A running host's
208
+ pidfile, settings, reservations and socket belong to that generation. A client that cannot use what it finds
209
+ fails CLOSED - it reports the refusal, or starts its own private host on its own endpoint - and never edits a
210
+ shared host's state files, unlinks its socket, or removes its pidfile to "clean up". A handoff is the one
211
+ exception and it still writes only its OWN generation directory before repointing the pointer (see
212
+ [Daemon state directory](#daemon-state-directory-layout-2)); the drained predecessor keeps its registration until
213
+ it exits, because it is still serving.
214
+ - **I4 - machine-driven work is invisible by default.** A session opened with `kind: "worker"` is omitted from
215
+ `list_sessions` unless the caller passes `include_workers: true`, its `context` is published on that listing only,
216
+ and its `session_closed`/`session_parked` records reach only the connections attached to it. A client that never
217
+ asked for worker sessions sees a daemon serving hundreds of them exactly as it saw an empty one, so a task runner
218
+ fanning out children cannot flood a desktop's session list.
195
219
 
196
220
  ### Generation handoff (`handoffHost`, `probeHost`, `stopHost`)
197
221
 
@@ -289,6 +313,105 @@ host, a reboot, a recycled pid with a different start time) is ignored. So a reo
289
313
  for the previous writer to finish rather than corrupting its transcript, and a session file is never
290
314
  permanently unopenable.
291
315
 
316
+ ### The `senpi host` command
317
+
318
+ Everything above is reachable from one command, so a terminal, a desktop and a task runner get a
319
+ daemon the same way instead of each re-implementing the decision:
320
+
321
+ ```
322
+ senpi host ensure [--json] [--launch-spec <file>] [--policy upgrade|fallback|never] [--socket <path>]
323
+ senpi host status [--json] [--include-workers] [--socket <path>]
324
+ senpi host stop [--json] [--drain] [--force] [--socket <path>]
325
+ senpi host handoff [--json] [--launch-spec <file>] [--socket <path>]
326
+ ```
327
+
328
+ The contract is machine-first: EXACTLY ONE JSON line on stdout and nothing else, diagnostics on stderr,
329
+ and an exit code that classifies the outcome without parsing the line.
330
+
331
+ | Exit | Meaning |
332
+ |---|---|
333
+ | `0` | it happened (`action`: `start`, `reuse`, `handoff`, `stopped`, `drained`, or a reachable `status`) |
334
+ | `1` | it failed; `{ action: "error", reason: "host_error", detail }` |
335
+ | `2` | the command line or the launch spec is unusable (`{ action: "error", reason: "launch_spec_*" }`) |
336
+ | `3` | refused: `{ action: "refuse", reason, host }` - or an unreachable socket (`status`) |
337
+ | `4` | fallback: `{ action: "fallback", reason, host }` - under `--policy fallback`, no host is better than this one |
338
+
339
+ The socket is `--socket`, else `SENPI_RPC_SOCKET`, else `<agentDir>/rpc/rpc.sock`. `--json` is accepted for
340
+ symmetry with other commands; the answer is always JSON.
341
+
342
+ - `ensure` prints `{ action, socket, pid, instanceId, generation, engineVersion, engineOrdinal,
343
+ capabilities, launchProfileId, reused, upgradeable }`. `--policy upgrade` (the default) allows a
344
+ generation handoff, `never` only attaches or starts, and `fallback` answers exit 4 rather than attaching
345
+ to a host this build disagrees with. `action` is `handoff` exactly when the socket was already served and
346
+ the process behind it changed.
347
+ - `status` prints `{ reachable, socket, pid, instanceId, generation, engineVersion, capabilities,
348
+ launchProfile, sessions: { total, interactive, worker, retained, foreign_attached, foreign_retained },
349
+ zombies, rss_mb, open_fds, env_keys, generations }` and exits 3 when nothing answers - with the same
350
+ field set, so a caller parses one shape and branches on one boolean. `sessions` is what `list_sessions`
351
+ reports under the same flag, so `worker` stays `0` without `--include-workers`; `foreign_*` is the same
352
+ count from the point of view of a client holding none of those sessions itself. `rss_mb`, `open_fds` and
353
+ `zombies` describe the daemon's whole process tree (supervisor plus host) and are `null` where the
354
+ platform does not publish them (`open_fds` is `/proc`-only). `generations` lists every generation record
355
+ in the daemon directory with `current` and `alive`.
356
+ - `stop` is the I1 carve-out: a plain stop needs a validated pidfile AND `foreign_attached +
357
+ foreign_retained == 0`, or it refuses with exit 3 and prints the counts it refused on; `--force`
358
+ overrides after printing the same counts; `--drain` (SIGUSR1) is always permitted, because it ends no
359
+ work.
360
+ - `handoff` forces a generation handoff from THIS binary. A host that cannot drain and a platform that
361
+ cannot rename answer alike: exit 3 `{ reason: "upgrade_unsupported", detail }`.
362
+
363
+ #### Launch spec (`--launch-spec <file>`)
364
+
365
+ The spec is what decides the code a long-lived, machine-wide daemon LOADS, so it is a trust boundary and
366
+ deliberately a FILE - never stdin, never an argv blob, both of which have no owner to check:
367
+
368
+ ```json
369
+ {
370
+ "spec_version": 1,
371
+ "core": { "session_runtime": "in-process", "multi_session": true, "extensions": ["ext/probe.js"] },
372
+ "tunables": { "idleExitMs": 900000, "coldStart": "transient" },
373
+ "env": { "SENPI_X": "1" }
374
+ }
375
+ ```
376
+
377
+ Extension paths are resolved against the SPEC FILE'S directory. Four refusals are proven before any
378
+ process is started, each reported with exit 2:
379
+
380
+ | Reason | When |
381
+ |---|---|
382
+ | `launch_spec_insecure` | the file is not owned by this uid, or it is group/world writable |
383
+ | `launch_spec_path_escape` | an extension path leaves the spec directory's tree, lexically or through a symlink |
384
+ | `launch_spec_env_denied` | an `env` key outside `^(SENPI\|OMO\|PI)_[A-Z0-9_]+$` |
385
+ | `launch_spec_missing_extension` | a listed extension does not exist - a daemon never boots with half a profile |
386
+
387
+ (`launch_spec_unreadable` and `launch_spec_invalid` cover a missing file and a malformed document.)
388
+
389
+ #### Daemon environment scope
390
+
391
+ A daemon outlives the shell that started it and serves every client on the machine, so it does NOT inherit
392
+ the ensuring process's environment. It receives an allowlist of NAMES - `PATH`, `HOME`, `USER`, `LOGNAME`,
393
+ `SHELL`, `TMPDIR`, `TERM`, `LANG`, `LC_*`, `XDG_*`, `SENPI_*`/`OMO_*`/`PI_*`, `HTTP_PROXY`/`HTTPS_PROXY`/
394
+ `NO_PROXY`, `*_API_KEY`, and the provider prefixes (`ANTHROPIC_`, `OPENAI_`, `GOOGLE_`, `GEMINI_`, `AZURE_`,
395
+ `AWS_`, `OPENROUTER_`, `XAI_`, `MISTRAL_`, `DEEPSEEK_`, `GROQ_`, `CEREBRAS_`, `MINIMAX_`) - plus whatever the
396
+ spec's `env` states. Matching is case-sensitive on POSIX and case-insensitive on win32, where the OS wiring
397
+ (`SystemRoot`, `ComSpec`, `PATHEXT`, ...) is allowed as well. Values are never inspected; `status` reports
398
+ the granted NAMES as `env_keys` and never a value.
399
+
400
+ #### Verifying a daemon build (live QA drivers)
401
+
402
+ Two POSIX-only drivers in this repository exercise the whole daemon against real processes in a sandbox agent
403
+ directory, printing one JSON line per step (written synchronously, so a step that hangs has still printed every step
404
+ before it) and a final cleanup receipt. They are how a build is checked before it is trusted with other clients'
405
+ sessions:
406
+
407
+ | Driver | What it proves |
408
+ |---|---|
409
+ | `node scripts/qa-rpc-socket/inprocess-daemon-qa.mjs` | Two COMPILED binaries of the tree differing only in build epoch; `host ensure --json` run from the older one; per-session `context` isolation (each session's extension sees only its own); `list_sessions` with and without `include_workers`; 50 sessions with the measured thread cost and no refusal; a retained session re-attached across a dropped connection; 200 bash calls leaving zero zombies; and a generation handoff by the newer binary while a client stays connected. |
410
+ | `node scripts/qa-rpc-socket/generation-handoff.mjs` | The handoff alone, against the source supervisor: `ensureHost` -> generation 0, `handoffHost` -> generation 1 on a new pid, `session_path_in_use` naming the owner while the held session is parking, `session_closed { reason: "handoff_parked" }`, the predecessor exiting, the transcript reopening intact in the new generation, and `stopHost({ drain: true })` draining to exit. |
411
+
412
+ Both exit non-zero if a daemon, a fixture host or the sandbox survives the run: a shared host outliving its QA is
413
+ exactly the failure they exist to catch.
414
+
292
415
  ### Child reaping on a socket host (`SENPI_RPC_HOST_REAPER`)
293
416
 
294
417
  A socket host reaps the exited child processes that no thread is left to wait on. A `worker_threads` Worker owns the
@@ -356,8 +479,13 @@ auth, model, extension or resource resolution, and they are never merged into th
356
479
  `invalid_session_context: <detail>`, where the detail names the cap that was broken.
357
480
 
358
481
  One shared host therefore loads ONE extension set and still lets an extension recognize the session it was loaded for
359
- (`pi.sessionKind`, `pi.sessionContext`). Probe `session_kind` and `session_context` in `get_protocol_info` capabilities
360
- before relying on either: an older host ignores both fields and lists every session.
482
+ (`pi.sessionKind`, `pi.sessionContext` - see
483
+ [ExtensionAPI session identity](extensions.md#pisessionkind--pisessioncontext--pisharedhostenabled)). Probe
484
+ `session_kind` and `session_context` in `get_protocol_info` capabilities before relying on either: an older host
485
+ ignores both fields and lists every session.
486
+
487
+ Default-invisible worker sessions are invariant **I4** above: a client that does not pass `include_workers: true`
488
+ sees the daemon exactly as it saw a host serving only that client.
361
489
 
362
490
  ### Session auto-titling
363
491
 
@@ -430,11 +558,16 @@ internal directory. The supervisor also exports `SENPI_RPC_HOST_WATCH_PPID` as a
430
558
  set only by the supervisor: a host started any other way (plain `senpi --mode rpc --listen …`, embedders, hand-started
431
559
  hosts) sees neither variable and is unaffected. A host whose supervisor is alive is never touched by this binding.
432
560
 
433
- ### Shared host occupancy (idle eviction, session cap, empty-host exit)
561
+ ### Shared host occupancy (idle eviction, retention, empty-host exit)
562
+
563
+ **The daemon does not cap sessions.** On the in-process runtime - the default for a `--listen` socket host, i.e. the
564
+ shared daemon clients attach to - there is no session limit, no admission counter, and no eviction of a live session
565
+ to make room for another: capacity is memory, and `open_session` is never refused for occupancy. `too_many_sessions`
566
+ exists only on the worker runtime described below. On that runtime every session owns a worker isolate and a complete
567
+ runtime; on the in-process runtime each session is a runtime in the host process. Memory depends on a session's
568
+ extensions and contents; neither runtime provides process-fatal OOM containment.
434
569
 
435
- On the worker runtime every CLI shared-host session owns a worker isolate and a complete runtime; on the in-process
436
- runtime (the socket-host default) each session is a runtime in the host process. Memory depends on its extensions and
437
- session contents; neither runtime provides process-fatal OOM containment. The host enforces these occupancy bounds:
570
+ What the host does enforce are lifecycle windows, and they only ever return memory from work nobody is doing:
438
571
 
439
572
  - **Idle eviction**: a session with no routed command and no session-owned work for
440
573
  `SENPI_RPC_SESSION_IDLE_EVICTION_MS` (default 30 minutes) is closed through the exact `close_session` sequence
@@ -455,14 +588,15 @@ session contents; neither runtime provides process-fatal OOM containment. The ho
455
588
  background terminal jobs and any other published wake source (terminal monitors, loop-guard holds), compaction,
456
589
  and barrier-held session work all defer eviction, and the idle clock restarts when that work settles. An evicted
457
590
  session resumes like any other: the next `open_session` with the same `sessionPath` reopens it.
458
- - **Worker capacity** (worker runtime only; an in-process host has no session cap of any kind): at most 20 workers
459
- may be preparing, open, closing, or quarantined together. Admission beyond
460
- this bound fails explicitly with `open_failed: too_many_sessions`; it never evicts another session or starts an OS
461
- process as a fallback. This is a new externally visible bound for CLI shared mode, which previously admitted
462
- unlimited logical sessions. It applies to new worker allocation, not attachments: a known canonical path or
463
- original opening spelling joins its already-bound owner without allocating a worker, even at capacity. An
464
- unknown path/alias still needs a preparation worker slot. In-process SDK registries using an injected runtime
465
- factory retain their existing behavior.
591
+ - **Worker capacity** (worker runtime ONLY - a stdio host, `--listen stdio://`, an embedder, or a socket host that
592
+ passed `--session-runtime worker` explicitly): at most 20 workers may be preparing, open, closing, or quarantined
593
+ together, because each one is an isolate the host must keep alive. Admission beyond this bound fails explicitly
594
+ with `open_failed: too_many_sessions`; it never evicts another session or starts an OS process as a fallback. It
595
+ applies to new worker allocation, not attachments: a known canonical path or original opening spelling joins its
596
+ already-bound owner without allocating a worker, even at capacity. An unknown path/alias still needs a preparation
597
+ worker slot. In-process SDK registries using an injected runtime factory retain their existing behavior. A socket
598
+ host on its default runtime never reaches this bound and never answers `too_many_sessions` - there is nothing to
599
+ raise, tune, or shard.
466
600
  - **Retained sessions**: a session opened with `open_session { retain_on_disconnect: true }` treats a client's
467
601
  disconnect as a DETACH, not a close. The dropped connection's attachment is released immediately (no waiting for a
468
602
  streaming turn, since nothing is being torn down), the entry stays `open` with `attachments: 0`, keeps running any
@@ -510,6 +644,30 @@ REPORT: nothing here aborts a turn, kills a session, or refuses an `open_session
510
644
 
511
645
  `host_stalled` and `host_memory_pressure` are additive records: a client that does not know them ignores them.
512
646
 
647
+ #### The no-sync rule
648
+
649
+ One event loop serves every session of the daemon, so a synchronous wait taken while handling one session is an
650
+ outage for all of them: a five-second `spawnSync` inside a tool is five seconds in which the host answers nobody -
651
+ not another session's `prompt`, not even `get_protocol_info`. The rule for code on the session path is therefore
652
+ absolute: **no blocking primitive, and no unbounded synchronous filesystem read.**
653
+
654
+ - Banned inside the engine: `execSync`, `execFileSync`, `spawnSync`, `Bun.spawnSync`, `Bun.sleepSync`, `Atomics.wait`.
655
+ A ban-with-ledger audit (`test/suite/no-sync-in-session-path.test.ts`) walks the transitive call graph rooted at the
656
+ session registry, session binding, connection handler, command router, `AgentSession`, auth storage and every tool,
657
+ and fails on any call site the checked-in ledger does not already record with the reason it is still there.
658
+ Synchronous filesystem calls are reported against the same ledger: a new call site, or one more call inside a
659
+ ledgered function, fails; removing one never does. The blocking ledger is five bounded entries - the sync credential
660
+ and settings lock backoffs (1 s budget each), the memoized `which`/`where` probe, the win32 `taskkill` path and an
661
+ on-demand tool extraction - and the filesystem ledger records each remaining synchronous read/write with the bytes
662
+ it moves (the JSONL transcript append is deliberately there), so "how long can this host be frozen by its own code"
663
+ has a written answer instead of a guess.
664
+ - The same rule applies to EXTENSIONS, where nothing can enforce it: an extension that shells out synchronously,
665
+ sleeps synchronously, or reads a large file synchronously inside an event handler freezes every other client's
666
+ session on that host. Use the async API, and give genuinely CPU-bound work its own worker or child process.
667
+ - The rule is observable rather than enforced at runtime: the stall watchdog above is what names the offender.
668
+ `host_stalled { driftMs, sessionId, tool }` and the matching stderr line are how a blocking call in a session or a
669
+ tool becomes a report instead of an unexplained freeze.
670
+
513
671
  ### Worker ownership and flow control
514
672
 
515
673
  This section describes the WORKER runtime (`--session-runtime worker`). An in-process host owns transport,
@@ -1768,6 +1926,10 @@ Events are streamed to stdout as JSON lines during agent operation. Events do no
1768
1926
  | `session_parked` | Multi-session host: a retained session was released to disk at the idle window (`sessionId`, `sessionPath`). Replaces `session_closed` for that handle |
1769
1927
  | `host_stalled` | Multi-session host: the event loop was blocked past `SENPI_RPC_LOOP_LAG_ERROR_MS`, with the drift and the session/tool blamed for it |
1770
1928
  | `host_memory_pressure` | Multi-session host: RSS is above `SENPI_RPC_HOST_RSS_WARN_MB`, with the live session count |
1929
+ | `session_opened` | Multi-session host: a session was opened on this host (content-free lifecycle record) |
1930
+ | `session_closed` | Multi-session host: a routing handle ended, with an optional `reason` (`handoff_parked` = a generation handoff put the session back on disk; reopen it by `sessionPath`) |
1931
+ | `session_parked` | Multi-session host: a retained session's handle was released while the session itself stays on disk (`{ sessionId, sessionPath }`); reopen it with `open_session { sessionPath }` |
1932
+ | `session_replaced` | The live session was swapped by `new_session`, `switch_session` or `fork`, carrying the new `durableSessionId` |
1771
1933
 
1772
1934
  Event types are additive: a client that does not recognise a type must ignore that record rather than fail. `model_changed`
1773
1935
  and `service_tier_changed` were added after the initial protocol and are safe to ignore. `session_parked`, `host_stalled`,
package/docs/settings.md CHANGED
@@ -88,7 +88,7 @@ Permission rules are a confirmation policy, not a sandbox. Senpi, extensions, pa
88
88
  | `modelThinkingLevels` | object | - | Per-model reasoning effort memory (`"provider/id": "level"`) |
89
89
  | `modelLastOnThinkingLevels` | object | - | Per-model last non-off reasoning level, used by `/reasoning on` to restore the previous effort |
90
90
  | `modelServiceTiers` | object | - | Per-model service tier memory (`"provider/id": "auto" \| "priority"`) |
91
- | `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-fable-5-1"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-1-flash"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, `"gpt-5.6"`, or `"gpt-6-astra"` |
91
+ | `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k2-8"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-fable-5-1"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-1-flash"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, `"gpt-5.6"`, or `"gpt-6-astra"` |
92
92
  | `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
93
93
  | `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses, compaction or branch-summary usage, and provider recovery diagnostics such as dropped Anthropic thinking blocks |
94
94
  | `thinkingBudgets` | object | - | Custom token budgets per thinking level. Anthropic, Google, and Bedrock use these natively. OpenAI-compatible models use them when `compat.thinkingTokenBudgetField` (or `supportsThinkingTokenBudget`) is set. |
@@ -12,6 +12,78 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.9.19] - 2026-09-19
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ ### Removed
26
+
27
+ ## [2026.9.18-6] - 2026-09-18
28
+
29
+ ### Breaking Changes
30
+
31
+ ### Added
32
+
33
+ ### Changed
34
+
35
+ ### Fixed
36
+
37
+ ### Removed
38
+
39
+ ## [2026.9.18-5] - 2026-09-18
40
+
41
+ ### Breaking Changes
42
+
43
+ ### Added
44
+
45
+ ### Changed
46
+
47
+ ### Fixed
48
+
49
+ ### Removed
50
+
51
+ ## [2026.9.18-4] - 2026-09-18
52
+
53
+ ### Breaking Changes
54
+
55
+ ### Added
56
+
57
+ ### Changed
58
+
59
+ ### Fixed
60
+
61
+ ### Removed
62
+
63
+ ## [2026.9.18-3] - 2026-09-18
64
+
65
+ ### Breaking Changes
66
+
67
+ ### Added
68
+
69
+ ### Changed
70
+
71
+ ### Fixed
72
+
73
+ ### Removed
74
+
75
+ ## [2026.9.18-2] - 2026-09-18
76
+
77
+ ### Breaking Changes
78
+
79
+ ### Added
80
+
81
+ ### Changed
82
+
83
+ ### Fixed
84
+
85
+ ### Removed
86
+
15
87
  ## [2026.9.18] - 2026-09-18
16
88
 
17
89
  ### Breaking Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "description": "Source-only senpi extension package for codemode evaluation tools",
6
6
  "type": "module",
@@ -31,14 +31,14 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/parser": "8.0.4",
34
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.18",
34
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.19",
35
35
  "typebox": "1.3.27"
36
36
  },
37
37
  "peerDependencies": {
38
- "@code-yeongyu/senpi": "2026.9.18"
38
+ "@code-yeongyu/senpi": "2026.9.19"
39
39
  },
40
40
  "devDependencies": {
41
- "@code-yeongyu/senpi": "2026.9.18"
41
+ "@code-yeongyu/senpi": "2026.9.19"
42
42
  },
43
43
  "keywords": [
44
44
  "senpi",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-agent-core",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -57,8 +57,8 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@earendil-works/chord": "0.85.1",
60
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.18",
61
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.18",
60
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.19",
61
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.19",
62
62
  "diff": "9.0.0",
63
63
  "ignore": "7.0.8",
64
64
  "typebox": "1.3.27",
@@ -58,6 +58,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
58
58
  ## Supported Providers
59
59
 
60
60
  - **OpenAI**
61
+ - **B.AI** (credential-scoped multi-provider catalog)
61
62
  - **Ant Ling**
62
63
  - **Azure OpenAI (Responses)**
63
64
  - **OpenAI Codex** (ChatGPT Plus/Pro subscription, requires OAuth, see below)
@@ -329,6 +330,13 @@ const fresh = models.getModel('llamacpp', 'qwen3-30b');
329
330
 
330
331
  Static built-in providers are no-ops for `refresh()`. See [createProvider()](#createprovider) for building a dynamic provider.
331
332
 
333
+ B.AI is dynamic: `GET https://api.b.ai/v1/models` returns the model IDs available to the current credential,
334
+ while the shipped catalog supplies B.AI's documented capabilities and standard reference pricing. B.AI serves
335
+ one key over three protocols and documents several models on more than one of them, so Senpi pins the endpoint
336
+ per model rather than treating it as a B.AI property: GPT and DeepSeek use OpenAI Responses, Claude uses
337
+ Anthropic Messages, and the remaining chat families use OpenAI Chat Completions. Image-only IDs such as
338
+ `gpt-image-2` are not exposed through the chat catalog.
339
+
332
340
  ## Auth
333
341
 
334
342
  Every provider owns its auth: how API keys resolve (stored credentials, environment variables, ambient sources like AWS profiles or gcloud ADC) and, where supported, OAuth login/refresh flows.
@@ -421,6 +429,7 @@ Built-in providers resolve these env vars (Node.js; in browsers pass `apiKey` ex
421
429
  | Provider | Environment Variable(s) |
422
430
  |----------|------------------------|
423
431
  | OpenAI | `OPENAI_API_KEY` |
432
+ | B.AI | `BAI_API_KEY` |
424
433
  | Ollama Cloud | `OLLAMA_API_KEY` |
425
434
  | Ant Ling | `ANT_LING_API_KEY` |
426
435
  | Azure OpenAI | `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_BASE_URL` (e.g. `https://{resource}.ai.azure.com`) or `AZURE_OPENAI_RESOURCE_NAME`. Supports `*.openai.azure.com`, `*.cognitiveservices.azure.com` and `*.ai.azure.com`; root endpoints auto-normalize to `/openai/v1`. Optional: `AZURE_OPENAI_API_VERSION` (default `v1`), `AZURE_OPENAI_DEPLOYMENT_NAME_MAP`. |
@@ -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;AAqCzD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAwDhF;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"}
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,CAyDhF;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"}
@@ -106,6 +106,7 @@ export function getApiKeyEnvVars(provider) {
106
106
  fireworks: "FIREWORKS_API_KEY",
107
107
  together: "TOGETHER_API_KEY",
108
108
  baseten: "BASETEN_API_KEY",
109
+ bai: "BAI_API_KEY",
109
110
  opencode: "OPENCODE_API_KEY",
110
111
  "opencode-go": "OPENCODE_API_KEY",
111
112
  "kimi-coding": "KIMI_API_KEY",
@@ -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\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\tvenice: \"VENICE_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\tvenice: \"VENICE_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\tbai: \"BAI_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"]}
@@ -3,6 +3,7 @@ import { AMAZON_BEDROCK_MODELS } from "./providers/amazon-bedrock.models.ts";
3
3
  import { ANT_LING_MODELS } from "./providers/ant-ling.models.ts";
4
4
  import { ANTHROPIC_MODELS } from "./providers/anthropic.models.ts";
5
5
  import { AZURE_OPENAI_RESPONSES_MODELS } from "./providers/azure-openai-responses.models.ts";
6
+ import { BAI_MODELS } from "./providers/bai.models.ts";
6
7
  import { BASETEN_MODELS } from "./providers/baseten.models.ts";
7
8
  import { CEREBRAS_MODELS } from "./providers/cerebras.models.ts";
8
9
  import { CLOUDFLARE_AI_GATEWAY_MODELS } from "./providers/cloudflare-ai-gateway.models.ts";
@@ -14,7 +15,6 @@ import { GOOGLE_MODELS } from "./providers/google.models.ts";
14
15
  import { GOOGLE_VERTEX_MODELS } from "./providers/google-vertex.models.ts";
15
16
  import { GROQ_MODELS } from "./providers/groq.models.ts";
16
17
  import { HUGGINGFACE_MODELS } from "./providers/huggingface.models.ts";
17
- import { KIMI_CODING_MODELS } from "./providers/kimi-coding.models.ts";
18
18
  import { MINIMAX_MODELS } from "./providers/minimax.models.ts";
19
19
  import { MINIMAX_CN_MODELS } from "./providers/minimax-cn.models.ts";
20
20
  import { MISTRAL_MODELS } from "./providers/mistral.models.ts";
@@ -46,6 +46,7 @@ export declare const MODELS: {
46
46
  readonly "ant-ling": typeof ANT_LING_MODELS;
47
47
  readonly "anthropic": typeof ANTHROPIC_MODELS;
48
48
  readonly "azure-openai-responses": typeof AZURE_OPENAI_RESPONSES_MODELS;
49
+ readonly "bai": typeof BAI_MODELS;
49
50
  readonly "baseten": typeof BASETEN_MODELS;
50
51
  readonly "cerebras": typeof CEREBRAS_MODELS;
51
52
  readonly "cloudflare-ai-gateway": typeof CLOUDFLARE_AI_GATEWAY_MODELS;
@@ -57,7 +58,6 @@ export declare const MODELS: {
57
58
  readonly "google-vertex": typeof GOOGLE_VERTEX_MODELS;
58
59
  readonly "groq": typeof GROQ_MODELS;
59
60
  readonly "huggingface": typeof HUGGINGFACE_MODELS;
60
- readonly "kimi-coding": typeof KIMI_CODING_MODELS;
61
61
  readonly "minimax": typeof MINIMAX_MODELS;
62
62
  readonly "minimax-cn": typeof MINIMAX_CN_MODELS;
63
63
  readonly "mistral": typeof MISTRAL_MODELS;
@@ -1 +1 @@
1
- {"version":3,"file":"models.generated.d.ts","sourceRoot":"","sources":["../src/models.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"models.generated.d.ts","sourceRoot":"","sources":["../src/models.generated.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import { AMAZON_BEDROCK_MODELS } from "./providers/amazon-bedrock.models.js";
5
5
  import { ANT_LING_MODELS } from "./providers/ant-ling.models.js";
6
6
  import { ANTHROPIC_MODELS } from "./providers/anthropic.models.js";
7
7
  import { AZURE_OPENAI_RESPONSES_MODELS } from "./providers/azure-openai-responses.models.js";
8
+ import { BAI_MODELS } from "./providers/bai.models.js";
8
9
  import { BASETEN_MODELS } from "./providers/baseten.models.js";
9
10
  import { CEREBRAS_MODELS } from "./providers/cerebras.models.js";
10
11
  import { CLOUDFLARE_AI_GATEWAY_MODELS } from "./providers/cloudflare-ai-gateway.models.js";
@@ -16,7 +17,6 @@ import { GOOGLE_MODELS } from "./providers/google.models.js";
16
17
  import { GOOGLE_VERTEX_MODELS } from "./providers/google-vertex.models.js";
17
18
  import { GROQ_MODELS } from "./providers/groq.models.js";
18
19
  import { HUGGINGFACE_MODELS } from "./providers/huggingface.models.js";
19
- import { KIMI_CODING_MODELS } from "./providers/kimi-coding.models.js";
20
20
  import { MINIMAX_MODELS } from "./providers/minimax.models.js";
21
21
  import { MINIMAX_CN_MODELS } from "./providers/minimax-cn.models.js";
22
22
  import { MISTRAL_MODELS } from "./providers/mistral.models.js";
@@ -48,6 +48,7 @@ export const MODELS = {
48
48
  "ant-ling": ANT_LING_MODELS,
49
49
  "anthropic": ANTHROPIC_MODELS,
50
50
  "azure-openai-responses": AZURE_OPENAI_RESPONSES_MODELS,
51
+ "bai": BAI_MODELS,
51
52
  "baseten": BASETEN_MODELS,
52
53
  "cerebras": CEREBRAS_MODELS,
53
54
  "cloudflare-ai-gateway": CLOUDFLARE_AI_GATEWAY_MODELS,
@@ -59,7 +60,6 @@ export const MODELS = {
59
60
  "google-vertex": GOOGLE_VERTEX_MODELS,
60
61
  "groq": GROQ_MODELS,
61
62
  "huggingface": HUGGINGFACE_MODELS,
62
- "kimi-coding": KIMI_CODING_MODELS,
63
63
  "minimax": MINIMAX_MODELS,
64
64
  "minimax-cn": MINIMAX_CN_MODELS,
65
65
  "mistral": MISTRAL_MODELS,