evolcore 0.0.5 → 0.0.7

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 (323) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +4 -12
  3. package/dist/agents/baseagent.js +39 -0
  4. package/dist/agents/claude-runner.js +10 -2
  5. package/dist/agents/codex-runner.js +37 -8
  6. package/dist/agents/ecagent-runner.js +1159 -0
  7. package/dist/agents/gemini-runner.js +4 -1
  8. package/dist/agents/runner-types.js +20 -4
  9. package/dist/aun/msg/history.js +32 -9
  10. package/dist/aun/outbox.js +4 -9
  11. package/dist/channels/aun.js +32 -6
  12. package/dist/channels/daemon.js +7 -4
  13. package/dist/channels/dingtalk.js +3 -5
  14. package/dist/channels/feishu.js +16 -108
  15. package/dist/channels/wechat.js +4 -4
  16. package/dist/channels/wecom.js +4 -6
  17. package/dist/cli/agent-command.js +1 -1
  18. package/dist/cli/agent.js +42 -11
  19. package/dist/cli/aun-commands.js +50 -3
  20. package/dist/cli/daemon-commands.js +88 -8
  21. package/dist/cli/data-command.js +132 -0
  22. package/dist/cli/index.js +11 -3
  23. package/dist/cli/init.js +76 -17
  24. package/dist/cli/net-check.js +9 -20
  25. package/dist/cli/restart-monitor.js +25 -2
  26. package/dist/cli/trigger-command.js +1 -1
  27. package/dist/cli/watch-msg.js +12 -25
  28. package/dist/config/builtin-roles.js +3 -1
  29. package/dist/config/config-field-policy.js +1 -1
  30. package/dist/config/gateway-config.js +21 -4
  31. package/dist/config/resolved-config-op.js +10 -0
  32. package/dist/core/command/command-handler.js +2 -2
  33. package/dist/core/command/menu-handler.js +11 -9
  34. package/dist/core/command/role-menu.js +11 -0
  35. package/dist/core/command/slash-handler.js +18 -14
  36. package/dist/core/data-migration.js +1434 -0
  37. package/dist/core/handoff/store.js +14 -4
  38. package/dist/core/inference/text-inference.js +42 -1
  39. package/dist/core/message/pending-hints.js +1 -1
  40. package/dist/core/message/response-engine.js +406 -167
  41. package/dist/core/message/retry-scheduler.js +71 -0
  42. package/dist/core/model/model-catalog.js +7 -2
  43. package/dist/core/model/model-fallback.js +81 -0
  44. package/dist/core/protected-paths.js +41 -8
  45. package/dist/core/session/adapters/ecagent-session-file-adapter.js +112 -0
  46. package/dist/core/session/session-fs-store.js +283 -59
  47. package/dist/core/session/session-manager.js +19 -21
  48. package/dist/core/session/session-title.js +1 -0
  49. package/dist/core/session/session-turn-coordinator.js +8 -1
  50. package/dist/core/system-channels.js +1 -0
  51. package/dist/index.js +13 -10
  52. package/dist/paths.js +35 -27
  53. package/dist/trigger/feedback.js +16 -0
  54. package/dist/trigger/legacy-session-history.js +19 -0
  55. package/dist/trigger/manager.js +12 -1
  56. package/dist/trigger/parser.js +4 -2
  57. package/dist/trigger/scheduler.js +185 -15
  58. package/dist/trigger/session-lock.js +62 -0
  59. package/dist/trigger/state.js +64 -0
  60. package/dist/trigger/validation.js +32 -2
  61. package/dist/utils/aid-bind.js +1 -1
  62. package/dist/utils/error-utils.js +9 -0
  63. package/dist/utils/instance-registry.js +2 -2
  64. package/dist/utils/welcome.js +2 -3
  65. package/ecagent/LICENSE +21 -0
  66. package/ecagent/NOTICE +11 -0
  67. package/ecagent/README.md +61 -0
  68. package/ecagent/dist/agent-loop.d.ts +24 -0
  69. package/ecagent/dist/agent-loop.d.ts.map +1 -0
  70. package/ecagent/dist/agent-loop.js +547 -0
  71. package/ecagent/dist/agent-loop.js.map +1 -0
  72. package/ecagent/dist/agent.d.ts +127 -0
  73. package/ecagent/dist/agent.d.ts.map +1 -0
  74. package/ecagent/dist/agent.js +386 -0
  75. package/ecagent/dist/agent.js.map +1 -0
  76. package/ecagent/dist/harness/agent-harness.d.ts +95 -0
  77. package/ecagent/dist/harness/agent-harness.d.ts.map +1 -0
  78. package/ecagent/dist/harness/agent-harness.js +926 -0
  79. package/ecagent/dist/harness/agent-harness.js.map +1 -0
  80. package/ecagent/dist/harness/compaction/branch-summarization.d.ts +51 -0
  81. package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
  82. package/ecagent/dist/harness/compaction/branch-summarization.js +174 -0
  83. package/ecagent/dist/harness/compaction/branch-summarization.js.map +1 -0
  84. package/ecagent/dist/harness/compaction/compaction.d.ts +95 -0
  85. package/ecagent/dist/harness/compaction/compaction.d.ts.map +1 -0
  86. package/ecagent/dist/harness/compaction/compaction.js +528 -0
  87. package/ecagent/dist/harness/compaction/compaction.js.map +1 -0
  88. package/ecagent/dist/harness/compaction/utils.d.ts +25 -0
  89. package/ecagent/dist/harness/compaction/utils.d.ts.map +1 -0
  90. package/ecagent/dist/harness/compaction/utils.js +131 -0
  91. package/ecagent/dist/harness/compaction/utils.js.map +1 -0
  92. package/ecagent/dist/harness/env/nodejs.d.ts +51 -0
  93. package/ecagent/dist/harness/env/nodejs.d.ts.map +1 -0
  94. package/ecagent/dist/harness/env/nodejs.js +513 -0
  95. package/ecagent/dist/harness/env/nodejs.js.map +1 -0
  96. package/ecagent/dist/harness/messages.d.ts +51 -0
  97. package/ecagent/dist/harness/messages.d.ts.map +1 -0
  98. package/ecagent/dist/harness/messages.js +102 -0
  99. package/ecagent/dist/harness/messages.js.map +1 -0
  100. package/ecagent/dist/harness/prompt-templates.d.ts +48 -0
  101. package/ecagent/dist/harness/prompt-templates.d.ts.map +1 -0
  102. package/ecagent/dist/harness/prompt-templates.js +230 -0
  103. package/ecagent/dist/harness/prompt-templates.js.map +1 -0
  104. package/ecagent/dist/harness/session/jsonl-repo.d.ts +26 -0
  105. package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +1 -0
  106. package/ecagent/dist/harness/session/jsonl-repo.js +100 -0
  107. package/ecagent/dist/harness/session/jsonl-repo.js.map +1 -0
  108. package/ecagent/dist/harness/session/jsonl-storage.d.ts +34 -0
  109. package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +1 -0
  110. package/ecagent/dist/harness/session/jsonl-storage.js +234 -0
  111. package/ecagent/dist/harness/session/jsonl-storage.js.map +1 -0
  112. package/ecagent/dist/harness/session/memory-repo.d.ts +18 -0
  113. package/ecagent/dist/harness/session/memory-repo.d.ts.map +1 -0
  114. package/ecagent/dist/harness/session/memory-repo.js +44 -0
  115. package/ecagent/dist/harness/session/memory-repo.js.map +1 -0
  116. package/ecagent/dist/harness/session/memory-storage.d.ts +25 -0
  117. package/ecagent/dist/harness/session/memory-storage.d.ts.map +1 -0
  118. package/ecagent/dist/harness/session/memory-storage.js +111 -0
  119. package/ecagent/dist/harness/session/memory-storage.js.map +1 -0
  120. package/ecagent/dist/harness/session/repo-utils.d.ts +11 -0
  121. package/ecagent/dist/harness/session/repo-utils.d.ts.map +1 -0
  122. package/ecagent/dist/harness/session/repo-utils.js +39 -0
  123. package/ecagent/dist/harness/session/repo-utils.js.map +1 -0
  124. package/ecagent/dist/harness/session/session.d.ts +47 -0
  125. package/ecagent/dist/harness/session/session.d.ts.map +1 -0
  126. package/ecagent/dist/harness/session/session.js +245 -0
  127. package/ecagent/dist/harness/session/session.js.map +1 -0
  128. package/ecagent/dist/harness/session/uuid.d.ts +2 -0
  129. package/ecagent/dist/harness/session/uuid.d.ts.map +1 -0
  130. package/ecagent/dist/harness/session/uuid.js +50 -0
  131. package/ecagent/dist/harness/session/uuid.js.map +1 -0
  132. package/ecagent/dist/harness/skills.d.ts +44 -0
  133. package/ecagent/dist/harness/skills.d.ts.map +1 -0
  134. package/ecagent/dist/harness/skills.js +311 -0
  135. package/ecagent/dist/harness/skills.js.map +1 -0
  136. package/ecagent/dist/harness/system-prompt.d.ts +3 -0
  137. package/ecagent/dist/harness/system-prompt.d.ts.map +1 -0
  138. package/ecagent/dist/harness/system-prompt.js +30 -0
  139. package/ecagent/dist/harness/system-prompt.js.map +1 -0
  140. package/ecagent/dist/harness/types.d.ts +619 -0
  141. package/ecagent/dist/harness/types.d.ts.map +1 -0
  142. package/ecagent/dist/harness/types.js +81 -0
  143. package/ecagent/dist/harness/types.js.map +1 -0
  144. package/ecagent/dist/harness/utils/shell-output.d.ts +14 -0
  145. package/ecagent/dist/harness/utils/shell-output.d.ts.map +1 -0
  146. package/ecagent/dist/harness/utils/shell-output.js +126 -0
  147. package/ecagent/dist/harness/utils/shell-output.js.map +1 -0
  148. package/ecagent/dist/harness/utils/truncate.d.ts +70 -0
  149. package/ecagent/dist/harness/utils/truncate.d.ts.map +1 -0
  150. package/ecagent/dist/harness/utils/truncate.js +290 -0
  151. package/ecagent/dist/harness/utils/truncate.js.map +1 -0
  152. package/ecagent/dist/index.d.ts +22 -0
  153. package/ecagent/dist/index.d.ts.map +1 -0
  154. package/ecagent/dist/index.js +27 -0
  155. package/ecagent/dist/index.js.map +1 -0
  156. package/ecagent/dist/node.d.ts +3 -0
  157. package/ecagent/dist/node.d.ts.map +1 -0
  158. package/ecagent/dist/node.js +3 -0
  159. package/ecagent/dist/node.js.map +1 -0
  160. package/ecagent/dist/proxy.d.ts +69 -0
  161. package/ecagent/dist/proxy.d.ts.map +1 -0
  162. package/ecagent/dist/proxy.js +278 -0
  163. package/ecagent/dist/proxy.js.map +1 -0
  164. package/ecagent/dist/runtime/api/lazy.d.ts +15 -0
  165. package/ecagent/dist/runtime/api/lazy.d.ts.map +1 -0
  166. package/ecagent/dist/runtime/api/lazy.js +59 -0
  167. package/ecagent/dist/runtime/api/lazy.js.map +1 -0
  168. package/ecagent/dist/runtime/api/pi-messages.d.ts +97 -0
  169. package/ecagent/dist/runtime/api/pi-messages.d.ts.map +1 -0
  170. package/ecagent/dist/runtime/api/pi-messages.js +307 -0
  171. package/ecagent/dist/runtime/api/pi-messages.js.map +1 -0
  172. package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts +3 -0
  173. package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +1 -0
  174. package/ecagent/dist/runtime/api/pi-messages.lazy.js +3 -0
  175. package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +1 -0
  176. package/ecagent/dist/runtime/auth/context.d.ts +7 -0
  177. package/ecagent/dist/runtime/auth/context.d.ts.map +1 -0
  178. package/ecagent/dist/runtime/auth/context.js +42 -0
  179. package/ecagent/dist/runtime/auth/context.js.map +1 -0
  180. package/ecagent/dist/runtime/auth/credential-store.d.ts +16 -0
  181. package/ecagent/dist/runtime/auth/credential-store.d.ts.map +1 -0
  182. package/ecagent/dist/runtime/auth/credential-store.js +39 -0
  183. package/ecagent/dist/runtime/auth/credential-store.js.map +1 -0
  184. package/ecagent/dist/runtime/auth/helpers.d.ts +20 -0
  185. package/ecagent/dist/runtime/auth/helpers.d.ts.map +1 -0
  186. package/ecagent/dist/runtime/auth/helpers.js +46 -0
  187. package/ecagent/dist/runtime/auth/helpers.js.map +1 -0
  188. package/ecagent/dist/runtime/auth/resolve.d.ts +26 -0
  189. package/ecagent/dist/runtime/auth/resolve.d.ts.map +1 -0
  190. package/ecagent/dist/runtime/auth/resolve.js +100 -0
  191. package/ecagent/dist/runtime/auth/resolve.js.map +1 -0
  192. package/ecagent/dist/runtime/auth/types.d.ts +180 -0
  193. package/ecagent/dist/runtime/auth/types.d.ts.map +1 -0
  194. package/ecagent/dist/runtime/auth/types.js +2 -0
  195. package/ecagent/dist/runtime/auth/types.js.map +1 -0
  196. package/ecagent/dist/runtime/compat.d.ts +28 -0
  197. package/ecagent/dist/runtime/compat.d.ts.map +1 -0
  198. package/ecagent/dist/runtime/compat.js +86 -0
  199. package/ecagent/dist/runtime/compat.js.map +1 -0
  200. package/ecagent/dist/runtime/index.d.ts +20 -0
  201. package/ecagent/dist/runtime/index.d.ts.map +1 -0
  202. package/ecagent/dist/runtime/index.js +17 -0
  203. package/ecagent/dist/runtime/index.js.map +1 -0
  204. package/ecagent/dist/runtime/models.d.ts +142 -0
  205. package/ecagent/dist/runtime/models.d.ts.map +1 -0
  206. package/ecagent/dist/runtime/models.js +245 -0
  207. package/ecagent/dist/runtime/models.js.map +1 -0
  208. package/ecagent/dist/runtime/oauth.d.ts +2 -0
  209. package/ecagent/dist/runtime/oauth.d.ts.map +1 -0
  210. package/ecagent/dist/runtime/oauth.js +2 -0
  211. package/ecagent/dist/runtime/oauth.js.map +1 -0
  212. package/ecagent/dist/runtime/providers/faux.d.ts +97 -0
  213. package/ecagent/dist/runtime/providers/faux.d.ts.map +1 -0
  214. package/ecagent/dist/runtime/providers/faux.js +395 -0
  215. package/ecagent/dist/runtime/providers/faux.js.map +1 -0
  216. package/ecagent/dist/runtime/types.d.ts +607 -0
  217. package/ecagent/dist/runtime/types.d.ts.map +1 -0
  218. package/ecagent/dist/runtime/types.js +2 -0
  219. package/ecagent/dist/runtime/types.js.map +1 -0
  220. package/ecagent/dist/runtime/utils/diagnostics.d.ts +19 -0
  221. package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +1 -0
  222. package/ecagent/dist/runtime/utils/diagnostics.js +25 -0
  223. package/ecagent/dist/runtime/utils/diagnostics.js.map +1 -0
  224. package/ecagent/dist/runtime/utils/event-stream.d.ts +21 -0
  225. package/ecagent/dist/runtime/utils/event-stream.d.ts.map +1 -0
  226. package/ecagent/dist/runtime/utils/event-stream.js +77 -0
  227. package/ecagent/dist/runtime/utils/event-stream.js.map +1 -0
  228. package/ecagent/dist/runtime/utils/headers.d.ts +4 -0
  229. package/ecagent/dist/runtime/utils/headers.d.ts.map +1 -0
  230. package/ecagent/dist/runtime/utils/headers.js +18 -0
  231. package/ecagent/dist/runtime/utils/headers.js.map +1 -0
  232. package/ecagent/dist/runtime/utils/json-parse.d.ts +16 -0
  233. package/ecagent/dist/runtime/utils/json-parse.d.ts.map +1 -0
  234. package/ecagent/dist/runtime/utils/json-parse.js +113 -0
  235. package/ecagent/dist/runtime/utils/json-parse.js.map +1 -0
  236. package/ecagent/dist/runtime/utils/oauth/types.d.ts +64 -0
  237. package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +1 -0
  238. package/ecagent/dist/runtime/utils/oauth/types.js +2 -0
  239. package/ecagent/dist/runtime/utils/oauth/types.js.map +1 -0
  240. package/ecagent/dist/runtime/utils/overflow.d.ts +58 -0
  241. package/ecagent/dist/runtime/utils/overflow.d.ts.map +1 -0
  242. package/ecagent/dist/runtime/utils/overflow.js +158 -0
  243. package/ecagent/dist/runtime/utils/overflow.js.map +1 -0
  244. package/ecagent/dist/runtime/utils/provider-env.d.ts +7 -0
  245. package/ecagent/dist/runtime/utils/provider-env.d.ts.map +1 -0
  246. package/ecagent/dist/runtime/utils/provider-env.js +44 -0
  247. package/ecagent/dist/runtime/utils/provider-env.js.map +1 -0
  248. package/ecagent/dist/runtime/utils/retry.d.ts +12 -0
  249. package/ecagent/dist/runtime/utils/retry.d.ts.map +1 -0
  250. package/ecagent/dist/runtime/utils/retry.js +90 -0
  251. package/ecagent/dist/runtime/utils/retry.js.map +1 -0
  252. package/ecagent/dist/runtime/utils/typebox-helpers.d.ts +17 -0
  253. package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +1 -0
  254. package/ecagent/dist/runtime/utils/typebox-helpers.js +21 -0
  255. package/ecagent/dist/runtime/utils/typebox-helpers.js.map +1 -0
  256. package/ecagent/dist/runtime/utils/validation.d.ts +18 -0
  257. package/ecagent/dist/runtime/utils/validation.d.ts.map +1 -0
  258. package/ecagent/dist/runtime/utils/validation.js +269 -0
  259. package/ecagent/dist/runtime/utils/validation.js.map +1 -0
  260. package/ecagent/dist/types.d.ts +401 -0
  261. package/ecagent/dist/types.d.ts.map +1 -0
  262. package/ecagent/dist/types.js +2 -0
  263. package/ecagent/dist/types.js.map +1 -0
  264. package/ecagent/package.json +93 -0
  265. package/ecagent/src/agent-loop.ts +792 -0
  266. package/ecagent/src/agent.ts +575 -0
  267. package/ecagent/src/harness/agent-harness.ts +1029 -0
  268. package/ecagent/src/harness/compaction/branch-summarization.ts +261 -0
  269. package/ecagent/src/harness/compaction/compaction.ts +753 -0
  270. package/ecagent/src/harness/compaction/utils.ts +144 -0
  271. package/ecagent/src/harness/env/nodejs.ts +569 -0
  272. package/ecagent/src/harness/messages.ts +164 -0
  273. package/ecagent/src/harness/prompt-templates.ts +267 -0
  274. package/ecagent/src/harness/session/jsonl-repo.ts +179 -0
  275. package/ecagent/src/harness/session/jsonl-storage.ts +314 -0
  276. package/ecagent/src/harness/session/memory-repo.ts +50 -0
  277. package/ecagent/src/harness/session/memory-storage.ts +133 -0
  278. package/ecagent/src/harness/session/repo-utils.ts +51 -0
  279. package/ecagent/src/harness/session/session.ts +338 -0
  280. package/ecagent/src/harness/session/uuid.ts +54 -0
  281. package/ecagent/src/harness/skills.ts +375 -0
  282. package/ecagent/src/harness/system-prompt.ts +34 -0
  283. package/ecagent/src/harness/types.ts +838 -0
  284. package/ecagent/src/harness/utils/shell-output.ts +135 -0
  285. package/ecagent/src/harness/utils/truncate.ts +344 -0
  286. package/ecagent/src/index.ts +46 -0
  287. package/ecagent/src/node.ts +2 -0
  288. package/ecagent/src/proxy.ts +367 -0
  289. package/ecagent/src/runtime/api/lazy.ts +70 -0
  290. package/ecagent/src/runtime/api/pi-messages.lazy.ts +4 -0
  291. package/ecagent/src/runtime/api/pi-messages.ts +436 -0
  292. package/ecagent/src/runtime/auth/context.ts +45 -0
  293. package/ecagent/src/runtime/auth/credential-store.ts +47 -0
  294. package/ecagent/src/runtime/auth/helpers.ts +46 -0
  295. package/ecagent/src/runtime/auth/resolve.ts +141 -0
  296. package/ecagent/src/runtime/auth/types.ts +182 -0
  297. package/ecagent/src/runtime/compat.ts +158 -0
  298. package/ecagent/src/runtime/index.ts +31 -0
  299. package/ecagent/src/runtime/models.ts +452 -0
  300. package/ecagent/src/runtime/oauth.ts +1 -0
  301. package/ecagent/src/runtime/providers/faux.ts +538 -0
  302. package/ecagent/src/runtime/types.ts +718 -0
  303. package/ecagent/src/runtime/utils/diagnostics.ts +45 -0
  304. package/ecagent/src/runtime/utils/event-stream.ts +88 -0
  305. package/ecagent/src/runtime/utils/headers.ts +18 -0
  306. package/ecagent/src/runtime/utils/json-parse.ts +124 -0
  307. package/ecagent/src/runtime/utils/oauth/types.ts +79 -0
  308. package/ecagent/src/runtime/utils/overflow.ts +165 -0
  309. package/ecagent/src/runtime/utils/provider-env.ts +52 -0
  310. package/ecagent/src/runtime/utils/retry.ts +101 -0
  311. package/ecagent/src/runtime/utils/typebox-helpers.ts +24 -0
  312. package/ecagent/src/runtime/utils/validation.ts +310 -0
  313. package/ecagent/src/types.ts +430 -0
  314. package/ecagent/tsconfig.build.json +32 -0
  315. package/kits/schemas/_meta.json +7 -4
  316. package/kits/schemas/agent-config.schema.10.json +370 -0
  317. package/kits/schemas/defaults.schema.4.json +93 -0
  318. package/kits/schemas/relation-config.schema.8.json +69 -0
  319. package/kits/templates/roles/admin.json +1 -1
  320. package/package.json +22 -6
  321. package/skills/eclink/SKILL.md +70 -0
  322. package/skills/eclink/agents/openai.yaml +4 -0
  323. package/assets/.env.template +0 -4
