@elie-laloum/outpost 4.2.0 → 5.0.0

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 (450) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +5 -3
  3. package/dist/{cli/init-authentication.constants.js → adapters/agents/authentication.constants.js} +1 -1
  4. package/dist/adapters/agents/authentication.constants.js.map +1 -0
  5. package/dist/adapters/agents/authentication.d.ts +2 -0
  6. package/dist/adapters/agents/authentication.js +52 -0
  7. package/dist/adapters/agents/authentication.js.map +1 -0
  8. package/dist/adapters/agents/claude-adapter.d.ts +2 -2
  9. package/dist/adapters/agents/claude-adapter.js +30 -2
  10. package/dist/adapters/agents/claude-adapter.js.map +1 -1
  11. package/dist/adapters/agents/claude-request.d.ts +2 -2
  12. package/dist/adapters/agents/claude-request.js +3 -3
  13. package/dist/adapters/agents/claude-request.js.map +1 -1
  14. package/dist/adapters/agents/codex-adapter.d.ts +2 -2
  15. package/dist/adapters/agents/codex-adapter.js +17 -1
  16. package/dist/adapters/agents/codex-adapter.js.map +1 -1
  17. package/dist/adapters/agents/codex-provider.d.ts +2 -2
  18. package/dist/adapters/agents/codex-provider.js +1 -1
  19. package/dist/adapters/agents/codex-provider.js.map +1 -1
  20. package/dist/adapters/agents/codex-request.d.ts +2 -2
  21. package/dist/adapters/agents/codex-request.js +3 -3
  22. package/dist/adapters/agents/codex-request.js.map +1 -1
  23. package/dist/adapters/agents/gemini-adapter.d.ts +2 -2
  24. package/dist/adapters/agents/gemini-adapter.js +20 -1
  25. package/dist/adapters/agents/gemini-adapter.js.map +1 -1
  26. package/dist/adapters/agents/gemini-request.d.ts +2 -1
  27. package/dist/adapters/agents/gemini-request.js +1 -1
  28. package/dist/adapters/agents/gemini-request.js.map +1 -1
  29. package/dist/adapters/agents/gemini.types.d.ts +2 -1
  30. package/dist/adapters/agents/gemini.types.js.map +1 -1
  31. package/dist/adapters/agents/model-support.constants.d.ts +6 -0
  32. package/dist/adapters/agents/model-support.constants.js +18 -0
  33. package/dist/adapters/agents/model-support.constants.js.map +1 -0
  34. package/dist/adapters/agents/model-support.d.ts +4 -0
  35. package/dist/adapters/agents/model-support.js +11 -0
  36. package/dist/adapters/agents/model-support.js.map +1 -0
  37. package/dist/adapters/agents/settings.types.d.ts +11 -3
  38. package/dist/adapters/agents/settings.types.js.map +1 -1
  39. package/dist/adapters/models/anthropic-model-provider.constants.d.ts +3 -0
  40. package/dist/adapters/models/anthropic-model-provider.constants.js +17 -0
  41. package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -0
  42. package/dist/adapters/models/anthropic-model-provider.d.ts +3 -0
  43. package/dist/adapters/models/anthropic-model-provider.js +31 -0
  44. package/dist/adapters/models/anthropic-model-provider.js.map +1 -0
  45. package/dist/adapters/models/anthropic-model-provider.types.d.ts +7 -0
  46. package/dist/adapters/models/anthropic-model-provider.types.js +2 -0
  47. package/dist/adapters/models/anthropic-model-provider.types.js.map +1 -0
  48. package/dist/adapters/models/anthropic-request.d.ts +4 -0
  49. package/dist/adapters/models/anthropic-request.js +81 -0
  50. package/dist/adapters/models/anthropic-request.js.map +1 -0
  51. package/dist/adapters/models/anthropic-response.d.ts +3 -0
  52. package/dist/adapters/models/anthropic-response.js +55 -0
  53. package/dist/adapters/models/anthropic-response.js.map +1 -0
  54. package/dist/adapters/models/anthropic-stream.d.ts +2 -0
  55. package/dist/adapters/models/anthropic-stream.js +96 -0
  56. package/dist/adapters/models/anthropic-stream.js.map +1 -0
  57. package/dist/adapters/models/http-provider.d.ts +3 -0
  58. package/dist/adapters/models/http-provider.js +113 -0
  59. package/dist/adapters/models/http-provider.js.map +1 -0
  60. package/dist/adapters/models/{openai-http.js → model-http.js} +1 -1
  61. package/dist/adapters/models/model-http.js.map +1 -0
  62. package/dist/adapters/models/model-protocol.types.d.ts +41 -0
  63. package/dist/adapters/models/model-protocol.types.js +2 -0
  64. package/dist/adapters/models/model-protocol.types.js.map +1 -0
  65. package/dist/adapters/models/model-request.d.ts +2 -0
  66. package/dist/adapters/models/model-request.js +18 -0
  67. package/dist/adapters/models/model-request.js.map +1 -0
  68. package/dist/adapters/models/model-response.d.ts +7 -0
  69. package/dist/adapters/models/model-response.js +41 -0
  70. package/dist/adapters/models/model-response.js.map +1 -0
  71. package/dist/adapters/models/{openai-compatible.constants.js → model.constants.js} +6 -1
  72. package/dist/adapters/models/model.constants.js.map +1 -0
  73. package/dist/adapters/models/openai-chat-stream.d.ts +2 -0
  74. package/dist/adapters/models/openai-chat-stream.js +66 -0
  75. package/dist/adapters/models/openai-chat-stream.js.map +1 -0
  76. package/dist/adapters/models/openai-chat.d.ts +4 -0
  77. package/dist/adapters/models/openai-chat.js +108 -0
  78. package/dist/adapters/models/openai-chat.js.map +1 -0
  79. package/dist/adapters/models/openai-model-provider.d.ts +3 -0
  80. package/dist/adapters/models/openai-model-provider.js +13 -0
  81. package/dist/adapters/models/openai-model-provider.js.map +1 -0
  82. package/dist/adapters/models/openai-model-provider.types.d.ts +4 -0
  83. package/dist/adapters/models/openai-model-provider.types.js +2 -0
  84. package/dist/adapters/models/openai-model-provider.types.js.map +1 -0
  85. package/dist/adapters/models/openai-protocols.d.ts +2 -0
  86. package/dist/adapters/models/openai-protocols.js +22 -0
  87. package/dist/adapters/models/openai-protocols.js.map +1 -0
  88. package/dist/adapters/models/openai-responses-stream.d.ts +2 -0
  89. package/dist/adapters/models/openai-responses-stream.js +35 -0
  90. package/dist/adapters/models/openai-responses-stream.js.map +1 -0
  91. package/dist/adapters/models/openai-responses.d.ts +4 -0
  92. package/dist/adapters/models/openai-responses.js +107 -0
  93. package/dist/adapters/models/openai-responses.js.map +1 -0
  94. package/dist/adapters/models/openai-usage.d.ts +3 -0
  95. package/dist/adapters/models/openai-usage.js +20 -0
  96. package/dist/adapters/models/openai-usage.js.map +1 -0
  97. package/dist/adapters/models/stop-reasons.constants.d.ts +4 -0
  98. package/dist/adapters/models/stop-reasons.constants.js +19 -0
  99. package/dist/adapters/models/stop-reasons.constants.js.map +1 -0
  100. package/dist/adapters/models/stream-events.d.ts +3 -0
  101. package/dist/adapters/models/stream-events.js +22 -0
  102. package/dist/adapters/models/stream-events.js.map +1 -0
  103. package/dist/adapters/tools/edit-tools.d.ts +2 -0
  104. package/dist/adapters/tools/edit-tools.js +84 -0
  105. package/dist/adapters/tools/edit-tools.js.map +1 -0
  106. package/dist/adapters/tools/file-tools.d.ts +2 -0
  107. package/dist/adapters/tools/file-tools.js +97 -0
  108. package/dist/adapters/tools/file-tools.js.map +1 -0
  109. package/dist/adapters/tools/git-tools.d.ts +2 -0
  110. package/dist/adapters/tools/git-tools.js +54 -0
  111. package/dist/adapters/tools/git-tools.js.map +1 -0
  112. package/dist/adapters/tools/sandbox-files.d.ts +10 -0
  113. package/dist/adapters/tools/sandbox-files.js +60 -0
  114. package/dist/adapters/tools/sandbox-files.js.map +1 -0
  115. package/dist/adapters/tools/search-tools.d.ts +2 -0
  116. package/dist/adapters/tools/search-tools.js +65 -0
  117. package/dist/adapters/tools/search-tools.js.map +1 -0
  118. package/dist/adapters/tools/shell-tools.d.ts +3 -0
  119. package/dist/adapters/tools/shell-tools.js +38 -0
  120. package/dist/adapters/tools/shell-tools.js.map +1 -0
  121. package/dist/adapters/tools/tools.constants.d.ts +11 -0
  122. package/dist/adapters/tools/tools.constants.js +17 -0
  123. package/dist/adapters/tools/tools.constants.js.map +1 -0
  124. package/dist/adapters/tools/tools.types.d.ts +41 -0
  125. package/dist/adapters/tools/tools.types.js +2 -0
  126. package/dist/adapters/tools/tools.types.js.map +1 -0
  127. package/dist/application/activity-watchdog.js +15 -2
  128. package/dist/application/activity-watchdog.js.map +1 -1
  129. package/dist/application/agent-bootstrap.d.ts +2 -2
  130. package/dist/application/agent-bootstrap.js +2 -0
  131. package/dist/application/agent-bootstrap.js.map +1 -1
  132. package/dist/application/agent-storage.d.ts +3 -2
  133. package/dist/application/agent-storage.js +9 -2
  134. package/dist/application/agent-storage.js.map +1 -1
  135. package/dist/application/agent-turn.d.ts +3 -3
  136. package/dist/application/agent-turn.js +7 -1
  137. package/dist/application/agent-turn.js.map +1 -1
  138. package/dist/application/attach.js +1 -0
  139. package/dist/application/attach.js.map +1 -1
  140. package/dist/application/custom-turn.d.ts +5 -0
  141. package/dist/application/custom-turn.js +190 -0
  142. package/dist/application/custom-turn.js.map +1 -0
  143. package/dist/application/dispatch-observation.d.ts +3 -0
  144. package/dist/application/dispatch-observation.js +51 -0
  145. package/dist/application/dispatch-observation.js.map +1 -0
  146. package/dist/application/dispatch-observation.types.d.ts +5 -0
  147. package/dist/application/dispatch-observation.types.js +2 -0
  148. package/dist/application/dispatch-observation.types.js.map +1 -0
  149. package/dist/application/dispatch-validation.d.ts +2 -2
  150. package/dist/application/dispatch-validation.js.map +1 -1
  151. package/dist/application/dispatch.js +8 -3
  152. package/dist/application/dispatch.js.map +1 -1
  153. package/dist/application/doctor-image.js +3 -3
  154. package/dist/application/doctor-image.js.map +1 -1
  155. package/dist/application/doctor-protocol.js +9 -4
  156. package/dist/application/doctor-protocol.js.map +1 -1
  157. package/dist/application/doctor-sandbox.js +4 -4
  158. package/dist/application/doctor-sandbox.js.map +1 -1
  159. package/dist/application/doctor-sandbox.types.d.ts +2 -2
  160. package/dist/application/doctor-sandbox.types.js.map +1 -1
  161. package/dist/application/doctor.constants.d.ts +1 -1
  162. package/dist/application/doctor.constants.js +1 -1
  163. package/dist/application/doctor.constants.js.map +1 -1
  164. package/dist/application/doctor.js +10 -9
  165. package/dist/application/doctor.js.map +1 -1
  166. package/dist/application/doctor.types.d.ts +3 -3
  167. package/dist/application/doctor.types.js.map +1 -1
  168. package/dist/application/execution.d.ts +2 -2
  169. package/dist/application/execution.js +1 -1
  170. package/dist/application/execution.js.map +1 -1
  171. package/dist/application/execution.types.d.ts +9 -2
  172. package/dist/application/execution.types.js.map +1 -1
  173. package/dist/application/harness-context.d.ts +2 -0
  174. package/dist/application/harness-context.js +54 -0
  175. package/dist/application/harness-context.js.map +1 -0
  176. package/dist/application/harness-history.d.ts +3 -0
  177. package/dist/application/harness-history.js +17 -0
  178. package/dist/application/harness-history.js.map +1 -0
  179. package/dist/application/harness-hooks.d.ts +9 -0
  180. package/dist/application/harness-hooks.js +90 -0
  181. package/dist/application/harness-hooks.js.map +1 -0
  182. package/dist/application/harness-loop.d.ts +2 -0
  183. package/dist/application/harness-loop.js +132 -0
  184. package/dist/application/harness-loop.js.map +1 -0
  185. package/dist/application/harness.types.d.ts +55 -0
  186. package/dist/application/harness.types.js +2 -0
  187. package/dist/application/harness.types.js.map +1 -0
  188. package/dist/application/lifecycle.constants.d.ts +1 -1
  189. package/dist/application/lifecycle.constants.js +1 -1
  190. package/dist/application/lifecycle.constants.js.map +1 -1
  191. package/dist/application/outpost.types.d.ts +6 -6
  192. package/dist/application/outpost.types.js.map +1 -1
  193. package/dist/application/remote-download.js +1 -1
  194. package/dist/application/remote-download.js.map +1 -1
  195. package/dist/application/sandbox-agents.js +12 -4
  196. package/dist/application/sandbox-agents.js.map +1 -1
  197. package/dist/application/sandbox-attach.js +5 -2
  198. package/dist/application/sandbox-attach.js.map +1 -1
  199. package/dist/application/sandbox-dispatch.js +3 -3
  200. package/dist/application/sandbox-dispatch.js.map +1 -1
  201. package/dist/application/sandbox-provision.js +13 -10
  202. package/dist/application/sandbox-provision.js.map +1 -1
  203. package/dist/application/sandbox-session.types.d.ts +8 -8
  204. package/dist/application/sandbox-session.types.js.map +1 -1
  205. package/dist/application/sandbox.js +6 -3
  206. package/dist/application/sandbox.js.map +1 -1
  207. package/dist/application/speculation.js +1 -1
  208. package/dist/application/speculation.js.map +1 -1
  209. package/dist/application/speculation.types.d.ts +3 -3
  210. package/dist/application/speculation.types.js.map +1 -1
  211. package/dist/application/tasks.types.d.ts +2 -2
  212. package/dist/application/tasks.types.js.map +1 -1
  213. package/dist/application/tool-execution.d.ts +3 -0
  214. package/dist/application/tool-execution.js +211 -0
  215. package/dist/application/tool-execution.js.map +1 -0
  216. package/dist/cli/commands.js +4 -2
  217. package/dist/cli/commands.js.map +1 -1
  218. package/dist/cli/doctor-command.js +6 -6
  219. package/dist/cli/doctor-command.js.map +1 -1
  220. package/dist/cli/init-authentication.js +6 -7
  221. package/dist/cli/init-authentication.js.map +1 -1
  222. package/dist/cli/init-command.js +3 -3
  223. package/dist/cli/init-command.js.map +1 -1
  224. package/dist/cli/main.constants.d.ts +4 -4
  225. package/dist/cli/main.constants.js +4 -4
  226. package/dist/cli/main.constants.js.map +1 -1
  227. package/dist/cli/recovery-command.js +1 -1
  228. package/dist/cli/recovery-command.js.map +1 -1
  229. package/dist/cli/scaffold-files.js +5 -4
  230. package/dist/cli/scaffold-files.js.map +1 -1
  231. package/dist/cli/scaffold-validation.js +13 -10
  232. package/dist/cli/scaffold-validation.js.map +1 -1
  233. package/dist/cli/scaffold.js +8 -4
  234. package/dist/cli/scaffold.js.map +1 -1
  235. package/dist/cli/scaffold.types.d.ts +1 -1
  236. package/dist/cli/scaffold.types.js.map +1 -1
  237. package/dist/cli/starters.js +8 -8
  238. package/dist/cli/starters.js.map +1 -1
  239. package/dist/domain/agent-model.d.ts +3 -0
  240. package/dist/domain/agent-model.js +22 -0
  241. package/dist/domain/agent-model.js.map +1 -0
  242. package/dist/domain/agent.d.ts +4 -0
  243. package/dist/domain/agent.js +32 -0
  244. package/dist/domain/agent.js.map +1 -0
  245. package/dist/domain/agent.types.d.ts +69 -2
  246. package/dist/domain/agent.types.js.map +1 -1
  247. package/dist/domain/context.constants.d.ts +7 -0
  248. package/dist/domain/context.constants.js +8 -0
  249. package/dist/domain/context.constants.js.map +1 -0
  250. package/dist/domain/context.d.ts +4 -0
  251. package/dist/domain/context.js +81 -0
  252. package/dist/domain/context.js.map +1 -0
  253. package/dist/domain/context.types.d.ts +26 -0
  254. package/dist/domain/context.types.js +2 -0
  255. package/dist/domain/context.types.js.map +1 -0
  256. package/dist/domain/dispatch-telemetry.types.d.ts +12 -0
  257. package/dist/domain/dispatch-telemetry.types.js +2 -0
  258. package/dist/domain/dispatch-telemetry.types.js.map +1 -0
  259. package/dist/domain/errors.types.d.ts +1 -1
  260. package/dist/domain/errors.types.js.map +1 -1
  261. package/dist/domain/glob.d.ts +2 -0
  262. package/dist/domain/glob.js +25 -0
  263. package/dist/domain/glob.js.map +1 -0
  264. package/dist/domain/glob.types.d.ts +1 -0
  265. package/dist/domain/glob.types.js +2 -0
  266. package/dist/domain/glob.types.js.map +1 -0
  267. package/dist/domain/harness.constants.d.ts +11 -0
  268. package/dist/domain/harness.constants.js +24 -0
  269. package/dist/domain/harness.constants.js.map +1 -0
  270. package/dist/domain/harness.d.ts +2 -0
  271. package/dist/domain/harness.js +89 -0
  272. package/dist/domain/harness.js.map +1 -0
  273. package/dist/domain/harness.types.d.ts +60 -0
  274. package/dist/domain/harness.types.js +2 -0
  275. package/dist/domain/harness.types.js.map +1 -0
  276. package/dist/domain/hook.constants.d.ts +3 -0
  277. package/dist/domain/hook.constants.js +10 -0
  278. package/dist/domain/hook.constants.js.map +1 -0
  279. package/dist/domain/hook.d.ts +3 -0
  280. package/dist/domain/hook.js +25 -0
  281. package/dist/domain/hook.js.map +1 -0
  282. package/dist/domain/hook.types.d.ts +66 -0
  283. package/dist/domain/hook.types.js +2 -0
  284. package/dist/domain/hook.types.js.map +1 -0
  285. package/dist/domain/instructions.d.ts +3 -0
  286. package/dist/domain/instructions.js +25 -0
  287. package/dist/domain/instructions.js.map +1 -0
  288. package/dist/domain/model-messages.d.ts +5 -0
  289. package/dist/domain/model-messages.js +81 -0
  290. package/dist/domain/model-messages.js.map +1 -0
  291. package/dist/domain/model-messages.types.d.ts +6 -0
  292. package/dist/domain/model-messages.types.js +2 -0
  293. package/dist/domain/model-messages.types.js.map +1 -0
  294. package/dist/domain/model.constants.d.ts +4 -0
  295. package/dist/domain/model.constants.js +16 -0
  296. package/dist/domain/model.constants.js.map +1 -0
  297. package/dist/domain/model.types.d.ts +59 -2
  298. package/dist/domain/model.types.js.map +1 -1
  299. package/dist/domain/permissions.d.ts +3 -0
  300. package/dist/domain/permissions.js +92 -0
  301. package/dist/domain/permissions.js.map +1 -0
  302. package/dist/domain/permissions.types.d.ts +34 -0
  303. package/dist/domain/permissions.types.js +2 -0
  304. package/dist/domain/permissions.types.js.map +1 -0
  305. package/dist/domain/response.js +3 -2
  306. package/dist/domain/response.js.map +1 -1
  307. package/dist/domain/response.types.d.ts +12 -0
  308. package/dist/domain/response.types.js.map +1 -1
  309. package/dist/domain/skill.constants.d.ts +2 -0
  310. package/dist/domain/skill.constants.js +8 -0
  311. package/dist/domain/skill.constants.js.map +1 -0
  312. package/dist/domain/skill.d.ts +8 -0
  313. package/dist/domain/skill.js +79 -0
  314. package/dist/domain/skill.js.map +1 -0
  315. package/dist/domain/skill.types.d.ts +18 -0
  316. package/dist/domain/skill.types.js +2 -0
  317. package/dist/domain/skill.types.js.map +1 -0
  318. package/dist/domain/standard-schema.d.ts +6 -0
  319. package/dist/domain/standard-schema.js +45 -0
  320. package/dist/domain/standard-schema.js.map +1 -0
  321. package/dist/domain/tool-schema.d.ts +3 -0
  322. package/dist/domain/tool-schema.js +109 -0
  323. package/dist/domain/tool-schema.js.map +1 -0
  324. package/dist/domain/tool.constants.d.ts +4 -0
  325. package/dist/domain/tool.constants.js +36 -0
  326. package/dist/domain/tool.constants.js.map +1 -0
  327. package/dist/domain/tool.d.ts +4 -0
  328. package/dist/domain/tool.js +66 -0
  329. package/dist/domain/tool.js.map +1 -0
  330. package/dist/domain/tool.types.d.ts +62 -0
  331. package/dist/domain/tool.types.js +2 -0
  332. package/dist/domain/tool.types.js.map +1 -0
  333. package/dist/domain/transcript.d.ts +4 -0
  334. package/dist/domain/transcript.js +48 -0
  335. package/dist/domain/transcript.js.map +1 -0
  336. package/dist/domain/transcript.types.d.ts +15 -0
  337. package/dist/domain/transcript.types.js +2 -0
  338. package/dist/domain/transcript.types.js.map +1 -0
  339. package/dist/domain/workflow/workflow-state.js +13 -6
  340. package/dist/domain/workflow/workflow-state.js.map +1 -1
  341. package/dist/domain/workflow.d.ts +1 -1
  342. package/dist/domain/workflow.js.map +1 -1
  343. package/dist/domain/workflow.types.d.ts +4 -0
  344. package/dist/domain/workflow.types.js.map +1 -1
  345. package/dist/index.d.ts +34 -8
  346. package/dist/index.js +19 -4
  347. package/dist/index.js.map +1 -1
  348. package/dist/infrastructure/conversations/harness-store.d.ts +3 -0
  349. package/dist/infrastructure/conversations/harness-store.js +27 -0
  350. package/dist/infrastructure/conversations/harness-store.js.map +1 -0
  351. package/dist/infrastructure/conversations/harness-transcript.d.ts +2 -0
  352. package/dist/infrastructure/conversations/harness-transcript.js +50 -0
  353. package/dist/infrastructure/conversations/harness-transcript.js.map +1 -0
  354. package/dist/infrastructure/conversations/harness-transcript.types.d.ts +18 -0
  355. package/dist/infrastructure/conversations/harness-transcript.types.js +2 -0
  356. package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -0
  357. package/dist/infrastructure/conversations.d.ts +4 -1
  358. package/dist/infrastructure/conversations.js +3 -0
  359. package/dist/infrastructure/conversations.js.map +1 -1
  360. package/dist/infrastructure/conversations.types.d.ts +1 -0
  361. package/dist/infrastructure/conversations.types.js.map +1 -1
  362. package/dist/infrastructure/custom-reporter.d.ts +2 -0
  363. package/dist/infrastructure/custom-reporter.js +33 -0
  364. package/dist/infrastructure/custom-reporter.js.map +1 -0
  365. package/dist/infrastructure/custom-reporter.types.d.ts +13 -0
  366. package/dist/infrastructure/custom-reporter.types.js +2 -0
  367. package/dist/infrastructure/custom-reporter.types.js.map +1 -0
  368. package/dist/infrastructure/git/git.constants.d.ts +1 -1
  369. package/dist/infrastructure/git/git.constants.js +1 -0
  370. package/dist/infrastructure/git/git.constants.js.map +1 -1
  371. package/dist/infrastructure/journal.constants.d.ts +1 -0
  372. package/dist/infrastructure/journal.constants.js +2 -0
  373. package/dist/infrastructure/journal.constants.js.map +1 -0
  374. package/dist/infrastructure/journal.js +4 -1
  375. package/dist/infrastructure/journal.js.map +1 -1
  376. package/dist/infrastructure/opentelemetry-dispatch.d.ts +6 -0
  377. package/dist/infrastructure/opentelemetry-dispatch.js +70 -0
  378. package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -0
  379. package/dist/infrastructure/opentelemetry.constants.d.ts +3 -0
  380. package/dist/infrastructure/opentelemetry.constants.js +3 -0
  381. package/dist/infrastructure/opentelemetry.constants.js.map +1 -1
  382. package/dist/infrastructure/opentelemetry.js +4 -0
  383. package/dist/infrastructure/opentelemetry.js.map +1 -1
  384. package/dist/infrastructure/opentelemetry.types.d.ts +3 -3
  385. package/dist/infrastructure/opentelemetry.types.js.map +1 -1
  386. package/dist/infrastructure/reporter.js +27 -2
  387. package/dist/infrastructure/reporter.js.map +1 -1
  388. package/dist/infrastructure/resource-activity-inspection.js +3 -2
  389. package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
  390. package/dist/infrastructure/resource-activity.js +2 -2
  391. package/dist/infrastructure/resource-activity.js.map +1 -1
  392. package/dist/infrastructure/resource-activity.types.d.ts +2 -2
  393. package/dist/infrastructure/resource-activity.types.js.map +1 -1
  394. package/dist/infrastructure/settings.d.ts +1 -1
  395. package/dist/infrastructure/settings.js +3 -3
  396. package/dist/infrastructure/settings.js.map +1 -1
  397. package/dist/infrastructure/sse.d.ts +2 -0
  398. package/dist/infrastructure/sse.js +64 -0
  399. package/dist/infrastructure/sse.js.map +1 -0
  400. package/dist/infrastructure/sse.types.d.ts +4 -0
  401. package/dist/infrastructure/sse.types.js +2 -0
  402. package/dist/infrastructure/sse.types.js.map +1 -0
  403. package/dist/infrastructure/transport-conversations.d.ts +2 -2
  404. package/dist/infrastructure/transport-conversations.js +8 -1
  405. package/dist/infrastructure/transport-conversations.js.map +1 -1
  406. package/dist/infrastructure/transport-journal.js +2 -1
  407. package/dist/infrastructure/transport-journal.js.map +1 -1
  408. package/dist/providers/agents.d.ts +3 -3
  409. package/dist/providers/agents.js +3 -3
  410. package/dist/providers/agents.js.map +1 -1
  411. package/dist/providers/daytona.d.ts +1 -1
  412. package/dist/providers/daytona.js +1 -1
  413. package/dist/providers/daytona.js.map +1 -1
  414. package/dist/providers/docker.d.ts +1 -1
  415. package/dist/providers/docker.js +1 -1
  416. package/dist/providers/docker.js.map +1 -1
  417. package/dist/providers/factories.d.ts +2 -2
  418. package/dist/providers/factories.js +3 -3
  419. package/dist/providers/factories.js.map +1 -1
  420. package/dist/providers/firecracker.d.ts +1 -1
  421. package/dist/providers/firecracker.js +1 -1
  422. package/dist/providers/firecracker.js.map +1 -1
  423. package/dist/providers/local.d.ts +1 -1
  424. package/dist/providers/local.js +1 -1
  425. package/dist/providers/local.js.map +1 -1
  426. package/dist/providers/podman.d.ts +1 -1
  427. package/dist/providers/podman.js +1 -1
  428. package/dist/providers/podman.js.map +1 -1
  429. package/dist/providers/vercel.d.ts +1 -1
  430. package/dist/providers/vercel.js +1 -1
  431. package/dist/providers/vercel.js.map +1 -1
  432. package/package.json +1 -1
  433. package/dist/adapters/models/openai-compatible.constants.js.map +0 -1
  434. package/dist/adapters/models/openai-compatible.d.ts +0 -3
  435. package/dist/adapters/models/openai-compatible.js +0 -78
  436. package/dist/adapters/models/openai-compatible.js.map +0 -1
  437. package/dist/adapters/models/openai-compatible.types.d.ts +0 -14
  438. package/dist/adapters/models/openai-compatible.types.js +0 -2
  439. package/dist/adapters/models/openai-compatible.types.js.map +0 -1
  440. package/dist/adapters/models/openai-http.js.map +0 -1
  441. package/dist/adapters/models/openai-request.d.ts +0 -4
  442. package/dist/adapters/models/openai-request.js +0 -46
  443. package/dist/adapters/models/openai-request.js.map +0 -1
  444. package/dist/adapters/models/openai-response.d.ts +0 -3
  445. package/dist/adapters/models/openai-response.js +0 -65
  446. package/dist/adapters/models/openai-response.js.map +0 -1
  447. package/dist/cli/init-authentication.constants.js.map +0 -1
  448. /package/dist/{cli/init-authentication.constants.d.ts → adapters/agents/authentication.constants.d.ts} +0 -0
  449. /package/dist/adapters/models/{openai-http.d.ts → model-http.d.ts} +0 -0
  450. /package/dist/adapters/models/{openai-compatible.constants.d.ts → model.constants.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"settings.types.js","sourceRoot":"","sources":["../../../src/adapters/agents/settings.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Variables } from \"../../domain/command.types.ts\";\n\nexport interface CommonAgentSettings {\n readonly model?: string;\n readonly variables?: Variables;\n readonly saveConversations?: boolean;\n}\n\nexport interface ClaudeSettings extends CommonAgentSettings {\n readonly reasoning?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n readonly permissions?:\n | \"default\"\n | \"acceptEdits\"\n | \"plan\"\n | \"auto\"\n | \"dontAsk\"\n | \"bypassPermissions\";\n}\n\nexport interface CodexModelProvider {\n readonly baseUrl: string;\n readonly apiKeyEnvironment?: string | false;\n}\n\nexport interface CodexSettings extends CommonAgentSettings {\n readonly modelProvider?: CodexModelProvider;\n readonly reasoning?: \"low\" | \"medium\" | \"high\" | \"xhigh\";\n readonly approvalReviewer?: \"user\" | \"auto_review\";\n}\n"]}