@@ -0,0 +1,307 @@
1
+ /**
2
+ * pi-messages API implementation.
3
+ *
4
+ * Streams pi's own message protocol directly to a backend: the request is a
5
+ * single POST of `{ model, context, options }` to `<baseUrl>/messages`, the
6
+ * response is an SSE stream of serialized assistant-message events plus a
7
+ * terminal `done`/`error` event. This is the wire protocol spoken by the
8
+ * Radius gateway, but any backend implementing it can be used, e.g. via a
9
+ * models.json custom provider with `"api": "pi-messages"`.
10
+ */
11
+ import { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic } from "../utils/diagnostics.js";
12
+ import { AssistantMessageEventStream } from "../utils/event-stream.js";
13
+ import { headersToRecord, providerHeadersToRecord } from "../utils/headers.js";
14
+ import { parseStreamingJson } from "../utils/json-parse.js";
15
+ import { getProviderEnvValue } from "../utils/provider-env.js";
16
+ export class PiMessagesResponseError extends Error {
17
+ constructor(message, code, diagnosticDetails) {
18
+ super(message);
19
+ this.name = "PiMessagesResponseError";
20
+ this.code = code;
21
+ this.diagnosticDetails = diagnosticDetails;
22
+ }
23
+ }
24
+ function isRecord(value) {
25
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26
+ }
27
+ function parsePiMessagesErrorBody(body) {
28
+ try {
29
+ const parsed = JSON.parse(body);
30
+ return isRecord(parsed) && isRecord(parsed.error) ? parsed : undefined;
31
+ }
32
+ catch {
33
+ return undefined;
34
+ }
35
+ }
36
+ function truncateDiagnosticString(value) {
37
+ const maxLength = 8192;
38
+ return value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;
39
+ }
40
+ function formatPiMessagesResponseError(response, body, errorBody) {
41
+ const message = typeof errorBody?.error?.message === "string" ? errorBody.error.message : undefined;
42
+ const code = typeof errorBody?.error?.code === "string" ? errorBody.error.code : undefined;
43
+ const suffix = message ?? body;
44
+ const codeSuffix = code ? ` (${code})` : "";
45
+ return `${response.status} ${response.statusText}: ${suffix}${codeSuffix}`;
46
+ }
47
+ function createPiMessagesResponseError(model, url, response, body) {
48
+ const errorBody = parsePiMessagesErrorBody(body);
49
+ const code = typeof errorBody?.error?.code === "string" ? errorBody.error.code : undefined;
50
+ return new PiMessagesResponseError(formatPiMessagesResponseError(response, body, errorBody), code, {
51
+ version: 1,
52
+ provider: model.provider,
53
+ model: model.id,
54
+ url: url.toString(),
55
+ status: response.status,
56
+ statusText: response.statusText,
57
+ error: errorBody?.error,
58
+ body: errorBody ? undefined : truncateDiagnosticString(body),
59
+ timestampMs: Date.now(),
60
+ });
61
+ }
62
+ function createEmptyUsage() {
63
+ return {
64
+ input: 0,
65
+ output: 0,
66
+ cacheRead: 0,
67
+ cacheWrite: 0,
68
+ totalTokens: 0,
69
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
70
+ };
71
+ }
72
+ function appendRewriteDiagnostic(message, rewrite) {
73
+ if (!rewrite) {
74
+ return;
75
+ }
76
+ appendAssistantMessageDiagnostic(message, {
77
+ type: "pi_messages_rewrite",
78
+ timestamp: Date.now(),
79
+ details: { ...rewrite },
80
+ });
81
+ }
82
+ function createEventConverter(model) {
83
+ const partial = {
84
+ role: "assistant",
85
+ content: [],
86
+ api: model.api,
87
+ provider: model.provider,
88
+ model: model.id,
89
+ usage: createEmptyUsage(),
90
+ stopReason: "stop",
91
+ timestamp: Date.now(),
92
+ };
93
+ const toolJson = new Map();
94
+ return (event) => {
95
+ switch (event.type) {
96
+ case "done":
97
+ Object.assign(partial, {
98
+ stopReason: event.reason,
99
+ usage: event.usage,
100
+ responseId: event.responseId,
101
+ });
102
+ appendRewriteDiagnostic(partial, event.rewrite);
103
+ return { type: "done", reason: event.reason, message: partial };
104
+ case "error":
105
+ Object.assign(partial, {
106
+ stopReason: event.reason,
107
+ usage: event.usage,
108
+ errorMessage: event.errorMessage,
109
+ responseId: event.responseId,
110
+ });
111
+ appendRewriteDiagnostic(partial, event.rewrite);
112
+ return { type: "error", reason: event.reason, error: partial };
113
+ case "start":
114
+ break;
115
+ case "text_start":
116
+ partial.content[event.contentIndex] = { type: "text", text: "" };
117
+ break;
118
+ case "text_delta":
119
+ partial.content[event.contentIndex].text += event.delta;
120
+ break;
121
+ case "text_end":
122
+ Object.assign(partial.content[event.contentIndex], {
123
+ text: event.content,
124
+ textSignature: event.contentSignature,
125
+ });
126
+ break;
127
+ case "thinking_start":
128
+ partial.content[event.contentIndex] = { type: "thinking", thinking: "" };
129
+ break;
130
+ case "thinking_delta":
131
+ partial.content[event.contentIndex].thinking += event.delta;
132
+ break;
133
+ case "thinking_end":
134
+ Object.assign(partial.content[event.contentIndex], {
135
+ thinking: event.content,
136
+ thinkingSignature: event.contentSignature,
137
+ redacted: event.redacted,
138
+ });
139
+ break;
140
+ case "toolcall_start":
141
+ partial.content[event.contentIndex] = {
142
+ type: "toolCall",
143
+ id: event.id,
144
+ name: event.toolName,
145
+ arguments: {},
146
+ };
147
+ toolJson.set(event.contentIndex, "");
148
+ break;
149
+ case "toolcall_delta": {
150
+ const json = `${toolJson.get(event.contentIndex) ?? ""}${event.delta}`;
151
+ toolJson.set(event.contentIndex, json);
152
+ partial.content[event.contentIndex].arguments =
153
+ parseStreamingJson(json);
154
+ break;
155
+ }
156
+ case "toolcall_end":
157
+ Object.assign(partial.content[event.contentIndex], event.toolCall);
158
+ toolJson.delete(event.contentIndex);
159
+ return {
160
+ type: "toolcall_end",
161
+ contentIndex: event.contentIndex,
162
+ toolCall: partial.content[event.contentIndex],
163
+ partial,
164
+ };
165
+ }
166
+ return { ...event, partial };
167
+ };
168
+ }
169
+ async function* readPiMessagesEvents(stream) {
170
+ const decoder = new TextDecoder();
171
+ const reader = stream.getReader();
172
+ let buffer = "";
173
+ try {
174
+ while (true) {
175
+ const { done, value } = await reader.read();
176
+ buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
177
+ buffer = buffer.replace(/\r\n/g, "\n");
178
+ let split = buffer.indexOf("\n\n");
179
+ while (split !== -1) {
180
+ const event = parsePiMessagesEvent(buffer.slice(0, split));
181
+ if (event) {
182
+ yield event;
183
+ }
184
+ buffer = buffer.slice(split + 2);
185
+ split = buffer.indexOf("\n\n");
186
+ }
187
+ if (done) {
188
+ break;
189
+ }
190
+ }
191
+ if (buffer.trim()) {
192
+ const event = parsePiMessagesEvent(buffer);
193
+ if (event) {
194
+ yield event;
195
+ }
196
+ }
197
+ }
198
+ finally {
199
+ reader.releaseLock();
200
+ }
201
+ }
202
+ function parsePiMessagesEvent(raw) {
203
+ const data = raw
204
+ .split("\n")
205
+ .find((line) => line.startsWith("data:"))
206
+ ?.slice(5)
207
+ .trim();
208
+ return data && data !== "[DONE]" ? JSON.parse(data) : undefined;
209
+ }
210
+ function createErrorEvent(model, error, aborted) {
211
+ const reason = aborted ? "aborted" : "error";
212
+ const assistantMessage = {
213
+ role: "assistant",
214
+ content: [],
215
+ api: model.api,
216
+ provider: model.provider,
217
+ model: model.id,
218
+ usage: createEmptyUsage(),
219
+ stopReason: reason,
220
+ errorMessage: error instanceof Error ? error.message : String(error),
221
+ timestamp: Date.now(),
222
+ };
223
+ if (!aborted && error instanceof PiMessagesResponseError) {
224
+ appendAssistantMessageDiagnostic(assistantMessage, createAssistantMessageDiagnostic("pi_messages_response_failure", error, error.diagnosticDetails));
225
+ }
226
+ return { type: "error", reason, error: assistantMessage };
227
+ }
228
+ function resolveCacheRetention(cacheRetention, env) {
229
+ if (cacheRetention) {
230
+ return cacheRetention;
231
+ }
232
+ // Backend defaults apply when unset; only the legacy env opt-in is mapped.
233
+ return getProviderEnvValue("PI_CACHE_RETENTION", env) === "long" ? "long" : undefined;
234
+ }
235
+ export const stream = (model, context, options) => {
236
+ const eventStream = new AssistantMessageEventStream();
237
+ const convertEvent = createEventConverter(model);
238
+ void (async () => {
239
+ try {
240
+ const apiKey = options?.apiKey;
241
+ if (!apiKey) {
242
+ throw new Error(`No API key provided for provider "${model.provider}"`);
243
+ }
244
+ const url = new URL(`${model.baseUrl.replace(/\/+$/u, "")}/messages`);
245
+ if (options?.debug) {
246
+ url.searchParams.set("debug", "1");
247
+ }
248
+ let payload = {
249
+ model: model.id,
250
+ context,
251
+ options: {
252
+ temperature: options?.temperature,
253
+ maxTokens: options?.maxTokens,
254
+ reasoning: options?.reasoning,
255
+ cacheRetention: resolveCacheRetention(options?.cacheRetention, options?.env),
256
+ sessionId: options?.sessionId,
257
+ toolChoice: options?.toolChoice,
258
+ },
259
+ };
260
+ const nextPayload = await options?.onPayload?.(payload, model);
261
+ if (nextPayload !== undefined) {
262
+ payload = nextPayload;
263
+ }
264
+ const response = await fetch(url, {
265
+ method: "POST",
266
+ headers: {
267
+ authorization: `Bearer ${apiKey}`,
268
+ accept: "text/event-stream",
269
+ "content-type": "application/json",
270
+ ...providerHeadersToRecord(options?.headers),
271
+ },
272
+ body: JSON.stringify(payload),
273
+ signal: options?.signal,
274
+ });
275
+ await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
276
+ if (!response.ok) {
277
+ const body = await response.text();
278
+ throw createPiMessagesResponseError(model, url, response, body);
279
+ }
280
+ if (!response.body) {
281
+ throw new Error(`${model.provider} response has no body`);
282
+ }
283
+ for await (const piEvent of readPiMessagesEvents(response.body)) {
284
+ const event = convertEvent(piEvent);
285
+ eventStream.push(event);
286
+ if (event.type === "done" || event.type === "error") {
287
+ return;
288
+ }
289
+ }
290
+ throw new Error(`${model.provider} stream ended without a terminal event`);
291
+ }
292
+ catch (error) {
293
+ eventStream.push(createErrorEvent(model, error, options?.signal?.aborted ?? false));
294
+ }
295
+ })();
296
+ return eventStream;
297
+ };
298
+ export const streamSimple = (model, context, options) => {
299
+ const extra = options;
300
+ return stream(model, context, {
301
+ ...options,
302
+ reasoning: options?.reasoning,
303
+ toolChoice: extra?.toolChoice,
304
+ debug: extra?.debug,
305
+ });
306
+ };
307
+ //# sourceMappingURL=pi-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-messages.js","sourceRoot":"","sources":["../../../src/runtime/api/pi-messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * pi-messages API implementation.\n *\n * Streams pi's own message protocol directly to a backend: the request is a\n * single POST of `{ model, context, options }` to `<baseUrl>/messages`, the\n * response is an SSE stream of serialized assistant-message events plus a\n * terminal `done`/`error` event. This is the wire protocol spoken by the\n * Radius gateway, but any backend implementing it can be used, e.g. via a\n * models.json custom provider with `\"api\": \"pi-messages\"`.\n */\n\nimport type {\n\tAssistantMessage,\n\tAssistantMessageEvent,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tProviderEnv,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tThinkingLevel,\n\tToolCall,\n} from \"../types.ts\";\nimport { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic } from \"../utils/diagnostics.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord, providerHeadersToRecord } from \"../utils/headers.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\n\nexport interface PiMessagesOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\ttoolChoice?: \"auto\" | \"none\" | \"required\" | { type: \"function\"; function: { name: string } };\n\t/** Ask the backend for debug metadata (e.g. routing response headers). */\n\tdebug?: boolean;\n}\n\ntype PiMessagesUsage = AssistantMessage[\"usage\"];\ntype PiMessagesStopReason = AssistantMessage[\"stopReason\"];\n\n/** Impact summary of a server-side message rewrite (e.g. a gateway policy). */\nexport type PiMessagesRewriteImpact = {\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tchanged: boolean;\n\ttokenCountChange: number;\n\tmessageCountChange: number;\n\tsystemPromptChanged: boolean;\n};\n\n/** Serialized assistant-message event as sent by a pi-messages backend. */\nexport type PiMessagesEvent =\n\t| { type: \"start\" }\n\t| { type: \"text_start\"; contentIndex: number }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string }\n\t| { type: \"text_end\"; contentIndex: number; content: string; contentSignature?: string }\n\t| { type: \"thinking_start\"; contentIndex: number }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string }\n\t| {\n\t\t\ttype: \"thinking_end\";\n\t\t\tcontentIndex: number;\n\t\t\tcontent: string;\n\t\t\tcontentSignature?: string;\n\t\t\tredacted?: boolean;\n\t }\n\t| { type: \"toolcall_start\"; contentIndex: number; id: string; toolName: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall }\n\t| {\n\t\t\ttype: \"done\";\n\t\t\treason: Extract<PiMessagesStopReason, \"stop\" | \"length\" | \"toolUse\">;\n\t\t\tusage: PiMessagesUsage;\n\t\t\tresponseId?: string;\n\t\t\trewrite?: PiMessagesRewriteImpact;\n\t }\n\t| {\n\t\t\ttype: \"error\";\n\t\t\treason: Extract<PiMessagesStopReason, \"aborted\" | \"error\">;\n\t\t\tusage: PiMessagesUsage;\n\t\t\terrorMessage?: string;\n\t\t\tresponseId?: string;\n\t\t\trewrite?: PiMessagesRewriteImpact;\n\t };\n\ntype PiMessagesErrorBody = {\n\terror?: {\n\t\tmessage?: unknown;\n\t\tcode?: unknown;\n\t\tdetails?: unknown;\n\t\t[key: string]: unknown;\n\t};\n};\n\nexport class PiMessagesResponseError extends Error {\n\tcode?: string;\n\treadonly diagnosticDetails: Record<string, unknown>;\n\n\tconstructor(message: string, code: string | undefined, diagnosticDetails: Record<string, unknown>) {\n\t\tsuper(message);\n\t\tthis.name = \"PiMessagesResponseError\";\n\t\tthis.code = code;\n\t\tthis.diagnosticDetails = diagnosticDetails;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parsePiMessagesErrorBody(body: string): PiMessagesErrorBody | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(body) as unknown;\n\t\treturn isRecord(parsed) && isRecord(parsed.error) ? (parsed as PiMessagesErrorBody) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction truncateDiagnosticString(value: string): string {\n\tconst maxLength = 8192;\n\treturn value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;\n}\n\nfunction formatPiMessagesResponseError(\n\tresponse: Response,\n\tbody: string,\n\terrorBody: PiMessagesErrorBody | undefined,\n): string {\n\tconst message = typeof errorBody?.error?.message === \"string\" ? errorBody.error.message : undefined;\n\tconst code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n\tconst suffix = message ?? body;\n\tconst codeSuffix = code ? ` (${code})` : \"\";\n\treturn `${response.status} ${response.statusText}: ${suffix}${codeSuffix}`;\n}\n\nfunction createPiMessagesResponseError(\n\tmodel: Model<\"pi-messages\">,\n\turl: URL,\n\tresponse: Response,\n\tbody: string,\n): PiMessagesResponseError {\n\tconst errorBody = parsePiMessagesErrorBody(body);\n\tconst code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n\treturn new PiMessagesResponseError(formatPiMessagesResponseError(response, body, errorBody), code, {\n\t\tversion: 1,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\turl: url.toString(),\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\terror: errorBody?.error,\n\t\tbody: errorBody ? undefined : truncateDiagnosticString(body),\n\t\ttimestampMs: Date.now(),\n\t});\n}\n\nfunction createEmptyUsage(): PiMessagesUsage {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\n\nfunction appendRewriteDiagnostic(message: AssistantMessage, rewrite: PiMessagesRewriteImpact | undefined): void {\n\tif (!rewrite) {\n\t\treturn;\n\t}\n\tappendAssistantMessageDiagnostic(message, {\n\t\ttype: \"pi_messages_rewrite\",\n\t\ttimestamp: Date.now(),\n\t\tdetails: { ...rewrite },\n\t});\n}\n\nfunction createEventConverter(model: Model<\"pi-messages\">) {\n\tconst partial: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\tconst toolJson = new Map<number, string>();\n\n\treturn (event: PiMessagesEvent): AssistantMessageEvent => {\n\t\tswitch (event.type) {\n\t\t\tcase \"done\":\n\t\t\t\tObject.assign(partial, {\n\t\t\t\t\tstopReason: event.reason,\n\t\t\t\t\tusage: event.usage,\n\t\t\t\t\tresponseId: event.responseId,\n\t\t\t\t});\n\t\t\t\tappendRewriteDiagnostic(partial, event.rewrite);\n\t\t\t\treturn { type: \"done\", reason: event.reason, message: partial };\n\t\t\tcase \"error\":\n\t\t\t\tObject.assign(partial, {\n\t\t\t\t\tstopReason: event.reason,\n\t\t\t\t\tusage: event.usage,\n\t\t\t\t\terrorMessage: event.errorMessage,\n\t\t\t\t\tresponseId: event.responseId,\n\t\t\t\t});\n\t\t\t\tappendRewriteDiagnostic(partial, event.rewrite);\n\t\t\t\treturn { type: \"error\", reason: event.reason, error: partial };\n\t\t\tcase \"start\":\n\t\t\t\tbreak;\n\t\t\tcase \"text_start\":\n\t\t\t\tpartial.content[event.contentIndex] = { type: \"text\", text: \"\" };\n\t\t\t\tbreak;\n\t\t\tcase \"text_delta\":\n\t\t\t\t(partial.content[event.contentIndex] as { text: string }).text += event.delta;\n\t\t\t\tbreak;\n\t\t\tcase \"text_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, {\n\t\t\t\t\ttext: event.content,\n\t\t\t\t\ttextSignature: event.contentSignature,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_start\":\n\t\t\t\tpartial.content[event.contentIndex] = { type: \"thinking\", thinking: \"\" };\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_delta\":\n\t\t\t\t(partial.content[event.contentIndex] as { thinking: string }).thinking += event.delta;\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, {\n\t\t\t\t\tthinking: event.content,\n\t\t\t\t\tthinkingSignature: event.contentSignature,\n\t\t\t\t\tredacted: event.redacted,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"toolcall_start\":\n\t\t\t\tpartial.content[event.contentIndex] = {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\tid: event.id,\n\t\t\t\t\tname: event.toolName,\n\t\t\t\t\targuments: {},\n\t\t\t\t};\n\t\t\t\ttoolJson.set(event.contentIndex, \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"toolcall_delta\": {\n\t\t\t\tconst json = `${toolJson.get(event.contentIndex) ?? \"\"}${event.delta}`;\n\t\t\t\ttoolJson.set(event.contentIndex, json);\n\t\t\t\t(partial.content[event.contentIndex] as ToolCall).arguments =\n\t\t\t\t\tparseStreamingJson<ToolCall[\"arguments\"]>(json);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, event.toolCall);\n\t\t\t\ttoolJson.delete(event.contentIndex);\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\tcontentIndex: event.contentIndex,\n\t\t\t\t\ttoolCall: partial.content[event.contentIndex] as ToolCall,\n\t\t\t\t\tpartial,\n\t\t\t\t};\n\t\t}\n\n\t\treturn { ...event, partial } as AssistantMessageEvent;\n\t};\n}\n\nasync function* readPiMessagesEvents(stream: ReadableStream<Uint8Array>): AsyncGenerator<PiMessagesEvent> {\n\tconst decoder = new TextDecoder();\n\tconst reader = stream.getReader();\n\tlet buffer = \"\";\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tbuffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n\t\t\tbuffer = buffer.replace(/\\r\\n/g, \"\\n\");\n\n\t\t\tlet split = buffer.indexOf(\"\\n\\n\");\n\t\t\twhile (split !== -1) {\n\t\t\t\tconst event = parsePiMessagesEvent(buffer.slice(0, split));\n\t\t\t\tif (event) {\n\t\t\t\t\tyield event;\n\t\t\t\t}\n\t\t\t\tbuffer = buffer.slice(split + 2);\n\t\t\t\tsplit = buffer.indexOf(\"\\n\\n\");\n\t\t\t}\n\n\t\t\tif (done) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (buffer.trim()) {\n\t\t\tconst event = parsePiMessagesEvent(buffer);\n\t\t\tif (event) {\n\t\t\t\tyield event;\n\t\t\t}\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nfunction parsePiMessagesEvent(raw: string): PiMessagesEvent | undefined {\n\tconst data = raw\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.startsWith(\"data:\"))\n\t\t?.slice(5)\n\t\t.trim();\n\n\treturn data && data !== \"[DONE]\" ? (JSON.parse(data) as PiMessagesEvent) : undefined;\n}\n\nfunction createErrorEvent(model: Model<\"pi-messages\">, error: unknown, aborted: boolean): AssistantMessageEvent {\n\tconst reason = aborted ? \"aborted\" : \"error\";\n\tconst assistantMessage: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: reason,\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n\n\tif (!aborted && error instanceof PiMessagesResponseError) {\n\t\tappendAssistantMessageDiagnostic(\n\t\t\tassistantMessage,\n\t\t\tcreateAssistantMessageDiagnostic(\"pi_messages_response_failure\", error, error.diagnosticDetails),\n\t\t);\n\t}\n\n\treturn { type: \"error\", reason, error: assistantMessage };\n}\n\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention | undefined {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\t// Backend defaults apply when unset; only the legacy env opt-in is mapped.\n\treturn getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\" ? \"long\" : undefined;\n}\n\nexport const stream: StreamFunction<\"pi-messages\", PiMessagesOptions> = (\n\tmodel: Model<\"pi-messages\">,\n\tcontext: Context,\n\toptions?: PiMessagesOptions,\n): AssistantMessageEventStream => {\n\tconst eventStream = new AssistantMessageEventStream();\n\tconst convertEvent = createEventConverter(model);\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key provided for provider \"${model.provider}\"`);\n\t\t\t}\n\n\t\t\tconst url = new URL(`${model.baseUrl.replace(/\\/+$/u, \"\")}/messages`);\n\t\t\tif (options?.debug) {\n\t\t\t\turl.searchParams.set(\"debug\", \"1\");\n\t\t\t}\n\n\t\t\tlet payload: unknown = {\n\t\t\t\tmodel: model.id,\n\t\t\t\tcontext,\n\t\t\t\toptions: {\n\t\t\t\t\ttemperature: options?.temperature,\n\t\t\t\t\tmaxTokens: options?.maxTokens,\n\t\t\t\t\treasoning: options?.reasoning,\n\t\t\t\t\tcacheRetention: resolveCacheRetention(options?.cacheRetention, options?.env),\n\t\t\t\t\tsessionId: options?.sessionId,\n\t\t\t\t\ttoolChoice: options?.toolChoice,\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst nextPayload = await options?.onPayload?.(payload, model);\n\t\t\tif (nextPayload !== undefined) {\n\t\t\t\tpayload = nextPayload;\n\t\t\t}\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tauthorization: `Bearer ${apiKey}`,\n\t\t\t\t\taccept: \"text/event-stream\",\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t...providerHeadersToRecord(options?.headers),\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\tsignal: options?.signal,\n\t\t\t});\n\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst body = await response.text();\n\t\t\t\tthrow createPiMessagesResponseError(model, url, response, body);\n\t\t\t}\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new Error(`${model.provider} response has no body`);\n\t\t\t}\n\n\t\t\tfor await (const piEvent of readPiMessagesEvents(response.body)) {\n\t\t\t\tconst event = convertEvent(piEvent);\n\t\t\t\teventStream.push(event);\n\t\t\t\tif (event.type === \"done\" || event.type === \"error\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow new Error(`${model.provider} stream ended without a terminal event`);\n\t\t} catch (error) {\n\t\t\teventStream.push(createErrorEvent(model, error, options?.signal?.aborted ?? false));\n\t\t}\n\t})();\n\n\treturn eventStream;\n};\n\nexport const streamSimple: StreamFunction<\"pi-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"pi-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst extra = options as PiMessagesOptions | undefined;\n\treturn stream(model, context, {\n\t\t...options,\n\t\treasoning: options?.reasoning,\n\t\ttoolChoice: extra?.toolChoice,\n\t\tdebug: extra?.debug,\n\t});\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ProviderStreams } from "../types.ts";
2
+ export declare const piMessagesApi: () => ProviderStreams;
3
+ //# sourceMappingURL=pi-messages.lazy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-messages.lazy.d.ts","sourceRoot":"","sources":["../../../src/runtime/api/pi-messages.lazy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,eAAO,MAAM,aAAa,QAAO,eAA4D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { lazyApi } from "./lazy.js";
2
+ export const piMessagesApi = () => lazyApi(() => import("./pi-messages.js"));
3
+ //# sourceMappingURL=pi-messages.lazy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-messages.lazy.js","sourceRoot":"","sources":["../../../src/runtime/api/pi-messages.lazy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAoB,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC","sourcesContent":["import type { ProviderStreams } from \"../types.ts\";\nimport { lazyApi } from \"./lazy.ts\";\n\nexport const piMessagesApi = (): ProviderStreams => lazyApi(() => import(\"./pi-messages.ts\"));\n"]}
@@ -0,0 +1,7 @@
1
+ import type { AuthContext } from "./types.ts";
2
+ /**
3
+ * Default auth context: env vars from `process.env` (undefined in browsers),
4
+ * file existence via node:fs (always false in browsers).
5
+ */
6
+ export declare function defaultProviderAuthContext(): AuthContext;
7
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkB9C;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,WAAW,CAsBxD"}
@@ -0,0 +1,42 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ // Variable specifier so browser bundlers do not try to resolve node builtins.
10
+ const importNodeModule = (specifier) => import(__rewriteRelativeImportExtension(specifier));
11
+ function getProcessEnv() {
12
+ const proc = globalThis.process;
13
+ return proc?.env;
14
+ }
15
+ /**
16
+ * Default auth context: env vars from `process.env` (undefined in browsers),
17
+ * file existence via node:fs (always false in browsers).
18
+ */
19
+ export function defaultProviderAuthContext() {
20
+ return {
21
+ async env(name) {
22
+ const value = getProcessEnv()?.[name];
23
+ return typeof value === "string" && value.trim().length > 0 ? value : undefined;
24
+ },
25
+ async fileExists(path) {
26
+ try {
27
+ const fs = (await importNodeModule("node:fs/promises"));
28
+ let resolved = path;
29
+ if (resolved.startsWith("~")) {
30
+ const os = (await importNodeModule("node:os"));
31
+ resolved = os.homedir() + resolved.slice(1);
32
+ }
33
+ await fs.access(resolved);
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ },
40
+ };
41
+ }
42
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/runtime/auth/context.ts"],"names":[],"mappings":";;;;;;;;AAUA,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAoB,EAAE,CAAC,MAAM,kCAAC,SAAS,EAAC,CAAC;AAEpF,SAAS,aAAa;IACrB,MAAM,IAAI,GAAI,UAAyE,CAAC,OAAO,CAAC;IAChG,OAAO,IAAI,EAAE,GAAG,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B;IACzC,OAAO;QACN,KAAK,CAAC,GAAG,CAAC,IAAY;YACrB,MAAM,KAAK,GAAG,aAAa,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;YACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACjF,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,IAAY;YAC5B,IAAI,CAAC;gBACJ,MAAM,EAAE,GAAG,CAAC,MAAM,gBAAgB,CAAC,kBAAkB,CAAC,CAAiB,CAAC;gBACxE,IAAI,QAAQ,GAAG,IAAI,CAAC;gBACpB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAiB,CAAC;oBAC/D,QAAQ,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC7C,CAAC;gBACD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import type { AuthContext } from \"./types.ts\";\n\ninterface NodeFsModule {\n\taccess(path: string): Promise<void>;\n}\n\ninterface NodeOsModule {\n\thomedir(): string;\n}\n\n// Variable specifier so browser bundlers do not try to resolve node builtins.\nconst importNodeModule = (specifier: string): Promise<unknown> => import(specifier);\n\nfunction getProcessEnv(): Record<string, string | undefined> | undefined {\n\tconst proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n\treturn proc?.env;\n}\n\n/**\n * Default auth context: env vars from `process.env` (undefined in browsers),\n * file existence via node:fs (always false in browsers).\n */\nexport function defaultProviderAuthContext(): AuthContext {\n\treturn {\n\t\tasync env(name: string): Promise<string | undefined> {\n\t\t\tconst value = getProcessEnv()?.[name];\n\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : undefined;\n\t\t},\n\n\t\tasync fileExists(path: string): Promise<boolean> {\n\t\t\ttry {\n\t\t\t\tconst fs = (await importNodeModule(\"node:fs/promises\")) as NodeFsModule;\n\t\t\t\tlet resolved = path;\n\t\t\t\tif (resolved.startsWith(\"~\")) {\n\t\t\t\t\tconst os = (await importNodeModule(\"node:os\")) as NodeOsModule;\n\t\t\t\t\tresolved = os.homedir() + resolved.slice(1);\n\t\t\t\t}\n\t\t\t\tawait fs.access(resolved);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { Credential, CredentialStore } from "./types.ts";
2
+ /**
3
+ * Default in-memory credential store. Apps inject persistent stores.
4
+ * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
5
+ * Writes are serialized per provider through a promise chain.
6
+ */
7
+ export declare class InMemoryCredentialStore implements CredentialStore {
8
+ private credentials;
9
+ private chains;
10
+ /** Serialize tasks per provider id. */
11
+ private enqueue;
12
+ read(providerId: string): Promise<Credential | undefined>;
13
+ modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
14
+ delete(providerId: string): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=credential-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC9D,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,MAAM,CAAuC;IAErD,uCAAuC;IACvC,OAAO,CAAC,OAAO;IAaT,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI/D,MAAM,CACL,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GACtE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IASlC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKzC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Default in-memory credential store. Apps inject persistent stores.
3
+ * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
4
+ * Writes are serialized per provider through a promise chain.
5
+ */
6
+ export class InMemoryCredentialStore {
7
+ constructor() {
8
+ this.credentials = new Map();
9
+ this.chains = new Map();
10
+ }
11
+ /** Serialize tasks per provider id. */
12
+ enqueue(providerId, task) {
13
+ const previous = this.chains.get(providerId) ?? Promise.resolve();
14
+ const next = (async () => {
15
+ await previous.catch(() => { });
16
+ return task();
17
+ })();
18
+ this.chains.set(providerId, next.catch(() => { }));
19
+ return next;
20
+ }
21
+ async read(providerId) {
22
+ return this.credentials.get(providerId);
23
+ }
24
+ modify(providerId, fn) {
25
+ return this.enqueue(providerId, async () => {
26
+ const current = this.credentials.get(providerId);
27
+ const next = await fn(current);
28
+ if (next !== undefined)
29
+ this.credentials.set(providerId, next);
30
+ return next ?? current;
31
+ });
32
+ }
33
+ delete(providerId) {
34
+ return this.enqueue(providerId, async () => {
35
+ this.credentials.delete(providerId);
36
+ });
37
+ }
38
+ }
39
+ //# sourceMappingURL=credential-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../../src/runtime/auth/credential-store.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IAApC;QACS,gBAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;QAC5C,WAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAqCtD,CAAC;IAnCA,uCAAuC;IAC/B,OAAO,CAAI,UAAkB,EAAE,IAAsB;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC/B,OAAO,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,MAAM,CAAC,GAAG,CACd,UAAU,EACV,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CACpB,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CACL,UAAkB,EAClB,EAAwE;QAExE,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/B,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC/D,OAAO,IAAI,IAAI,OAAO,CAAC;QACxB,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAkB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;YAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["import type { Credential, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>): Promise<T> {\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst next = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\treturn task();\n\t\t})();\n\t\tthis.chains.set(\n\t\t\tproviderId,\n\t\t\tnext.catch(() => {}),\n\t\t);\n\t\treturn next;\n\t}\n\n\tasync read(providerId: string): Promise<Credential | undefined> {\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tconst current = this.credentials.get(providerId);\n\t\t\tconst next = await fn(current);\n\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\treturn next ?? current;\n\t\t});\n\t}\n\n\tdelete(providerId: string): Promise<void> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tthis.credentials.delete(providerId);\n\t\t});\n\t}\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import type { ApiKeyAuth, OAuthAuth } from "./types.ts";
2
+ /**
3
+ * Standard api-key auth: a stored credential key wins, otherwise the first
4
+ * set env var resolves. Includes a `login` that prompts for the key.
5
+ * Providers with non-standard resolution (provider env, ambient files, IAM)
6
+ * write their own `ApiKeyAuth`.
7
+ */
8
+ export declare function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth;
9
+ /**
10
+ * Wraps a dynamically imported `OAuthAuth` so provider definitions can
11
+ * advertise OAuth without importing the implementation. The flow loads on
12
+ * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out
13
+ * of bundles by loading through a bundler-opaque dynamic import (variable
14
+ * specifier, see the bedrock lazy wrapper).
15
+ */
16
+ export declare function lazyOAuth(input: {
17
+ name: string;
18
+ load: () => Promise<OAuthAuth>;
19
+ }): OAuthAuth;
20
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAgBlF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,SAAS,CAY5F"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Standard api-key auth: a stored credential key wins, otherwise the first
3
+ * set env var resolves. Includes a `login` that prompts for the key.
4
+ * Providers with non-standard resolution (provider env, ambient files, IAM)
5
+ * write their own `ApiKeyAuth`.
6
+ */
7
+ export function envApiKeyAuth(name, envVars) {
8
+ return {
9
+ name,
10
+ login: async (callbacks) => {
11
+ const key = await callbacks.prompt({ type: "secret", message: `Enter ${name}` });
12
+ return { type: "api_key", key };
13
+ },
14
+ resolve: async ({ ctx, credential }) => {
15
+ if (credential?.key)
16
+ return { auth: { apiKey: credential.key }, source: "stored credential" };
17
+ for (const envVar of envVars) {
18
+ const value = await ctx.env(envVar);
19
+ if (value)
20
+ return { auth: { apiKey: value }, source: envVar };
21
+ }
22
+ return undefined;
23
+ },
24
+ };
25
+ }
26
+ /**
27
+ * Wraps a dynamically imported `OAuthAuth` so provider definitions can
28
+ * advertise OAuth without importing the implementation. The flow loads on
29
+ * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out
30
+ * of bundles by loading through a bundler-opaque dynamic import (variable
31
+ * specifier, see the bedrock lazy wrapper).
32
+ */
33
+ export function lazyOAuth(input) {
34
+ let promise;
35
+ const loaded = () => {
36
+ promise ??= input.load();
37
+ return promise;
38
+ };
39
+ return {
40
+ name: input.name,
41
+ login: async (callbacks) => (await loaded()).login(callbacks),
42
+ refresh: async (credential) => (await loaded()).refresh(credential),
43
+ toAuth: async (credential) => (await loaded()).toAuth(credential),
44
+ };
45
+ }
46
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/runtime/auth/helpers.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAA0B;IACrE,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;YAC1B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;YACjF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE;YACtC,IAAI,UAAU,EAAE,GAAG;gBAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;YAC9F,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,KAAK;oBAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC/D,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAAuD;IAChF,IAAI,OAAuC,CAAC;IAC5C,MAAM,MAAM,GAAG,GAAG,EAAE;QACnB,OAAO,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC;IACF,OAAO;QACN,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;QAC7D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACnE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;KACjE,CAAC;AACH,CAAC","sourcesContent":["import type { ApiKeyAuth, OAuthAuth } from \"./types.ts\";\n\n/**\n * Standard api-key auth: a stored credential key wins, otherwise the first\n * set env var resolves. Includes a `login` that prompts for the key.\n * Providers with non-standard resolution (provider env, ambient files, IAM)\n * write their own `ApiKeyAuth`.\n */\nexport function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth {\n\treturn {\n\t\tname,\n\t\tlogin: async (callbacks) => {\n\t\t\tconst key = await callbacks.prompt({ type: \"secret\", message: `Enter ${name}` });\n\t\t\treturn { type: \"api_key\", key };\n\t\t},\n\t\tresolve: async ({ ctx, credential }) => {\n\t\t\tif (credential?.key) return { auth: { apiKey: credential.key }, source: \"stored credential\" };\n\t\t\tfor (const envVar of envVars) {\n\t\t\t\tconst value = await ctx.env(envVar);\n\t\t\t\tif (value) return { auth: { apiKey: value }, source: envVar };\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\n/**\n * Wraps a dynamically imported `OAuthAuth` so provider definitions can\n * advertise OAuth without importing the implementation. The flow loads on\n * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out\n * of bundles by loading through a bundler-opaque dynamic import (variable\n * specifier, see the bedrock lazy wrapper).\n */\nexport function lazyOAuth(input: { name: string; load: () => Promise<OAuthAuth> }): OAuthAuth {\n\tlet promise: Promise<OAuthAuth> | undefined;\n\tconst loaded = () => {\n\t\tpromise ??= input.load();\n\t\treturn promise;\n\t};\n\treturn {\n\t\tname: input.name,\n\t\tlogin: async (callbacks) => (await loaded()).login(callbacks),\n\t\trefresh: async (credential) => (await loaded()).refresh(credential),\n\t\ttoAuth: async (credential) => (await loaded()).toAuth(credential),\n\t};\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import type { Api, ImagesApi, ImagesModel, Model, ProviderEnv } from "../types.ts";
2
+ import type { AuthContext, AuthResult, CredentialStore, ProviderAuth } from "./types.ts";
3
+ export type ModelsErrorCode = "model_source" | "model_validation" | "provider" | "stream" | "auth" | "oauth";
4
+ export interface AuthResolutionOverrides {
5
+ apiKey?: string;
6
+ env?: ProviderEnv;
7
+ }
8
+ export declare class ModelsError extends Error {
9
+ readonly code: ModelsErrorCode;
10
+ constructor(code: ModelsErrorCode, message: string, options?: {
11
+ cause?: unknown;
12
+ });
13
+ }
14
+ /** Model shape auth resolution receives: chat or image-generation models. */
15
+ export type AuthModel = Model<Api> | ImagesModel<ImagesApi>;
16
+ /**
17
+ * Auth resolution shared by the `Models` and `ImagesModels` collections.
18
+ * A stored credential owns the provider: ambient/env is consulted only when
19
+ * nothing is stored. No silent env fallback after a failed refresh or for a
20
+ * credential type without a matching handler.
21
+ */
22
+ export declare function resolveProviderAuth(provider: {
23
+ id: string;
24
+ auth: ProviderAuth;
25
+ }, model: AuthModel, credentials: CredentialStore, authContext: AuthContext, overrides?: AuthResolutionOverrides): Promise<AuthResult | undefined>;
26
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,KAAK,EAGX,WAAW,EACX,UAAU,EAEV,eAAe,EAGf,YAAY,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,kBAAkB,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7G,MAAM,WAAW,uBAAuB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,WAAW,CAAC;CAClB;AAED,qBAAa,WAAY,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;gBAEnB,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKjF;AAED,6EAA6E;AAC7E,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AAE5D;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACxC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,EAC5C,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,eAAe,EAC5B,WAAW,EAAE,WAAW,EACxB,SAAS,CAAC,EAAE,uBAAuB,GACjC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAyBjC"}