1
+ {"version":3,"file":"settings.types.js","sourceRoot":"","sources":["../../../src/adapters/agents/settings.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAuthentication } from \"../../domain/agent.types.ts\";\nimport type { Variables } from \"../../domain/command.types.ts\";\nimport type { AgentModel, ModelReasoning } from \"../../domain/model.types.ts\";\n\nexport interface CommonAgentSettings {\n readonly authentication?: AgentAuthentication;\n readonly variables?: Variables;\n readonly saveConversations?: boolean;\n}\n\nexport interface ClaudeSettings extends CommonAgentSettings {\n readonly permissions?:\n | \"default\"\n | \"acceptEdits\"\n | \"plan\"\n | \"auto\"\n | \"dontAsk\"\n | \"bypassPermissions\";\n}\n\nexport interface CodexModelProvider {\n readonly baseUrl: string;\n readonly apiKeyEnvironment?: string | false;\n}\n\nexport interface CodexSettings extends CommonAgentSettings {\n readonly modelProvider?: CodexModelProvider;\n readonly approvalReviewer?: \"user\" | \"auto_review\";\n}\n\nexport type Bound<Settings> = Settings & { readonly model?: AgentModel };\n\nexport interface CliModelSupport {\n readonly agent: string;\n readonly reasoning: ReadonlySet<ModelReasoning>;\n readonly maxOutputTokens: boolean;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const ANTHROPIC_BASE_URL = "https://api.anthropic.com/v1";
2
+ export declare const ANTHROPIC_VERSION = "2023-06-01";
3
+ export declare const ANTHROPIC_REASONING: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
@@ -0,0 +1,17 @@
1
+ export const ANTHROPIC_BASE_URL = "https://api.anthropic.com/v1";
2
+ export const ANTHROPIC_VERSION = "2023-06-01";
3
+ export const ANTHROPIC_REASONING = {
4
+ none: { thinking: { type: "disabled" } },
5
+ low: { thinking: { type: "adaptive" }, output_config: { effort: "low" } },
6
+ medium: {
7
+ thinking: { type: "adaptive" },
8
+ output_config: { effort: "medium" },
9
+ },
10
+ high: { thinking: { type: "adaptive" }, output_config: { effort: "high" } },
11
+ xhigh: {
12
+ thinking: { type: "adaptive" },
13
+ output_config: { effort: "xhigh" },
14
+ },
15
+ max: { thinking: { type: "adaptive" }, output_config: { effort: "max" } },
16
+ };
17
+ //# sourceMappingURL=anthropic-model-provider.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-model-provider.constants.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-model-provider.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,8BAA8B,CAAC;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAE9C,MAAM,CAAC,MAAM,mBAAmB,GAE5B;IACF,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IACxC,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;IACzE,MAAM,EAAE;QACN,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC9B,aAAa,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;KACpC;IACD,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;IAC3E,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC9B,aAAa,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;KACnC;IACD,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;CAC1E,CAAC","sourcesContent":["export const ANTHROPIC_BASE_URL = \"https://api.anthropic.com/v1\";\nexport const ANTHROPIC_VERSION = \"2023-06-01\";\n\nexport const ANTHROPIC_REASONING: Readonly<\n Record<string, Readonly<Record<string, unknown>>>\n> = {\n none: { thinking: { type: \"disabled\" } },\n low: { thinking: { type: \"adaptive\" }, output_config: { effort: \"low\" } },\n medium: {\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"medium\" },\n },\n high: { thinking: { type: \"adaptive\" }, output_config: { effort: \"high\" } },\n xhigh: {\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"xhigh\" },\n },\n max: { thinking: { type: \"adaptive\" }, output_config: { effort: \"max\" } },\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ModelProvider } from "../../domain/model.types.ts";
2
+ import type { AnthropicModelProviderOptions } from "./anthropic-model-provider.types.ts";
3
+ export declare function anthropicModelProvider(options: AnthropicModelProviderOptions): ModelProvider;
@@ -0,0 +1,31 @@
1
+ import { invariant } from "../../domain/errors.js";
2
+ import { ANTHROPIC_BASE_URL, ANTHROPIC_VERSION, } from "./anthropic-model-provider.constants.js";
3
+ import { anthropicBody, supportedReasoning } from "./anthropic-request.js";
4
+ import { readAnthropicResponse } from "./anthropic-response.js";
5
+ import { anthropicStream } from "./anthropic-stream.js";
6
+ import { httpModelProvider } from "./http-provider.js";
7
+ export function anthropicModelProvider(options) {
8
+ invariant(options && typeof options === "object", "Model provider options must be an object");
9
+ invariant(Object.keys(options).every((key) => [
10
+ "baseUrl",
11
+ "apiKey",
12
+ "cacheSystem",
13
+ "timeoutMs",
14
+ "maxResponseBytes",
15
+ ].includes(key)), "Unsupported Anthropic model provider option");
16
+ invariant(typeof options.apiKey === "string", "Anthropic requires an API key");
17
+ invariant(options.cacheSystem === undefined ||
18
+ typeof options.cacheSystem === "boolean", "cacheSystem must be boolean");
19
+ const cacheSystem = options.cacheSystem ?? false;
20
+ return httpModelProvider({ ...options, baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL }, {
21
+ path: "messages",
22
+ validate(model) {
23
+ invariant(model.maxOutputTokens !== undefined, "Anthropic requires maxOutputTokens on the agent model");
24
+ supportedReasoning(model.reasoning);
25
+ },
26
+ build: (request, context) => anthropicBody(request, context, cacheSystem),
27
+ read: readAnthropicResponse,
28
+ stream: { body: { stream: true }, decoder: anthropicStream },
29
+ }, "anthropic", { "x-api-key": options.apiKey, "anthropic-version": ANTHROPIC_VERSION });
30
+ }
31
+ //# sourceMappingURL=anthropic-model-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-model-provider.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-model-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,sBAAsB,CACpC,OAAsC;IAEtC,SAAS,CACP,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EACtC,0CAA0C,CAC3C,CAAC;IACF,SAAS,CACP,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACjC;QACE,SAAS;QACT,QAAQ;QACR,aAAa;QACb,WAAW;QACX,kBAAkB;KACnB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAChB,EACD,6CAA6C,CAC9C,CAAC;IACF,SAAS,CACP,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,EAClC,+BAA+B,CAChC,CAAC;IACF,SAAS,CACP,OAAO,CAAC,WAAW,KAAK,SAAS;QAC/B,OAAO,OAAO,CAAC,WAAW,KAAK,SAAS,EAC1C,6BAA6B,CAC9B,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC;IACjD,OAAO,iBAAiB,CACtB,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,kBAAkB,EAAE,EAC9D;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,CAAC,KAAK;YACZ,SAAS,CACP,KAAK,CAAC,eAAe,KAAK,SAAS,EACnC,uDAAuD,CACxD,CAAC;YACF,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;QACzE,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE;KAC7D,EACD,WAAW,EACX,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CACxE,CAAC;AACJ,CAAC","sourcesContent":["import { invariant } from \"../../domain/errors.ts\";\nimport type { ModelProvider } from \"../../domain/model.types.ts\";\nimport type { AnthropicModelProviderOptions } from \"./anthropic-model-provider.types.ts\";\nimport {\n ANTHROPIC_BASE_URL,\n ANTHROPIC_VERSION,\n} from \"./anthropic-model-provider.constants.ts\";\nimport { anthropicBody, supportedReasoning } from \"./anthropic-request.ts\";\nimport { readAnthropicResponse } from \"./anthropic-response.ts\";\nimport { anthropicStream } from \"./anthropic-stream.ts\";\nimport { httpModelProvider } from \"./http-provider.ts\";\n\nexport function anthropicModelProvider(\n options: AnthropicModelProviderOptions,\n): ModelProvider {\n invariant(\n options && typeof options === \"object\",\n \"Model provider options must be an object\",\n );\n invariant(\n Object.keys(options).every((key) =>\n [\n \"baseUrl\",\n \"apiKey\",\n \"cacheSystem\",\n \"timeoutMs\",\n \"maxResponseBytes\",\n ].includes(key),\n ),\n \"Unsupported Anthropic model provider option\",\n );\n invariant(\n typeof options.apiKey === \"string\",\n \"Anthropic requires an API key\",\n );\n invariant(\n options.cacheSystem === undefined ||\n typeof options.cacheSystem === \"boolean\",\n \"cacheSystem must be boolean\",\n );\n const cacheSystem = options.cacheSystem ?? false;\n return httpModelProvider(\n { ...options, baseUrl: options.baseUrl ?? ANTHROPIC_BASE_URL },\n {\n path: \"messages\",\n validate(model) {\n invariant(\n model.maxOutputTokens !== undefined,\n \"Anthropic requires maxOutputTokens on the agent model\",\n );\n supportedReasoning(model.reasoning);\n },\n build: (request, context) => anthropicBody(request, context, cacheSystem),\n read: readAnthropicResponse,\n stream: { body: { stream: true }, decoder: anthropicStream },\n },\n \"anthropic\",\n { \"x-api-key\": options.apiKey, \"anthropic-version\": ANTHROPIC_VERSION },\n );\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export interface AnthropicModelProviderOptions {
2
+ readonly apiKey: string;
3
+ readonly baseUrl?: string;
4
+ readonly cacheSystem?: boolean;
5
+ readonly timeoutMs?: number;
6
+ readonly maxResponseBytes?: number;
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=anthropic-model-provider.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-model-provider.types.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-model-provider.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface AnthropicModelProviderOptions {\n readonly apiKey: string;\n readonly baseUrl?: string;\n readonly cacheSystem?: boolean;\n readonly timeoutMs?: number;\n readonly maxResponseBytes?: number;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { ModelReasoning, ModelRequest } from "../../domain/model.types.ts";
2
+ import type { ProtocolContext } from "./model-protocol.types.ts";
3
+ export declare function anthropicBody(request: ModelRequest, context: ProtocolContext, cacheSystem: boolean): Record<string, unknown>;
4
+ export declare function supportedReasoning(reasoning: ModelReasoning | undefined): void;
@@ -0,0 +1,81 @@
1
+ import { invariant } from "../../domain/errors.js";
2
+ import { replayable, requestMessages } from "../../domain/model-messages.js";
3
+ import { ANTHROPIC_REASONING } from "./anthropic-model-provider.constants.js";
4
+ const encoders = {
5
+ text: (block) => ({ type: "text", text: block.text }),
6
+ "tool-call": (block) => ({
7
+ type: "tool_use",
8
+ id: block.id,
9
+ name: block.name,
10
+ input: block.input,
11
+ }),
12
+ "tool-result": (block) => ({
13
+ type: "tool_result",
14
+ tool_use_id: block.callId,
15
+ content: block.content,
16
+ ...(block.isError ? { is_error: true } : {}),
17
+ }),
18
+ reasoning: (block) => block.data,
19
+ };
20
+ export function anthropicBody(request, context, cacheSystem) {
21
+ invariant(!cacheSystem || !!request.system?.trim(), "System cache requires system instructions");
22
+ invariant(request.maxOutputTokens !== undefined, "Anthropic requests require maxOutputTokens");
23
+ supportedReasoning(request.reasoning);
24
+ const messages = requestMessages(request).flatMap((message) => anthropicMessage(message, context));
25
+ return {
26
+ model: context.model,
27
+ max_tokens: request.maxOutputTokens,
28
+ ...(request.reasoning === undefined
29
+ ? {}
30
+ : ANTHROPIC_REASONING[request.reasoning]),
31
+ ...(request.cache ? { cache_control: { type: "ephemeral" } } : {}),
32
+ stream: false,
33
+ messages: request.messages === undefined
34
+ ? [{ role: "user", content: request.prompt }]
35
+ : messages,
36
+ ...(request.tools?.length
37
+ ? {
38
+ tools: request.tools.map((tool) => ({
39
+ name: tool.name,
40
+ description: tool.description,
41
+ input_schema: tool.inputSchema,
42
+ })),
43
+ }
44
+ : {}),
45
+ ...(request.system === undefined
46
+ ? {}
47
+ : {
48
+ system: cacheSystem
49
+ ? [
50
+ {
51
+ type: "text",
52
+ text: request.system,
53
+ cache_control: { type: "ephemeral" },
54
+ },
55
+ ]
56
+ : request.system,
57
+ }),
58
+ };
59
+ }
60
+ export function supportedReasoning(reasoning) {
61
+ invariant(reasoning === undefined || Object.hasOwn(ANTHROPIC_REASONING, reasoning), `Anthropic does not support reasoning "${reasoning}"`);
62
+ }
63
+ function anthropicMessage(message, context) {
64
+ const blocks = message.content.filter((block) => replayable(block, context.identity, context.model) &&
65
+ (block.type !== "text" || block.text !== ""));
66
+ const ordered = message.role === "user"
67
+ ? [
68
+ ...blocks.filter((block) => block.type === "tool-result"),
69
+ ...blocks.filter((block) => block.type !== "tool-result"),
70
+ ]
71
+ : blocks;
72
+ if (ordered.length === 0)
73
+ return [];
74
+ return [
75
+ {
76
+ role: message.role,
77
+ content: ordered.map((block) => encoders[block.type](block)),
78
+ },
79
+ ];
80
+ }
81
+ //# sourceMappingURL=anthropic-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-request.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-request.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../../domain/errors.ts\";\nimport { replayable, requestMessages } from \"../../domain/model-messages.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelReasoning,\n ModelRequest,\n} from \"../../domain/model.types.ts\";\nimport { ANTHROPIC_REASONING } from \"./anthropic-model-provider.constants.ts\";\nimport type { BlockEncoders, ProtocolContext } from \"./model-protocol.types.ts\";\n\nconst encoders: BlockEncoders = {\n text: (block) => ({ type: \"text\", text: block.text }),\n \"tool-call\": (block) => ({\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input: block.input,\n }),\n \"tool-result\": (block) => ({\n type: \"tool_result\",\n tool_use_id: block.callId,\n content: block.content,\n ...(block.isError ? { is_error: true } : {}),\n }),\n reasoning: (block) => block.data,\n};\n\nexport function anthropicBody(\n request: ModelRequest,\n context: ProtocolContext,\n cacheSystem: boolean,\n): Record<string, unknown> {\n invariant(\n !cacheSystem || !!request.system?.trim(),\n \"System cache requires system instructions\",\n );\n invariant(\n request.maxOutputTokens !== undefined,\n \"Anthropic requests require maxOutputTokens\",\n );\n supportedReasoning(request.reasoning);\n const messages = requestMessages(request).flatMap((message) =>\n anthropicMessage(message, context),\n );\n return {\n model: context.model,\n max_tokens: request.maxOutputTokens,\n ...(request.reasoning === undefined\n ? {}\n : ANTHROPIC_REASONING[request.reasoning]),\n ...(request.cache ? { cache_control: { type: \"ephemeral\" } } : {}),\n stream: false,\n messages:\n request.messages === undefined\n ? [{ role: \"user\", content: request.prompt }]\n : messages,\n ...(request.tools?.length\n ? {\n tools: request.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.inputSchema,\n })),\n }\n : {}),\n ...(request.system === undefined\n ? {}\n : {\n system: cacheSystem\n ? [\n {\n type: \"text\",\n text: request.system,\n cache_control: { type: \"ephemeral\" },\n },\n ]\n : request.system,\n }),\n };\n}\n\nexport function supportedReasoning(\n reasoning: ModelReasoning | undefined,\n): void {\n invariant(\n reasoning === undefined || Object.hasOwn(ANTHROPIC_REASONING, reasoning),\n `Anthropic does not support reasoning \"${reasoning}\"`,\n );\n}\n\nfunction anthropicMessage(message: ModelMessage, context: ProtocolContext) {\n const blocks = message.content.filter(\n (block) =>\n replayable(block, context.identity, context.model) &&\n (block.type !== \"text\" || block.text !== \"\"),\n );\n const ordered =\n message.role === \"user\"\n ? [\n ...blocks.filter((block) => block.type === \"tool-result\"),\n ...blocks.filter((block) => block.type !== \"tool-result\"),\n ]\n : blocks;\n if (ordered.length === 0) return [];\n return [\n {\n role: message.role,\n content: ordered.map((block) =>\n (encoders[block.type] as (value: ModelContentBlock) => unknown)(block),\n ),\n },\n ];\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ModelResult } from "../../domain/model.types.ts";
2
+ import type { ProtocolContext } from "./model-protocol.types.ts";
3
+ export declare function readAnthropicResponse(value: unknown, context?: ProtocolContext): ModelResult;
@@ -0,0 +1,55 @@
1
+ import { modelResult, object, requireResponse, stopReason, tokens, toolInput, } from "./model-response.js";
2
+ import { ANTHROPIC_STOP_REASONS } from "./stop-reasons.constants.js";
3
+ const decoders = {
4
+ text: (block) => {
5
+ requireResponse(typeof block.text === "string");
6
+ return { type: "text", text: block.text };
7
+ },
8
+ tool_use: (block) => {
9
+ requireResponse(typeof block.id === "string" && typeof block.name === "string");
10
+ return {
11
+ type: "tool-call",
12
+ id: block.id,
13
+ name: block.name,
14
+ input: toolInput(block.input),
15
+ };
16
+ },
17
+ thinking: reasoning,
18
+ redacted_thinking: reasoning,
19
+ };
20
+ export function readAnthropicResponse(value, context = { identity: "anthropic", model: "" }) {
21
+ const data = object(value);
22
+ requireResponse(data.type === "message" && data.role === "assistant");
23
+ const reason = stopReason(ANTHROPIC_STOP_REASONS, data.stop_reason);
24
+ requireResponse(Array.isArray(data.content));
25
+ const content = data.content.map((value) => {
26
+ const block = object(value);
27
+ requireResponse(typeof block.type === "string" && Object.hasOwn(decoders, block.type));
28
+ return decoders[block.type](block, context);
29
+ });
30
+ return modelResult(content, reason, usage(data.usage));
31
+ }
32
+ function reasoning(block, context) {
33
+ return {
34
+ type: "reasoning",
35
+ provider: context.identity,
36
+ model: context.model,
37
+ data: block,
38
+ };
39
+ }
40
+ function usage(value) {
41
+ if (value === undefined)
42
+ return undefined;
43
+ const reported = object(value);
44
+ const cached = tokens(reported.cache_read_input_tokens ?? 0);
45
+ const cacheCreated = tokens(reported.cache_creation_input_tokens ?? 0);
46
+ const input = tokens(reported.input_tokens) + cached + cacheCreated;
47
+ requireResponse(Number.isSafeInteger(input));
48
+ return {
49
+ input,
50
+ cached,
51
+ cacheCreated,
52
+ output: tokens(reported.output_tokens),
53
+ };
54
+ }
55
+ //# sourceMappingURL=anthropic-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-response.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-response.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EACX,MAAM,EACN,eAAe,EACf,UAAU,EACV,MAAM,EACN,SAAS,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,QAAQ,GAQV;IACF,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QACd,eAAe,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;QAClB,eAAe,CACb,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC/D,CAAC;QACF,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;SAC9B,CAAC;IACJ,CAAC;IACD,QAAQ,EAAE,SAAS;IACnB,iBAAiB,EAAE,SAAS;CAC7B,CAAC;AAEF,MAAM,UAAU,qBAAqB,CACnC,KAAc,EACd,UAA2B,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;IAE/D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,eAAe,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,UAAU,CAAC,sBAAsB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,eAAe,CACb,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CACtE,CAAC;QACF,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,OAAO,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,SAAS,CAChB,KAA8B,EAC9B,OAAwB;IAExB,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,KAAK;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,MAAM,GAAG,YAAY,CAAC;IACpE,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,OAAO;QACL,KAAK;QACL,MAAM;QACN,YAAY;QACZ,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["import type {\n ModelContentBlock,\n ModelResult,\n} from \"../../domain/model.types.ts\";\nimport type { ProtocolContext } from \"./model-protocol.types.ts\";\nimport {\n modelResult,\n object,\n requireResponse,\n stopReason,\n tokens,\n toolInput,\n} from \"./model-response.ts\";\nimport { ANTHROPIC_STOP_REASONS } from \"./stop-reasons.constants.ts\";\n\nconst decoders: Readonly<\n Record<\n string,\n (\n block: Record<string, unknown>,\n context: ProtocolContext,\n ) => ModelContentBlock\n >\n> = {\n text: (block) => {\n requireResponse(typeof block.text === \"string\");\n return { type: \"text\", text: block.text };\n },\n tool_use: (block) => {\n requireResponse(\n typeof block.id === \"string\" && typeof block.name === \"string\",\n );\n return {\n type: \"tool-call\",\n id: block.id,\n name: block.name,\n input: toolInput(block.input),\n };\n },\n thinking: reasoning,\n redacted_thinking: reasoning,\n};\n\nexport function readAnthropicResponse(\n value: unknown,\n context: ProtocolContext = { identity: \"anthropic\", model: \"\" },\n): ModelResult {\n const data = object(value);\n requireResponse(data.type === \"message\" && data.role === \"assistant\");\n const reason = stopReason(ANTHROPIC_STOP_REASONS, data.stop_reason);\n requireResponse(Array.isArray(data.content));\n const content = data.content.map((value) => {\n const block = object(value);\n requireResponse(\n typeof block.type === \"string\" && Object.hasOwn(decoders, block.type),\n );\n return decoders[block.type]!(block, context);\n });\n return modelResult(content, reason, usage(data.usage));\n}\n\nfunction reasoning(\n block: Record<string, unknown>,\n context: ProtocolContext,\n): ModelContentBlock {\n return {\n type: \"reasoning\",\n provider: context.identity,\n model: context.model,\n data: block,\n };\n}\n\nfunction usage(value: unknown): ModelResult[\"usage\"] {\n if (value === undefined) return undefined;\n const reported = object(value);\n const cached = tokens(reported.cache_read_input_tokens ?? 0);\n const cacheCreated = tokens(reported.cache_creation_input_tokens ?? 0);\n const input = tokens(reported.input_tokens) + cached + cacheCreated;\n requireResponse(Number.isSafeInteger(input));\n return {\n input,\n cached,\n cacheCreated,\n output: tokens(reported.output_tokens),\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { StreamDecoder } from "./model-protocol.types.ts";
2
+ export declare function anthropicStream(): StreamDecoder;
@@ -0,0 +1,96 @@
1
+ import { object, requireResponse } from "./model-response.js";
2
+ import { eventData, streamFailure } from "./stream-events.js";
3
+ export function anthropicStream() {
4
+ let message;
5
+ let usage = {};
6
+ let stop = null;
7
+ const blocks = [];
8
+ const arguments_ = [];
9
+ const append = (block, key, text) => {
10
+ requireResponse(typeof text === "string");
11
+ block[key] = `${typeof block[key] === "string" ? block[key] : ""}${text}`;
12
+ return text;
13
+ };
14
+ const deltas = {
15
+ text_delta: (block, delta) => append(block, "text", delta.text),
16
+ thinking_delta: (block, delta) => {
17
+ append(block, "thinking", delta.thinking);
18
+ return undefined;
19
+ },
20
+ signature_delta: (block, delta) => {
21
+ block.signature = delta.signature;
22
+ return undefined;
23
+ },
24
+ input_json_delta: (_block, delta, index) => {
25
+ requireResponse(typeof delta.partial_json === "string");
26
+ arguments_[index] = `${arguments_[index] ?? ""}${delta.partial_json}`;
27
+ return undefined;
28
+ },
29
+ };
30
+ const handlers = {
31
+ message_start: (data) => {
32
+ message = object(data.message);
33
+ usage = { ...object(message.usage ?? {}) };
34
+ return undefined;
35
+ },
36
+ content_block_start: (data) => {
37
+ blocks[index(data)] = { ...object(data.content_block) };
38
+ return undefined;
39
+ },
40
+ content_block_delta: (data) => {
41
+ const delta = object(data.delta);
42
+ const block = blocks[index(data)];
43
+ requireResponse(block);
44
+ const handler = typeof delta.type === "string" && Object.hasOwn(deltas, delta.type)
45
+ ? deltas[delta.type]
46
+ : undefined;
47
+ return handler?.(block, delta, index(data));
48
+ },
49
+ content_block_stop: (data) => {
50
+ const block = blocks[index(data)];
51
+ requireResponse(block);
52
+ if (block.type === "tool_use")
53
+ block.input = parse(arguments_[index(data)] ?? "");
54
+ return undefined;
55
+ },
56
+ message_delta: (data) => {
57
+ stop = object(data.delta).stop_reason ?? stop;
58
+ usage = { ...usage, ...object(data.usage ?? {}) };
59
+ return undefined;
60
+ },
61
+ error: streamFailure,
62
+ };
63
+ return {
64
+ push(event) {
65
+ const data = eventData(event);
66
+ const handler = typeof data.type === "string" && Object.hasOwn(handlers, data.type)
67
+ ? handlers[data.type]
68
+ : undefined;
69
+ return handler?.(data);
70
+ },
71
+ final() {
72
+ requireResponse(message);
73
+ return {
74
+ ...message,
75
+ content: blocks.filter(Boolean),
76
+ stop_reason: stop,
77
+ ...(Object.keys(usage).length ? { usage } : {}),
78
+ };
79
+ },
80
+ };
81
+ }
82
+ function index(data) {
83
+ requireResponse(Number.isSafeInteger(data.index) && Number(data.index) >= 0);
84
+ return Number(data.index);
85
+ }
86
+ function parse(text) {
87
+ if (!text.trim())
88
+ return {};
89
+ try {
90
+ return JSON.parse(text);
91
+ }
92
+ catch {
93
+ return text;
94
+ }
95
+ }
96
+ //# sourceMappingURL=anthropic-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-stream.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StreamDecoder } from \"./model-protocol.types.ts\";\nimport { object, requireResponse } from \"./model-response.ts\";\nimport { eventData, streamFailure } from \"./stream-events.ts\";\n\nexport function anthropicStream(): StreamDecoder {\n let message: Record<string, unknown> | undefined;\n let usage: Record<string, unknown> = {};\n let stop: unknown = null;\n const blocks: Record<string, unknown>[] = [];\n const arguments_: string[] = [];\n const append = (\n block: Record<string, unknown>,\n key: string,\n text: unknown,\n ) => {\n requireResponse(typeof text === \"string\");\n block[key] = `${typeof block[key] === \"string\" ? block[key] : \"\"}${text}`;\n return text;\n };\n const deltas: Readonly<\n Record<\n string,\n (\n block: Record<string, unknown>,\n delta: Record<string, unknown>,\n index: number,\n ) => string | undefined\n >\n > = {\n text_delta: (block, delta) => append(block, \"text\", delta.text),\n thinking_delta: (block, delta) => {\n append(block, \"thinking\", delta.thinking);\n return undefined;\n },\n signature_delta: (block, delta) => {\n block.signature = delta.signature;\n return undefined;\n },\n input_json_delta: (_block, delta, index) => {\n requireResponse(typeof delta.partial_json === \"string\");\n arguments_[index] = `${arguments_[index] ?? \"\"}${delta.partial_json}`;\n return undefined;\n },\n };\n const handlers: Readonly<\n Record<string, (data: Record<string, unknown>) => string | undefined>\n > = {\n message_start: (data) => {\n message = object(data.message);\n usage = { ...object(message.usage ?? {}) };\n return undefined;\n },\n content_block_start: (data) => {\n blocks[index(data)] = { ...object(data.content_block) };\n return undefined;\n },\n content_block_delta: (data) => {\n const delta = object(data.delta);\n const block = blocks[index(data)];\n requireResponse(block);\n const handler =\n typeof delta.type === \"string\" && Object.hasOwn(deltas, delta.type)\n ? deltas[delta.type]\n : undefined;\n return handler?.(block, delta, index(data));\n },\n content_block_stop: (data) => {\n const block = blocks[index(data)];\n requireResponse(block);\n if (block.type === \"tool_use\")\n block.input = parse(arguments_[index(data)] ?? \"\");\n return undefined;\n },\n message_delta: (data) => {\n stop = object(data.delta).stop_reason ?? stop;\n usage = { ...usage, ...object(data.usage ?? {}) };\n return undefined;\n },\n error: streamFailure,\n };\n return {\n push(event) {\n const data = eventData(event);\n const handler =\n typeof data.type === \"string\" && Object.hasOwn(handlers, data.type)\n ? handlers[data.type]\n : undefined;\n return handler?.(data);\n },\n final() {\n requireResponse(message);\n return {\n ...message,\n content: blocks.filter(Boolean),\n stop_reason: stop,\n ...(Object.keys(usage).length ? { usage } : {}),\n };\n },\n };\n}\n\nfunction index(data: Record<string, unknown>): number {\n requireResponse(Number.isSafeInteger(data.index) && Number(data.index) >= 0);\n return Number(data.index);\n}\n\nfunction parse(text: string): unknown {\n if (!text.trim()) return {};\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ModelProvider } from "../../domain/model.types.ts";
2
+ import type { HttpModelOptions, ModelProtocol } from "./model-protocol.types.ts";
3
+ export declare function httpModelProvider(options: HttpModelOptions, protocol: ModelProtocol, name: string, headers: Readonly<Record<string, string>>): ModelProvider;
@@ -0,0 +1,113 @@
1
+ import { invariant, OutpostError, positive } from "../../domain/errors.js";
2
+ import { serverSentEvents } from "../../infrastructure/sse.js";
3
+ import { MODEL_MAX_TIMEOUT_MS, MODEL_RESPONSE_BYTES, MODEL_TIMEOUT_MS, } from "./model.constants.js";
4
+ import { validateModelRequest } from "./model-request.js";
5
+ import { modelJson } from "./model-http.js";
6
+ export function httpModelProvider(options, protocol, name, headers) {
7
+ let base;
8
+ try {
9
+ base = new URL(options.baseUrl);
10
+ }
11
+ catch {
12
+ throw new OutpostError("configuration", "Model baseUrl must be an absolute HTTP(S) URL");
13
+ }
14
+ invariant(["http:", "https:"].includes(base.protocol) &&
15
+ !base.username &&
16
+ !base.password &&
17
+ !base.search &&
18
+ !base.hash, "Model baseUrl must use HTTP(S) without credentials, query or fragment");
19
+ invariant(options.apiKey === false ||
20
+ (typeof options.apiKey === "string" &&
21
+ options.apiKey.trim() &&
22
+ !/[\r\n]/.test(options.apiKey)), "Model apiKey must be a nonempty key or false for unauthenticated endpoints");
23
+ const endpoint = `${base.href.replace(/\/+$/, "")}/${protocol.path}`;
24
+ const timeoutMs = positive(options.timeoutMs ?? MODEL_TIMEOUT_MS, "Model timeoutMs");
25
+ invariant(timeoutMs <= MODEL_MAX_TIMEOUT_MS, "Model timeoutMs exceeds the supported timer range");
26
+ const maxBytes = positive(options.maxResponseBytes ?? MODEL_RESPONSE_BYTES, "Model maxResponseBytes");
27
+ const identity = `${name}:${protocol.path}:${base.origin}${base.pathname.replace(/\/+$/, "")}`;
28
+ const post = async (body, signal) => {
29
+ signal.throwIfAborted();
30
+ const response = await fetch(endpoint, {
31
+ method: "POST",
32
+ redirect: "error",
33
+ headers: { "Content-Type": "application/json", ...headers },
34
+ body: JSON.stringify(body),
35
+ signal,
36
+ });
37
+ if (response.ok)
38
+ return response;
39
+ await response.body?.cancel();
40
+ throw new OutpostError("provider", `Model request failed with HTTP ${response.status}`, { status: response.status });
41
+ };
42
+ const failure = (error, signal, deadline, request) => {
43
+ if (signal.aborted) {
44
+ const timedOut = deadline.aborted && !request.signal?.aborted;
45
+ return new OutpostError(timedOut ? "timeout" : "aborted", timedOut ? "Model request timed out" : "Model request was cancelled");
46
+ }
47
+ if (error instanceof OutpostError)
48
+ return error;
49
+ return new OutpostError("provider", "Model request failed during HTTP transport");
50
+ };
51
+ async function* stream(request) {
52
+ validateModelRequest(request);
53
+ const streaming = protocol.stream;
54
+ const context = { identity, model: request.model };
55
+ const deadline = new AbortController();
56
+ const signal = request.signal
57
+ ? AbortSignal.any([request.signal, deadline.signal])
58
+ : deadline.signal;
59
+ let timer = setTimeout(() => deadline.abort(), timeoutMs);
60
+ const refresh = () => {
61
+ clearTimeout(timer);
62
+ timer = setTimeout(() => deadline.abort(), timeoutMs);
63
+ };
64
+ try {
65
+ const response = await post({ ...protocol.build(request, context), ...streaming.body }, signal);
66
+ if (!response.body)
67
+ throw new OutpostError("response", "Model response has no body");
68
+ const decoder = streaming.decoder();
69
+ for await (const event of serverSentEvents(response.body, maxBytes, refresh)) {
70
+ signal.throwIfAborted();
71
+ const text = decoder.push(event);
72
+ if (text)
73
+ yield { type: "text-delta", text };
74
+ }
75
+ signal.throwIfAborted();
76
+ yield { type: "result", result: protocol.read(decoder.final(), context) };
77
+ }
78
+ catch (error) {
79
+ throw failure(error, signal, deadline.signal, request);
80
+ }
81
+ finally {
82
+ clearTimeout(timer);
83
+ }
84
+ }
85
+ return Object.freeze({
86
+ name,
87
+ identity,
88
+ ...(protocol.validate ? { validate: protocol.validate } : {}),
89
+ ...(protocol.stream ? { stream } : {}),
90
+ async request(request) {
91
+ validateModelRequest(request);
92
+ const context = { identity, model: request.model };
93
+ const deadline = new AbortController();
94
+ const signal = request.signal
95
+ ? AbortSignal.any([request.signal, deadline.signal])
96
+ : deadline.signal;
97
+ const timer = setTimeout(() => deadline.abort(), timeoutMs);
98
+ try {
99
+ const response = await post(protocol.build(request, context), signal);
100
+ const value = await modelJson(response, maxBytes);
101
+ signal.throwIfAborted();
102
+ return protocol.read(value, context);
103
+ }
104
+ catch (error) {
105
+ throw failure(error, signal, deadline.signal, request);
106
+ }
107
+ finally {
108
+ clearTimeout(timer);
109
+ }
110
+ },
111
+ });
112
+ }
113
+ //# sourceMappingURL=http-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-provider.js","sourceRoot":"","sources":["../../../src/adapters/models/http-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant, OutpostError, positive } from \"../../domain/errors.ts\";\nimport type {\n ModelProvider,\n ModelRequest,\n ModelStreamEvent,\n} from \"../../domain/model.types.ts\";\nimport { serverSentEvents } from \"../../infrastructure/sse.ts\";\nimport type {\n HttpModelOptions,\n ModelProtocol,\n} from \"./model-protocol.types.ts\";\nimport {\n MODEL_MAX_TIMEOUT_MS,\n MODEL_RESPONSE_BYTES,\n MODEL_TIMEOUT_MS,\n} from \"./model.constants.ts\";\nimport { validateModelRequest } from \"./model-request.ts\";\nimport { modelJson } from \"./model-http.ts\";\n\nexport function httpModelProvider(\n options: HttpModelOptions,\n protocol: ModelProtocol,\n name: string,\n headers: Readonly<Record<string, string>>,\n): ModelProvider {\n let base: URL;\n try {\n base = new URL(options.baseUrl);\n } catch {\n throw new OutpostError(\n \"configuration\",\n \"Model baseUrl must be an absolute HTTP(S) URL\",\n );\n }\n invariant(\n [\"http:\", \"https:\"].includes(base.protocol) &&\n !base.username &&\n !base.password &&\n !base.search &&\n !base.hash,\n \"Model baseUrl must use HTTP(S) without credentials, query or fragment\",\n );\n invariant(\n options.apiKey === false ||\n (typeof options.apiKey === \"string\" &&\n options.apiKey.trim() &&\n !/[\\r\\n]/.test(options.apiKey)),\n \"Model apiKey must be a nonempty key or false for unauthenticated endpoints\",\n );\n const endpoint = `${base.href.replace(/\\/+$/, \"\")}/${protocol.path}`;\n const timeoutMs = positive(\n options.timeoutMs ?? MODEL_TIMEOUT_MS,\n \"Model timeoutMs\",\n );\n invariant(\n timeoutMs <= MODEL_MAX_TIMEOUT_MS,\n \"Model timeoutMs exceeds the supported timer range\",\n );\n const maxBytes = positive(\n options.maxResponseBytes ?? MODEL_RESPONSE_BYTES,\n \"Model maxResponseBytes\",\n );\n const identity = `${name}:${protocol.path}:${base.origin}${base.pathname.replace(/\\/+$/, \"\")}`;\n const post = async (body: unknown, signal: AbortSignal) => {\n signal.throwIfAborted();\n const response = await fetch(endpoint, {\n method: \"POST\",\n redirect: \"error\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n signal,\n });\n if (response.ok) return response;\n await response.body?.cancel();\n throw new OutpostError(\n \"provider\",\n `Model request failed with HTTP ${response.status}`,\n { status: response.status },\n );\n };\n const failure = (\n error: unknown,\n signal: AbortSignal,\n deadline: AbortSignal,\n request: ModelRequest,\n ): OutpostError => {\n if (signal.aborted) {\n const timedOut = deadline.aborted && !request.signal?.aborted;\n return new OutpostError(\n timedOut ? \"timeout\" : \"aborted\",\n timedOut ? \"Model request timed out\" : \"Model request was cancelled\",\n );\n }\n if (error instanceof OutpostError) return error;\n return new OutpostError(\n \"provider\",\n \"Model request failed during HTTP transport\",\n );\n };\n async function* stream(\n request: ModelRequest,\n ): AsyncGenerator<ModelStreamEvent> {\n validateModelRequest(request);\n const streaming = protocol.stream!;\n const context = { identity, model: request.model };\n const deadline = new AbortController();\n const signal = request.signal\n ? AbortSignal.any([request.signal, deadline.signal])\n : deadline.signal;\n let timer = setTimeout(() => deadline.abort(), timeoutMs);\n const refresh = () => {\n clearTimeout(timer);\n timer = setTimeout(() => deadline.abort(), timeoutMs);\n };\n try {\n const response = await post(\n { ...protocol.build(request, context), ...streaming.body },\n signal,\n );\n if (!response.body)\n throw new OutpostError(\"response\", \"Model response has no body\");\n const decoder = streaming.decoder();\n for await (const event of serverSentEvents(\n response.body,\n maxBytes,\n refresh,\n )) {\n signal.throwIfAborted();\n const text = decoder.push(event);\n if (text) yield { type: \"text-delta\", text };\n }\n signal.throwIfAborted();\n yield { type: \"result\", result: protocol.read(decoder.final(), context) };\n } catch (error) {\n throw failure(error, signal, deadline.signal, request);\n } finally {\n clearTimeout(timer);\n }\n }\n return Object.freeze({\n name,\n identity,\n ...(protocol.validate ? { validate: protocol.validate } : {}),\n ...(protocol.stream ? { stream } : {}),\n async request(request: ModelRequest) {\n validateModelRequest(request);\n const context = { identity, model: request.model };\n const deadline = new AbortController();\n const signal = request.signal\n ? AbortSignal.any([request.signal, deadline.signal])\n : deadline.signal;\n const timer = setTimeout(() => deadline.abort(), timeoutMs);\n try {\n const response = await post(protocol.build(request, context), signal);\n const value = await modelJson(response, maxBytes);\n signal.throwIfAborted();\n return protocol.read(value, context);\n } catch (error) {\n throw failure(error, signal, deadline.signal, request);\n } finally {\n clearTimeout(timer);\n }\n },\n });\n}\n"]}
@@ -27,4 +27,4 @@ export async function modelJson(response, maxBytes) {
27
27
  throw new OutpostError("response", "Model response is not valid JSON");
28
28
  }
29
29
  }
30
- //# sourceMappingURL=openai-http.js.map
30
+ //# sourceMappingURL=model-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-http.js","sourceRoot":"","sources":["../../../src/adapters/models/model-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAkB,EAClB,QAAgB;IAEhB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1C,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC;YACzB,IAAI,IAAI,GAAG,QAAQ;gBACjB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,yCAAyC,CAC1C,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,kCAAkC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC","sourcesContent":["import { OutpostError } from \"../../domain/errors.ts\";\n\nexport async function modelJson(\n response: Response,\n maxBytes: number,\n): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) throw new OutpostError(\"response\", \"Model response has no body\");\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maxBytes)\n throw new OutpostError(\n \"response\",\n \"Model response exceeds maxResponseBytes\",\n );\n chunks.push(value);\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n }\n try {\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n } catch {\n throw new OutpostError(\"response\", \"Model response is not valid JSON\");\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import type { ServerSentEvent } from "../../infrastructure/sse.types.ts";
2
+ import type { AgentModel, ModelContentBlock, ModelRequest, ModelResult } from "../../domain/model.types.ts";
3
+ export interface HttpModelOptions {
4
+ readonly baseUrl: string;
5
+ readonly apiKey: string | false;
6
+ readonly timeoutMs?: number;
7
+ readonly maxResponseBytes?: number;
8
+ }
9
+ export interface ProtocolContext {
10
+ readonly identity: string;
11
+ readonly model: string;
12
+ }
13
+ export interface StreamDecoder {
14
+ push(event: ServerSentEvent): string | undefined;
15
+ final(): unknown;
16
+ }
17
+ export interface StreamProtocol {
18
+ readonly body: Readonly<Record<string, unknown>>;
19
+ decoder(): StreamDecoder;
20
+ }
21
+ export interface ModelProtocol {
22
+ readonly path: string;
23
+ readonly stream?: StreamProtocol;
24
+ validate?(model: AgentModel): void;
25
+ build(request: ModelRequest, context: ProtocolContext): Record<string, unknown>;
26
+ read(value: unknown, context: ProtocolContext): ModelResult;
27
+ }
28
+ export type BlockEncoders<Extra extends unknown[] = []> = {
29
+ readonly [Type in ModelContentBlock["type"]]: (block: Extract<ModelContentBlock, {
30
+ type: Type;
31
+ }>, ...extra: Extra) => unknown;
32
+ };
33
+ export interface ChatToolCallDraft {
34
+ id?: string;
35
+ readonly type: "function";
36
+ readonly function: ChatFunctionDraft;
37
+ }
38
+ export interface ChatFunctionDraft {
39
+ name?: string;
40
+ arguments: string;
41
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model-protocol.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-protocol.types.js","sourceRoot":"","sources":["../../../src/adapters/models/model-protocol.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ServerSentEvent } from \"../../infrastructure/sse.types.ts\";\nimport type {\n AgentModel,\n ModelContentBlock,\n ModelRequest,\n ModelResult,\n} from \"../../domain/model.types.ts\";\n\nexport interface HttpModelOptions {\n readonly baseUrl: string;\n readonly apiKey: string | false;\n readonly timeoutMs?: number;\n readonly maxResponseBytes?: number;\n}\n\nexport interface ProtocolContext {\n readonly identity: string;\n readonly model: string;\n}\n\nexport interface StreamDecoder {\n push(event: ServerSentEvent): string | undefined;\n final(): unknown;\n}\n\nexport interface StreamProtocol {\n readonly body: Readonly<Record<string, unknown>>;\n decoder(): StreamDecoder;\n}\n\nexport interface ModelProtocol {\n readonly path: string;\n readonly stream?: StreamProtocol;\n validate?(model: AgentModel): void;\n build(\n request: ModelRequest,\n context: ProtocolContext,\n ): Record<string, unknown>;\n read(value: unknown, context: ProtocolContext): ModelResult;\n}\n\nexport type BlockEncoders<Extra extends unknown[] = []> = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ...extra: Extra\n ) => unknown;\n};\n\nexport interface ChatToolCallDraft {\n id?: string;\n readonly type: \"function\";\n readonly function: ChatFunctionDraft;\n}\n\nexport interface ChatFunctionDraft {\n name?: string;\n arguments: string;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { ModelRequest } from "../../domain/model.types.ts";
2
+ export declare function validateModelRequest(request: ModelRequest): void;