indusagi 0.13.5 → 0.13.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 (435) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +7 -1
  3. package/dist/cli.js +114 -23
  4. package/package.json +56 -45
  5. package/dist/agent.js +0 -28713
  6. package/dist/ai.js +0 -19964
  7. package/dist/capabilities.js +0 -2730
  8. package/dist/connectors-saas.js +0 -3355
  9. package/dist/index.js +0 -16644
  10. package/dist/interop.js +0 -3247
  11. package/dist/knowledge/guides/authoring-an-agent.md +0 -53
  12. package/dist/knowledge/guides/choosing-tools.md +0 -49
  13. package/dist/knowledge/guides/model-selection.md +0 -51
  14. package/dist/knowledge/guides/writing-system-prompts.md +0 -53
  15. package/dist/knowledge/index.ts +0 -19
  16. package/dist/knowledge/loader.ts +0 -200
  17. package/dist/knowledge/manifest.json +0 -29
  18. package/dist/llmgateway.js +0 -3243
  19. package/dist/mcp.js +0 -1639
  20. package/dist/memory.js +0 -0
  21. package/dist/react-host/index.js +0 -101
  22. package/dist/react-host/ink.js +0 -97
  23. package/dist/react-host/jsx-runtime.js +0 -95
  24. package/dist/react-ink.js +0 -3834
  25. package/dist/runtime.js +0 -4421
  26. package/dist/shell-app.js +0 -12333
  27. package/dist/smithy.js +0 -8033
  28. package/dist/swarm.js +0 -8818
  29. package/dist/tracing.js +0 -724
  30. package/dist/tui.js +0 -2213
  31. package/dist/types/capabilities/backends/index.d.ts +0 -10
  32. package/dist/types/capabilities/backends/node-backends.d.ts +0 -30
  33. package/dist/types/capabilities/capabilities.test.d.ts +0 -14
  34. package/dist/types/capabilities/files/diff.d.ts +0 -49
  35. package/dist/types/capabilities/files/edit.d.ts +0 -21
  36. package/dist/types/capabilities/files/ls.d.ts +0 -16
  37. package/dist/types/capabilities/files/read-state-gate.d.ts +0 -69
  38. package/dist/types/capabilities/files/read-state-gate.test.d.ts +0 -14
  39. package/dist/types/capabilities/files/read.d.ts +0 -15
  40. package/dist/types/capabilities/files/write.d.ts +0 -16
  41. package/dist/types/capabilities/index.d.ts +0 -29
  42. package/dist/types/capabilities/kernel/backends.d.ts +0 -119
  43. package/dist/types/capabilities/kernel/context.d.ts +0 -52
  44. package/dist/types/capabilities/kernel/index.d.ts +0 -24
  45. package/dist/types/capabilities/kernel/output.d.ts +0 -40
  46. package/dist/types/capabilities/kernel/registry.d.ts +0 -61
  47. package/dist/types/capabilities/kernel/spec.d.ts +0 -168
  48. package/dist/types/capabilities/planning/todo.d.ts +0 -62
  49. package/dist/types/capabilities/registry.d.ts +0 -44
  50. package/dist/types/capabilities/search/find.d.ts +0 -33
  51. package/dist/types/capabilities/search/grep.d.ts +0 -30
  52. package/dist/types/capabilities/shell/bash.d.ts +0 -18
  53. package/dist/types/capabilities/shell/process.d.ts +0 -33
  54. package/dist/types/capabilities/web/webfetch.d.ts +0 -25
  55. package/dist/types/capabilities/web/websearch.d.ts +0 -23
  56. package/dist/types/connectors-saas/connectors-saas.test.d.ts +0 -12
  57. package/dist/types/connectors-saas/index.d.ts +0 -16
  58. package/dist/types/connectors-saas/saas/adapter/composio-backend.d.ts +0 -60
  59. package/dist/types/connectors-saas/saas/control/connect.d.ts +0 -114
  60. package/dist/types/connectors-saas/saas/control/tools.d.ts +0 -67
  61. package/dist/types/connectors-saas/saas/core/builder.d.ts +0 -86
  62. package/dist/types/connectors-saas/saas/core/cache.d.ts +0 -53
  63. package/dist/types/connectors-saas/saas/core/index.d.ts +0 -14
  64. package/dist/types/connectors-saas/saas/core/port.d.ts +0 -157
  65. package/dist/types/connectors-saas/saas/core/scope-planner.d.ts +0 -74
  66. package/dist/types/connectors-saas/saas/gateway.d.ts +0 -133
  67. package/dist/types/connectors-saas/saas/render/format.d.ts +0 -54
  68. package/dist/types/connectors-saas/saas/render/index.d.ts +0 -19
  69. package/dist/types/connectors-saas/saas/render/summarizers.d.ts +0 -58
  70. package/dist/types/facade/agent.d.ts +0 -1
  71. package/dist/types/facade/ai.d.ts +0 -1
  72. package/dist/types/facade/bot/actions/bash.d.ts +0 -71
  73. package/dist/types/facade/bot/actions/bash.test.d.ts +0 -1
  74. package/dist/types/facade/bot/actions/checkpoint.d.ts +0 -49
  75. package/dist/types/facade/bot/actions/checkpoint.test.d.ts +0 -1
  76. package/dist/types/facade/bot/actions/composio/accounts.d.ts +0 -22
  77. package/dist/types/facade/bot/actions/composio/client.d.ts +0 -39
  78. package/dist/types/facade/bot/actions/composio/connect.d.ts +0 -19
  79. package/dist/types/facade/bot/actions/composio/enable.d.ts +0 -25
  80. package/dist/types/facade/bot/actions/composio/execute.d.ts +0 -26
  81. package/dist/types/facade/bot/actions/composio/helpers.d.ts +0 -16
  82. package/dist/types/facade/bot/actions/composio/index.d.ts +0 -9
  83. package/dist/types/facade/bot/actions/composio/provider.d.ts +0 -8
  84. package/dist/types/facade/bot/actions/composio/toolkits.d.ts +0 -22
  85. package/dist/types/facade/bot/actions/composio/tools.d.ts +0 -28
  86. package/dist/types/facade/bot/actions/composio/types.d.ts +0 -137
  87. package/dist/types/facade/bot/actions/crew/activity-tracker.d.ts +0 -65
  88. package/dist/types/facade/bot/actions/crew/cleanup.d.ts +0 -50
  89. package/dist/types/facade/bot/actions/crew/fs-lock.d.ts +0 -11
  90. package/dist/types/facade/bot/actions/crew/index.d.ts +0 -11
  91. package/dist/types/facade/bot/actions/crew/mailbox.d.ts +0 -20
  92. package/dist/types/facade/bot/actions/crew/model-policy.d.ts +0 -22
  93. package/dist/types/facade/bot/actions/crew/names.d.ts +0 -27
  94. package/dist/types/facade/bot/actions/crew/protocol.d.ts +0 -74
  95. package/dist/types/facade/bot/actions/crew/task-store.d.ts +0 -88
  96. package/dist/types/facade/bot/actions/crew/team-attach-claim.d.ts +0 -35
  97. package/dist/types/facade/bot/actions/crew/team-config.d.ts +0 -54
  98. package/dist/types/facade/bot/actions/crew/worktree.d.ts +0 -39
  99. package/dist/types/facade/bot/actions/edit-diff.d.ts +0 -66
  100. package/dist/types/facade/bot/actions/edit-utils.d.ts +0 -86
  101. package/dist/types/facade/bot/actions/edit.d.ts +0 -59
  102. package/dist/types/facade/bot/actions/edit.test.d.ts +0 -1
  103. package/dist/types/facade/bot/actions/find.d.ts +0 -27
  104. package/dist/types/facade/bot/actions/find.test.d.ts +0 -1
  105. package/dist/types/facade/bot/actions/grep.d.ts +0 -53
  106. package/dist/types/facade/bot/actions/grep.test.d.ts +0 -1
  107. package/dist/types/facade/bot/actions/index.d.ts +0 -316
  108. package/dist/types/facade/bot/actions/kit/hook-runner.d.ts +0 -12
  109. package/dist/types/facade/bot/actions/kit/image-resize.d.ts +0 -19
  110. package/dist/types/facade/bot/actions/kit/mime.d.ts +0 -1
  111. package/dist/types/facade/bot/actions/kit/shell.d.ts +0 -12
  112. package/dist/types/facade/bot/actions/ls.d.ts +0 -41
  113. package/dist/types/facade/bot/actions/path-utils.d.ts +0 -8
  114. package/dist/types/facade/bot/actions/process-controller.d.ts +0 -14
  115. package/dist/types/facade/bot/actions/process-manager.d.ts +0 -59
  116. package/dist/types/facade/bot/actions/process-types.d.ts +0 -73
  117. package/dist/types/facade/bot/actions/process.d.ts +0 -37
  118. package/dist/types/facade/bot/actions/read-state.d.ts +0 -83
  119. package/dist/types/facade/bot/actions/read-state.test.d.ts +0 -1
  120. package/dist/types/facade/bot/actions/read.d.ts +0 -43
  121. package/dist/types/facade/bot/actions/read.test.d.ts +0 -1
  122. package/dist/types/facade/bot/actions/registry.d.ts +0 -20
  123. package/dist/types/facade/bot/actions/sandbox-backend.d.ts +0 -99
  124. package/dist/types/facade/bot/actions/sandbox-backend.test.d.ts +0 -1
  125. package/dist/types/facade/bot/actions/todo-store.d.ts +0 -76
  126. package/dist/types/facade/bot/actions/todo-types.d.ts +0 -72
  127. package/dist/types/facade/bot/actions/todo.d.ts +0 -76
  128. package/dist/types/facade/bot/actions/truncate.d.ts +0 -78
  129. package/dist/types/facade/bot/actions/webfetch.d.ts +0 -35
  130. package/dist/types/facade/bot/actions/websearch.d.ts +0 -37
  131. package/dist/types/facade/bot/actions/websearch.test.d.ts +0 -1
  132. package/dist/types/facade/bot/actions/write.d.ts +0 -45
  133. package/dist/types/facade/bot/agent-loop.d.ts +0 -30
  134. package/dist/types/facade/bot/agent-loop.test.d.ts +0 -1
  135. package/dist/types/facade/bot/agent.d.ts +0 -140
  136. package/dist/types/facade/bot/error-handler.d.ts +0 -7
  137. package/dist/types/facade/bot/event-bus.d.ts +0 -8
  138. package/dist/types/facade/bot/index.d.ts +0 -7
  139. package/dist/types/facade/bot/messages.d.ts +0 -83
  140. package/dist/types/facade/bot/permission-gate.test.d.ts +0 -1
  141. package/dist/types/facade/bot/proxy.d.ts +0 -70
  142. package/dist/types/facade/bot/session-manager.d.ts +0 -409
  143. package/dist/types/facade/bot/state-manager.d.ts +0 -21
  144. package/dist/types/facade/bot/telemetry.d.ts +0 -6
  145. package/dist/types/facade/bot/types.d.ts +0 -267
  146. package/dist/types/facade/mcp-core/client-pool.d.ts +0 -105
  147. package/dist/types/facade/mcp-core/client.d.ts +0 -213
  148. package/dist/types/facade/mcp-core/client.test.d.ts +0 -18
  149. package/dist/types/facade/mcp-core/config.d.ts +0 -60
  150. package/dist/types/facade/mcp-core/errors.d.ts +0 -103
  151. package/dist/types/facade/mcp-core/index.d.ts +0 -55
  152. package/dist/types/facade/mcp-core/schema-converter.d.ts +0 -67
  153. package/dist/types/facade/mcp-core/server.d.ts +0 -110
  154. package/dist/types/facade/mcp-core/tool-factory.d.ts +0 -62
  155. package/dist/types/facade/mcp-core/types.d.ts +0 -298
  156. package/dist/types/facade/mcp.d.ts +0 -1
  157. package/dist/types/facade/memory.d.ts +0 -1
  158. package/dist/types/facade/ml/adapters/amazon-bedrock.d.ts +0 -32
  159. package/dist/types/facade/ml/adapters/anthropic-retry.test.d.ts +0 -1
  160. package/dist/types/facade/ml/adapters/anthropic.d.ts +0 -78
  161. package/dist/types/facade/ml/adapters/azure-openai-responses.d.ts +0 -14
  162. package/dist/types/facade/ml/adapters/google-shared.d.ts +0 -99
  163. package/dist/types/facade/ml/adapters/google-vertex.d.ts +0 -14
  164. package/dist/types/facade/ml/adapters/google.d.ts +0 -15
  165. package/dist/types/facade/ml/adapters/kimi.d.ts +0 -21
  166. package/dist/types/facade/ml/adapters/mock.d.ts +0 -9
  167. package/dist/types/facade/ml/adapters/nvidia.d.ts +0 -12
  168. package/dist/types/facade/ml/adapters/openai-codex-responses.d.ts +0 -8
  169. package/dist/types/facade/ml/adapters/openai-completions.d.ts +0 -24
  170. package/dist/types/facade/ml/adapters/openai-responses-shared.d.ts +0 -25
  171. package/dist/types/facade/ml/adapters/openai-responses.d.ts +0 -12
  172. package/dist/types/facade/ml/adapters/openai-scaffold.d.ts +0 -3
  173. package/dist/types/facade/ml/adapters/register-builtins.d.ts +0 -2
  174. package/dist/types/facade/ml/adapters/simple-options.d.ts +0 -39
  175. package/dist/types/facade/ml/adapters/simple-options.test.d.ts +0 -1
  176. package/dist/types/facade/ml/adapters/transform-messages.d.ts +0 -23
  177. package/dist/types/facade/ml/api-registry.d.ts +0 -49
  178. package/dist/types/facade/ml/cli.d.ts +0 -2
  179. package/dist/types/facade/ml/env-api-keys.d.ts +0 -19
  180. package/dist/types/facade/ml/index.d.ts +0 -27
  181. package/dist/types/facade/ml/kit/auth/anthropic.d.ts +0 -17
  182. package/dist/types/facade/ml/kit/auth/github-copilot.d.ts +0 -22
  183. package/dist/types/facade/ml/kit/auth/index.d.ts +0 -50
  184. package/dist/types/facade/ml/kit/auth/kimi.d.ts +0 -23
  185. package/dist/types/facade/ml/kit/auth/oauth-page.d.ts +0 -2
  186. package/dist/types/facade/ml/kit/auth/openai-codex.d.ts +0 -36
  187. package/dist/types/facade/ml/kit/auth/pkce.d.ts +0 -12
  188. package/dist/types/facade/ml/kit/auth/types.d.ts +0 -67
  189. package/dist/types/facade/ml/kit/base-stream-handler.d.ts +0 -30
  190. package/dist/types/facade/ml/kit/event-stream.d.ts +0 -63
  191. package/dist/types/facade/ml/kit/index.d.ts +0 -14
  192. package/dist/types/facade/ml/kit/json-parse.d.ts +0 -23
  193. package/dist/types/facade/ml/kit/message-transform.d.ts +0 -32
  194. package/dist/types/facade/ml/kit/output-factory.d.ts +0 -8
  195. package/dist/types/facade/ml/kit/overflow.d.ts +0 -9
  196. package/dist/types/facade/ml/kit/provider-adapter.d.ts +0 -56
  197. package/dist/types/facade/ml/kit/provider-client-builder.d.ts +0 -36
  198. package/dist/types/facade/ml/kit/provider-consolidation.d.ts +0 -3
  199. package/dist/types/facade/ml/kit/provider-constants.d.ts +0 -34
  200. package/dist/types/facade/ml/kit/provider-errors.d.ts +0 -52
  201. package/dist/types/facade/ml/kit/sanitize-unicode.d.ts +0 -2
  202. package/dist/types/facade/ml/kit/stream-event-helper.d.ts +0 -38
  203. package/dist/types/facade/ml/kit/stream-handler-types.d.ts +0 -46
  204. package/dist/types/facade/ml/kit/streaming-state-manager.d.ts +0 -42
  205. package/dist/types/facade/ml/kit/tool-converter.d.ts +0 -49
  206. package/dist/types/facade/ml/kit/typebox-helpers.d.ts +0 -24
  207. package/dist/types/facade/ml/kit/validation.d.ts +0 -26
  208. package/dist/types/facade/ml/models.d.ts +0 -41
  209. package/dist/types/facade/ml/models.generated.d.ts +0 -12405
  210. package/dist/types/facade/ml/stream.d.ts +0 -27
  211. package/dist/types/facade/ml/types.d.ts +0 -269
  212. package/dist/types/index.d.ts +0 -16
  213. package/dist/types/interop/index.d.ts +0 -12
  214. package/dist/types/interop/interop.test.d.ts +0 -19
  215. package/dist/types/interop/protocol-bridge/bridge.d.ts +0 -52
  216. package/dist/types/interop/protocol-bridge/contract.d.ts +0 -249
  217. package/dist/types/interop/protocol-bridge/endpoint.d.ts +0 -124
  218. package/dist/types/interop/protocol-bridge/fleet.d.ts +0 -92
  219. package/dist/types/interop/protocol-bridge/host.d.ts +0 -61
  220. package/dist/types/interop/protocol-bridge/index.d.ts +0 -16
  221. package/dist/types/interop/protocol-bridge/schema.d.ts +0 -29
  222. package/dist/types/llmgateway/catalog/cards.d.ts +0 -18
  223. package/dist/types/llmgateway/catalog/cost.d.ts +0 -15
  224. package/dist/types/llmgateway/catalog/index.d.ts +0 -7
  225. package/dist/types/llmgateway/catalog/query.d.ts +0 -40
  226. package/dist/types/llmgateway/connectors/anthropic.d.ts +0 -35
  227. package/dist/types/llmgateway/connectors/azure-openai.d.ts +0 -33
  228. package/dist/types/llmgateway/connectors/bedrock.d.ts +0 -113
  229. package/dist/types/llmgateway/connectors/google-vertex.d.ts +0 -38
  230. package/dist/types/llmgateway/connectors/google.d.ts +0 -40
  231. package/dist/types/llmgateway/connectors/index.d.ts +0 -26
  232. package/dist/types/llmgateway/connectors/kimi.d.ts +0 -28
  233. package/dist/types/llmgateway/connectors/mock.d.ts +0 -37
  234. package/dist/types/llmgateway/connectors/nvidia.d.ts +0 -27
  235. package/dist/types/llmgateway/connectors/ollama.d.ts +0 -45
  236. package/dist/types/llmgateway/connectors/openai-chat.d.ts +0 -25
  237. package/dist/types/llmgateway/connectors/openai-responses.d.ts +0 -49
  238. package/dist/types/llmgateway/contract/connector.d.ts +0 -32
  239. package/dist/types/llmgateway/contract/conversation.d.ts +0 -86
  240. package/dist/types/llmgateway/contract/emission.d.ts +0 -55
  241. package/dist/types/llmgateway/contract/errors.d.ts +0 -27
  242. package/dist/types/llmgateway/contract/index.d.ts +0 -13
  243. package/dist/types/llmgateway/contract/model-card.d.ts +0 -42
  244. package/dist/types/llmgateway/contract/options.d.ts +0 -31
  245. package/dist/types/llmgateway/contract/reply.d.ts +0 -33
  246. package/dist/types/llmgateway/conversion/index.d.ts +0 -10
  247. package/dist/types/llmgateway/conversion/mappers.d.ts +0 -65
  248. package/dist/types/llmgateway/conversion/openai-compatible.d.ts +0 -46
  249. package/dist/types/llmgateway/conversion/reduce.d.ts +0 -20
  250. package/dist/types/llmgateway/credentials/oauth.d.ts +0 -73
  251. package/dist/types/llmgateway/credentials/pkce.d.ts +0 -52
  252. package/dist/types/llmgateway/credentials/secrets.d.ts +0 -74
  253. package/dist/types/llmgateway/gateway.d.ts +0 -34
  254. package/dist/types/llmgateway/gateway.test.d.ts +0 -14
  255. package/dist/types/llmgateway/index.d.ts +0 -11
  256. package/dist/types/llmgateway/streaming/channel.d.ts +0 -24
  257. package/dist/types/llmgateway/streaming/index.d.ts +0 -10
  258. package/dist/types/llmgateway/streaming/ndjson.d.ts +0 -17
  259. package/dist/types/llmgateway/streaming/sse.d.ts +0 -31
  260. package/dist/types/react-host/index.d.ts +0 -9
  261. package/dist/types/react-host/ink.d.ts +0 -5
  262. package/dist/types/react-host/jsx-runtime.d.ts +0 -4
  263. package/dist/types/react-host/loader.d.ts +0 -3
  264. package/dist/types/react-ink/components/ChangelogBlock.d.ts +0 -8
  265. package/dist/types/react-ink/components/DisplayBlockView.d.ts +0 -8
  266. package/dist/types/react-ink/components/Footer.d.ts +0 -11
  267. package/dist/types/react-ink/components/MessageList.d.ts +0 -14
  268. package/dist/types/react-ink/components/MessageRow.d.ts +0 -13
  269. package/dist/types/react-ink/components/StatusLine.d.ts +0 -18
  270. package/dist/types/react-ink/components/TaskPanel.d.ts +0 -11
  271. package/dist/types/react-ink/components/ToolEventBlock.d.ts +0 -48
  272. package/dist/types/react-ink/components/ToolEventBlock.test.d.ts +0 -1
  273. package/dist/types/react-ink/components/dialogs/DialogFrame.d.ts +0 -8
  274. package/dist/types/react-ink/components/dialogs/LoginDialog.d.ts +0 -14
  275. package/dist/types/react-ink/components/dialogs/ModelDialog.d.ts +0 -9
  276. package/dist/types/react-ink/components/dialogs/OAuthDialog.d.ts +0 -9
  277. package/dist/types/react-ink/components/dialogs/ScopedModelsDialog.d.ts +0 -9
  278. package/dist/types/react-ink/components/dialogs/SelectableDialog.d.ts +0 -22
  279. package/dist/types/react-ink/components/dialogs/SessionDialog.d.ts +0 -13
  280. package/dist/types/react-ink/components/dialogs/SettingsDialog.d.ts +0 -14
  281. package/dist/types/react-ink/components/dialogs/StartupSessionPicker.d.ts +0 -9
  282. package/dist/types/react-ink/components/dialogs/ThemeDialog.d.ts +0 -26
  283. package/dist/types/react-ink/components/dialogs/TreeDialog.d.ts +0 -8
  284. package/dist/types/react-ink/components/dialogs/UserMessageDialog.d.ts +0 -8
  285. package/dist/types/react-ink/components/messages/AssistantMessage.d.ts +0 -12
  286. package/dist/types/react-ink/components/messages/BashMessage.d.ts +0 -8
  287. package/dist/types/react-ink/components/messages/BranchSummaryMessage.d.ts +0 -8
  288. package/dist/types/react-ink/components/messages/CompactionMessage.d.ts +0 -8
  289. package/dist/types/react-ink/components/messages/CustomMessage.d.ts +0 -9
  290. package/dist/types/react-ink/components/messages/SkillInvocationMessage.d.ts +0 -7
  291. package/dist/types/react-ink/components/messages/ToolCallMessage.d.ts +0 -8
  292. package/dist/types/react-ink/components/messages/ToolResultBlock.d.ts +0 -12
  293. package/dist/types/react-ink/components/messages/UserMessage.d.ts +0 -9
  294. package/dist/types/react-ink/diff/Diff.d.ts +0 -22
  295. package/dist/types/react-ink/diff/diff.test.d.ts +0 -1
  296. package/dist/types/react-ink/diff/structured.d.ts +0 -41
  297. package/dist/types/react-ink/diff/word-diff.d.ts +0 -27
  298. package/dist/types/react-ink/index.d.ts +0 -42
  299. package/dist/types/react-ink/markdown/Markdown.d.ts +0 -23
  300. package/dist/types/react-ink/markdown/MarkdownTable.d.ts +0 -19
  301. package/dist/types/react-ink/markdown/StreamingMarkdown.d.ts +0 -34
  302. package/dist/types/react-ink/markdown/format-token.d.ts +0 -39
  303. package/dist/types/react-ink/markdown/highlight.d.ts +0 -31
  304. package/dist/types/react-ink/theme-adapter.d.ts +0 -66
  305. package/dist/types/react-ink/types.d.ts +0 -133
  306. package/dist/types/react-ink/utils/message-groups.d.ts +0 -25
  307. package/dist/types/react-ink/utils/selection-dialog.d.ts +0 -2
  308. package/dist/types/react-ink/utils/session-browser.d.ts +0 -27
  309. package/dist/types/react-ink/utils/tool-display.d.ts +0 -37
  310. package/dist/types/runtime/cadence/cadence.test.d.ts +0 -6
  311. package/dist/types/runtime/cadence/fold.d.ts +0 -48
  312. package/dist/types/runtime/cadence/index.d.ts +0 -12
  313. package/dist/types/runtime/cadence/reducer.d.ts +0 -44
  314. package/dist/types/runtime/conductor/agent.d.ts +0 -71
  315. package/dist/types/runtime/conductor/index.d.ts +0 -11
  316. package/dist/types/runtime/contract/config.d.ts +0 -44
  317. package/dist/types/runtime/contract/effect.d.ts +0 -41
  318. package/dist/types/runtime/contract/errors.d.ts +0 -22
  319. package/dist/types/runtime/contract/events.d.ts +0 -63
  320. package/dist/types/runtime/contract/index.d.ts +0 -18
  321. package/dist/types/runtime/contract/run-state.d.ts +0 -57
  322. package/dist/types/runtime/contract/session.d.ts +0 -42
  323. package/dist/types/runtime/contract/signal.d.ts +0 -49
  324. package/dist/types/runtime/contract/tools.d.ts +0 -45
  325. package/dist/types/runtime/dispatch/index.d.ts +0 -9
  326. package/dist/types/runtime/dispatch/scheduler.d.ts +0 -53
  327. package/dist/types/runtime/index.d.ts +0 -22
  328. package/dist/types/runtime/ledger/accumulator.d.ts +0 -44
  329. package/dist/types/runtime/ledger/bus.d.ts +0 -50
  330. package/dist/types/runtime/ledger/index.d.ts +0 -11
  331. package/dist/types/runtime/memory/compactor.d.ts +0 -56
  332. package/dist/types/runtime/memory/estimate.d.ts +0 -21
  333. package/dist/types/runtime/memory/index.d.ts +0 -8
  334. package/dist/types/runtime/runtime.test.d.ts +0 -15
  335. package/dist/types/runtime/store/dag.d.ts +0 -72
  336. package/dist/types/runtime/store/hash.d.ts +0 -18
  337. package/dist/types/runtime/store/index.d.ts +0 -12
  338. package/dist/types/runtime/store/persist.d.ts +0 -49
  339. package/dist/types/runtime/turn/driver.d.ts +0 -32
  340. package/dist/types/runtime/turn/index.d.ts +0 -8
  341. package/dist/types/runtime/wire/index.d.ts +0 -10
  342. package/dist/types/runtime/wire/projectors.d.ts +0 -53
  343. package/dist/types/shell-app/auth-cli/index.d.ts +0 -9
  344. package/dist/types/shell-app/auth-cli/oauth-cli.d.ts +0 -73
  345. package/dist/types/shell-app/boot/context.d.ts +0 -108
  346. package/dist/types/shell-app/boot/index.d.ts +0 -13
  347. package/dist/types/shell-app/boot/pipeline.d.ts +0 -66
  348. package/dist/types/shell-app/boot/stages.d.ts +0 -77
  349. package/dist/types/shell-app/cli.d.ts +0 -75
  350. package/dist/types/shell-app/config/index.d.ts +0 -11
  351. package/dist/types/shell-app/config/locator.d.ts +0 -85
  352. package/dist/types/shell-app/config/settings.d.ts +0 -91
  353. package/dist/types/shell-app/index.d.ts +0 -26
  354. package/dist/types/shell-app/invocation/flags.d.ts +0 -89
  355. package/dist/types/shell-app/invocation/parse.d.ts +0 -89
  356. package/dist/types/shell-app/locate/brand.d.ts +0 -71
  357. package/dist/types/shell-app/locate/index.d.ts +0 -12
  358. package/dist/types/shell-app/locate/locator.d.ts +0 -122
  359. package/dist/types/shell-app/runners/contract.d.ts +0 -116
  360. package/dist/types/shell-app/runners/index.d.ts +0 -15
  361. package/dist/types/shell-app/runners/one-shot.d.ts +0 -21
  362. package/dist/types/shell-app/runners/registry.d.ts +0 -34
  363. package/dist/types/shell-app/runners/repl.d.ts +0 -51
  364. package/dist/types/shell-app/runners/wire.d.ts +0 -34
  365. package/dist/types/shell-app/shell-app.test.d.ts +0 -14
  366. package/dist/types/shell-app/upgrade/index.d.ts +0 -9
  367. package/dist/types/shell-app/upgrade/upgrades.d.ts +0 -62
  368. package/dist/types/smithy/config/flag-reader.d.ts +0 -128
  369. package/dist/types/smithy/config/index.d.ts +0 -9
  370. package/dist/types/smithy/forge.d.ts +0 -135
  371. package/dist/types/smithy/index.d.ts +0 -36
  372. package/dist/types/smithy/knowledge/index.d.ts +0 -10
  373. package/dist/types/smithy/knowledge/loader.d.ts +0 -64
  374. package/dist/types/smithy/persona/blueprint.d.ts +0 -75
  375. package/dist/types/smithy/persona/define-agent.d.ts +0 -51
  376. package/dist/types/smithy/persona/index.d.ts +0 -14
  377. package/dist/types/smithy/persona/profiles.d.ts +0 -44
  378. package/dist/types/smithy/runtime/index.d.ts +0 -9
  379. package/dist/types/smithy/runtime/tool-ledger.d.ts +0 -130
  380. package/dist/types/smithy/smithy.test.d.ts +0 -20
  381. package/dist/types/smithy/ui/index.d.ts +0 -11
  382. package/dist/types/smithy/ui/transcript.d.ts +0 -183
  383. package/dist/types/swarm/coordinator.d.ts +0 -192
  384. package/dist/types/swarm/index.d.ts +0 -33
  385. package/dist/types/swarm/isolation/index.d.ts +0 -14
  386. package/dist/types/swarm/isolation/runner.d.ts +0 -61
  387. package/dist/types/swarm/isolation/worktree.d.ts +0 -142
  388. package/dist/types/swarm/kernel/faults.d.ts +0 -52
  389. package/dist/types/swarm/kernel/ids.d.ts +0 -25
  390. package/dist/types/swarm/kernel/index.d.ts +0 -26
  391. package/dist/types/swarm/kernel/json-cell.d.ts +0 -113
  392. package/dist/types/swarm/kernel/jsonl-log.d.ts +0 -81
  393. package/dist/types/swarm/postbox/channel.d.ts +0 -88
  394. package/dist/types/swarm/postbox/codecs.d.ts +0 -253
  395. package/dist/types/swarm/postbox/index.d.ts +0 -16
  396. package/dist/types/swarm/roster/index.d.ts +0 -16
  397. package/dist/types/swarm/roster/manifest.d.ts +0 -185
  398. package/dist/types/swarm/swarm.test.d.ts +0 -24
  399. package/dist/types/swarm/telemetry/activity.d.ts +0 -143
  400. package/dist/types/swarm/workboard/board.d.ts +0 -174
  401. package/dist/types/swarm/workboard/dep-graph.d.ts +0 -77
  402. package/dist/types/swarm/workboard/index.d.ts +0 -12
  403. package/dist/types/tracing/adapter/index.d.ts +0 -12
  404. package/dist/types/tracing/adapter/runtime-trace.d.ts +0 -54
  405. package/dist/types/tracing/channel/index.d.ts +0 -9
  406. package/dist/types/tracing/channel/signal.d.ts +0 -93
  407. package/dist/types/tracing/index.d.ts +0 -25
  408. package/dist/types/tracing/recorder/index.d.ts +0 -12
  409. package/dist/types/tracing/recorder/recorder.d.ts +0 -75
  410. package/dist/types/tracing/recorder/sampling.d.ts +0 -55
  411. package/dist/types/tracing/redaction/index.d.ts +0 -8
  412. package/dist/types/tracing/redaction/secret-scrubber.d.ts +0 -95
  413. package/dist/types/tracing/registry/hub.d.ts +0 -57
  414. package/dist/types/tracing/registry/index.d.ts +0 -7
  415. package/dist/types/tracing/signal/handle.d.ts +0 -73
  416. package/dist/types/tracing/signal/index.d.ts +0 -12
  417. package/dist/types/tracing/signal/segment.d.ts +0 -124
  418. package/dist/types/tracing/sinks/base.d.ts +0 -51
  419. package/dist/types/tracing/sinks/console.d.ts +0 -44
  420. package/dist/types/tracing/sinks/file.d.ts +0 -47
  421. package/dist/types/tracing/sinks/index.d.ts +0 -16
  422. package/dist/types/tracing/sinks/stream.d.ts +0 -46
  423. package/dist/types/tracing/tracing.test.d.ts +0 -7
  424. package/dist/types/ui/autocomplete.d.ts +0 -59
  425. package/dist/types/ui/contracts.d.ts +0 -38
  426. package/dist/types/ui/editor-component.d.ts +0 -100
  427. package/dist/types/ui/fuzzy.d.ts +0 -29
  428. package/dist/types/ui/index.d.ts +0 -8
  429. package/dist/types/ui/keybindings.d.ts +0 -62
  430. package/dist/types/ui/keys.d.ts +0 -171
  431. package/dist/types/ui/theme-types.d.ts +0 -36
  432. package/dist/types/ui/utils.d.ts +0 -101
  433. package/dist/types/ui-bridge/InteractiveApp.d.ts +0 -38
  434. package/dist/types/ui-bridge/adapter.d.ts +0 -90
  435. package/dist/types/ui-bridge/index.d.ts +0 -37
@@ -1,3243 +0,0 @@
1
- // src/llmgateway/contract/errors.ts
2
- var GatewayError = class _GatewayError extends Error {
3
- kind;
4
- status;
5
- provider;
6
- constructor(kind, message, extra) {
7
- super(message, extra?.cause !== void 0 ? { cause: extra.cause } : void 0);
8
- this.name = "GatewayError";
9
- this.kind = kind;
10
- this.status = extra?.status;
11
- this.provider = extra?.provider;
12
- Object.setPrototypeOf(this, _GatewayError.prototype);
13
- }
14
- };
15
- function gatewayError(kind, message, extra) {
16
- return new GatewayError(kind, message, extra);
17
- }
18
-
19
- // src/llmgateway/catalog/cards.ts
20
- var MODEL_CARDS = [
21
- // ── Anthropic (Claude) ──────────────────────────────────────────────────
22
- {
23
- id: "claude-opus-4",
24
- provider: "anthropic",
25
- api: "anthropic-messages",
26
- displayName: "Claude Opus 4",
27
- contextWindow: 2e5,
28
- maxOutputTokens: 32e3,
29
- modalities: ["text", "image"],
30
- reasoning: true,
31
- cost: {
32
- // approximate — flagship tier
33
- inputPerMTok: 15,
34
- outputPerMTok: 75,
35
- cacheReadPerMTok: 1.5,
36
- cacheWritePerMTok: 18.75
37
- }
38
- },
39
- {
40
- id: "claude-opus-4-7",
41
- provider: "anthropic",
42
- api: "anthropic-messages",
43
- displayName: "Claude Opus 4.7",
44
- contextWindow: 1e6,
45
- maxOutputTokens: 128e3,
46
- modalities: ["text", "image"],
47
- reasoning: true,
48
- cost: {
49
- // approximate — flagship tier
50
- inputPerMTok: 5,
51
- outputPerMTok: 25,
52
- cacheReadPerMTok: 0.5,
53
- cacheWritePerMTok: 6.25
54
- }
55
- },
56
- {
57
- id: "claude-opus-4-8",
58
- provider: "anthropic",
59
- api: "anthropic-messages",
60
- displayName: "Claude Opus 4.8",
61
- contextWindow: 1e6,
62
- maxOutputTokens: 128e3,
63
- modalities: ["text", "image"],
64
- reasoning: true,
65
- cost: {
66
- // approximate — flagship tier
67
- inputPerMTok: 5,
68
- outputPerMTok: 25,
69
- cacheReadPerMTok: 0.5,
70
- cacheWritePerMTok: 6.25
71
- }
72
- },
73
- {
74
- id: "claude-sonnet-4",
75
- provider: "anthropic",
76
- api: "anthropic-messages",
77
- displayName: "Claude Sonnet 4",
78
- contextWindow: 2e5,
79
- maxOutputTokens: 64e3,
80
- modalities: ["text", "image"],
81
- reasoning: true,
82
- cost: {
83
- // approximate — mid tier
84
- inputPerMTok: 3,
85
- outputPerMTok: 15,
86
- cacheReadPerMTok: 0.3,
87
- cacheWritePerMTok: 3.75
88
- }
89
- },
90
- {
91
- id: "claude-haiku-3-5",
92
- provider: "anthropic",
93
- api: "anthropic-messages",
94
- displayName: "Claude Haiku 3.5",
95
- contextWindow: 2e5,
96
- maxOutputTokens: 8192,
97
- modalities: ["text", "image"],
98
- reasoning: false,
99
- cost: {
100
- // approximate — fast/cheap tier
101
- inputPerMTok: 0.8,
102
- outputPerMTok: 4,
103
- cacheReadPerMTok: 0.08,
104
- cacheWritePerMTok: 1
105
- }
106
- },
107
- // ── OpenAI (GPT + o-series) ─────────────────────────────────────────────
108
- {
109
- id: "gpt-4o",
110
- provider: "openai",
111
- api: "openai-completions",
112
- displayName: "GPT-4o",
113
- contextWindow: 128e3,
114
- maxOutputTokens: 16384,
115
- modalities: ["text", "image", "audio"],
116
- reasoning: false,
117
- cost: {
118
- // approximate — omni flagship
119
- inputPerMTok: 2.5,
120
- outputPerMTok: 10,
121
- cacheReadPerMTok: 1.25
122
- }
123
- },
124
- {
125
- id: "gpt-4o-mini",
126
- provider: "openai",
127
- api: "openai-completions",
128
- displayName: "GPT-4o mini",
129
- contextWindow: 128e3,
130
- maxOutputTokens: 16384,
131
- modalities: ["text", "image"],
132
- reasoning: false,
133
- cost: {
134
- // approximate — small omni
135
- inputPerMTok: 0.15,
136
- outputPerMTok: 0.6,
137
- cacheReadPerMTok: 0.075
138
- }
139
- },
140
- {
141
- id: "o3",
142
- provider: "openai",
143
- api: "openai-responses",
144
- displayName: "OpenAI o3",
145
- contextWindow: 2e5,
146
- maxOutputTokens: 1e5,
147
- modalities: ["text", "image"],
148
- reasoning: true,
149
- cost: {
150
- // approximate — reasoning flagship
151
- inputPerMTok: 10,
152
- outputPerMTok: 40,
153
- cacheReadPerMTok: 2.5
154
- }
155
- },
156
- {
157
- id: "o4-mini",
158
- provider: "openai",
159
- api: "openai-responses",
160
- displayName: "OpenAI o4-mini",
161
- contextWindow: 2e5,
162
- maxOutputTokens: 1e5,
163
- modalities: ["text", "image"],
164
- reasoning: true,
165
- cost: {
166
- // approximate — small reasoning
167
- inputPerMTok: 1.1,
168
- outputPerMTok: 4.4,
169
- cacheReadPerMTok: 0.275
170
- }
171
- },
172
- // ── Google (Gemini) ─────────────────────────────────────────────────────
173
- {
174
- id: "gemini-2.5-pro",
175
- provider: "google",
176
- api: "google-generative",
177
- displayName: "Gemini 2.5 Pro",
178
- contextWindow: 1e6,
179
- maxOutputTokens: 65536,
180
- modalities: ["text", "image", "audio"],
181
- reasoning: true,
182
- cost: {
183
- // approximate — long-context pro tier
184
- inputPerMTok: 1.25,
185
- outputPerMTok: 10,
186
- cacheReadPerMTok: 0.31
187
- }
188
- },
189
- {
190
- id: "gemini-2.5-flash",
191
- provider: "google",
192
- api: "google-generative",
193
- displayName: "Gemini 2.5 Flash",
194
- contextWindow: 1e6,
195
- maxOutputTokens: 65536,
196
- modalities: ["text", "image", "audio"],
197
- reasoning: true,
198
- cost: {
199
- // approximate — fast flash tier
200
- inputPerMTok: 0.3,
201
- outputPerMTok: 2.5,
202
- cacheReadPerMTok: 0.075
203
- }
204
- },
205
- // ── NVIDIA (OpenAI-compatible NIM endpoint) ─────────────────────────────
206
- {
207
- id: "nvidia/llama-3.1-nemotron-70b-instruct",
208
- provider: "nvidia",
209
- api: "nvidia-openai-compatible",
210
- displayName: "Nemotron 70B Instruct",
211
- baseUrl: "https://integrate.api.nvidia.com/v1",
212
- contextWindow: 128e3,
213
- maxOutputTokens: 4096,
214
- modalities: ["text"],
215
- reasoning: false,
216
- cost: {
217
- // approximate — hosted NIM inference
218
- inputPerMTok: 0.2,
219
- outputPerMTok: 0.2
220
- }
221
- },
222
- // ── Kimi / Moonshot (OpenAI-compatible) ─────────────────────────────────
223
- {
224
- id: "kimi-k2",
225
- provider: "kimi",
226
- api: "kimi-openai-compatible",
227
- displayName: "Kimi K2",
228
- baseUrl: "https://api.moonshot.ai/v1",
229
- contextWindow: 256e3,
230
- maxOutputTokens: 16384,
231
- modalities: ["text"],
232
- reasoning: true,
233
- cost: {
234
- // approximate — Moonshot hosted
235
- inputPerMTok: 0.6,
236
- outputPerMTok: 2.5,
237
- cacheReadPerMTok: 0.15
238
- }
239
- },
240
- // ── Ollama (local; pricing is zero — your own hardware) ─────────────────
241
- {
242
- id: "llama3.1:8b",
243
- provider: "ollama",
244
- api: "ollama",
245
- displayName: "Llama 3.1 8B (local)",
246
- baseUrl: "http://localhost:11434",
247
- contextWindow: 128e3,
248
- maxOutputTokens: 8192,
249
- modalities: ["text"],
250
- reasoning: false,
251
- cost: {
252
- // local inference — no per-token cost
253
- inputPerMTok: 0,
254
- outputPerMTok: 0
255
- }
256
- },
257
- // ── Mock (deterministic test fixture; free) ─────────────────────────────
258
- {
259
- id: "mock-1",
260
- provider: "mock",
261
- api: "mock",
262
- displayName: "Mock Model",
263
- contextWindow: 32e3,
264
- maxOutputTokens: 4096,
265
- modalities: ["text"],
266
- reasoning: false,
267
- cost: {
268
- inputPerMTok: 0,
269
- outputPerMTok: 0
270
- }
271
- }
272
- ];
273
-
274
- // src/llmgateway/catalog/query.ts
275
- var CardSelection = class _CardSelection {
276
- constructor(pool, tests) {
277
- this.pool = pool;
278
- this.tests = tests;
279
- }
280
- pool;
281
- tests;
282
- /** Begin a query over the given pool (defaults to the full catalog). */
283
- static over(pool) {
284
- return new _CardSelection(pool, []);
285
- }
286
- withTest(test) {
287
- return new _CardSelection(this.pool, [...this.tests, test]);
288
- }
289
- /** Keep only cards from a specific vendor. */
290
- byProvider(provider) {
291
- return this.withTest((card) => card.provider === provider);
292
- }
293
- /** Keep only cards served over a specific wire dialect. */
294
- byApi(api) {
295
- return this.withTest((card) => card.api === api);
296
- }
297
- /** Keep cards whose reasoning capability matches `enabled`. */
298
- reasoning(enabled) {
299
- return this.withTest((card) => card.reasoning === enabled);
300
- }
301
- /** Materialize every card that satisfies all accumulated predicates. */
302
- all() {
303
- return this.pool.filter((card) => this.tests.every((test) => test(card)));
304
- }
305
- /**
306
- * Terminal lookup by exact `id`, also respecting any accumulated predicates.
307
- * Returns `undefined` when no surviving card matches.
308
- */
309
- find(id) {
310
- return this.all().find((card) => card.id === id);
311
- }
312
- };
313
- function models() {
314
- return CardSelection.over(MODEL_CARDS);
315
- }
316
- function getCard(id) {
317
- return MODEL_CARDS.find((card) => card.id === id);
318
- }
319
-
320
- // src/llmgateway/catalog/cost.ts
321
- var TOKENS_PER_MTOK = 1e6;
322
- function estimateCost(card, usage) {
323
- const { cost } = card;
324
- let dollars = 0;
325
- dollars += usage.inputTokens / TOKENS_PER_MTOK * cost.inputPerMTok;
326
- dollars += usage.outputTokens / TOKENS_PER_MTOK * cost.outputPerMTok;
327
- if (usage.cacheReadTokens && cost.cacheReadPerMTok !== void 0) {
328
- dollars += usage.cacheReadTokens / TOKENS_PER_MTOK * cost.cacheReadPerMTok;
329
- }
330
- if (usage.cacheWriteTokens && cost.cacheWritePerMTok !== void 0) {
331
- dollars += usage.cacheWriteTokens / TOKENS_PER_MTOK * cost.cacheWritePerMTok;
332
- }
333
- return dollars;
334
- }
335
-
336
- // src/llmgateway/credentials/secrets.ts
337
- var SECRET_TABLE = {
338
- anthropic: {
339
- provider: "anthropic",
340
- scheme: "api-key",
341
- envVars: ["ANTHROPIC_API_KEY"],
342
- hint: "Anthropic Messages API bearer key."
343
- },
344
- openai: {
345
- provider: "openai",
346
- scheme: "api-key",
347
- envVars: ["OPENAI_API_KEY"],
348
- hint: "OpenAI platform API key."
349
- },
350
- google: {
351
- provider: "google",
352
- scheme: "api-key",
353
- // Gemini Developer API: GEMINI_API_KEY is canonical; GOOGLE_API_KEY is the
354
- // legacy/alias name still honored by the Generative Language API.
355
- envVars: ["GEMINI_API_KEY", "GOOGLE_API_KEY"],
356
- hint: "Google Generative Language (Gemini) API key."
357
- },
358
- "google-vertex": {
359
- provider: "google-vertex",
360
- scheme: "cloud-iam",
361
- // Vertex authenticates via Application Default Credentials; these point at
362
- // a service-account key file and the target project/region.
363
- envVars: [
364
- "GOOGLE_APPLICATION_CREDENTIALS",
365
- "GOOGLE_VERTEX_PROJECT",
366
- "GOOGLE_CLOUD_PROJECT"
367
- ],
368
- hint: "Vertex AI via Application Default Credentials (service account)."
369
- },
370
- amazon: {
371
- provider: "amazon",
372
- scheme: "cloud-iam",
373
- // Bedrock supports a short-lived bearer token, otherwise the standard
374
- // AWS SigV4 credential chain.
375
- envVars: [
376
- "AWS_BEARER_TOKEN_BEDROCK",
377
- "AWS_ACCESS_KEY_ID",
378
- "AWS_PROFILE"
379
- ],
380
- hint: "Amazon Bedrock via bearer token or AWS credential chain."
381
- },
382
- azure: {
383
- provider: "azure",
384
- scheme: "api-key",
385
- envVars: ["AZURE_OPENAI_API_KEY", "AZURE_API_KEY"],
386
- hint: "Azure OpenAI resource key (paired with endpoint + deployment)."
387
- },
388
- nvidia: {
389
- provider: "nvidia",
390
- scheme: "api-key",
391
- envVars: ["NVIDIA_API_KEY"],
392
- hint: "NVIDIA NIM / build.nvidia.com API key."
393
- },
394
- kimi: {
395
- provider: "kimi",
396
- scheme: "api-key",
397
- // Moonshot AI ships the Kimi models; MOONSHOT_API_KEY is the documented
398
- // name, KIMI_API_KEY is a common community alias.
399
- envVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
400
- hint: "Moonshot AI (Kimi) API key."
401
- },
402
- ollama: {
403
- provider: "ollama",
404
- scheme: "none",
405
- envVars: [],
406
- hint: "Local Ollama server \u2014 no credential required."
407
- },
408
- mock: {
409
- provider: "mock",
410
- scheme: "none",
411
- envVars: [],
412
- hint: "In-process mock transport \u2014 no credential required."
413
- }
414
- };
415
- function readEnv(name) {
416
- const raw = process.env[name];
417
- if (raw === void 0) return void 0;
418
- const trimmed = raw.trim();
419
- return trimmed.length > 0 ? trimmed : void 0;
420
- }
421
- async function resolveSecret(provider, override) {
422
- if (override !== void 0) {
423
- const trimmed = override.trim();
424
- if (trimmed.length > 0) return trimmed;
425
- }
426
- const descriptor = SECRET_TABLE[provider];
427
- if (descriptor.scheme === "none") return void 0;
428
- for (const name of descriptor.envVars) {
429
- const value = readEnv(name);
430
- if (value !== void 0) return value;
431
- }
432
- return void 0;
433
- }
434
-
435
- // src/llmgateway/streaming/sse.ts
436
- var LF = "\n";
437
- var CR = "\r";
438
- async function* sseEvents(body, signal) {
439
- if (signal?.aborted) {
440
- throw gatewayError("aborted", "request aborted before reading the event stream");
441
- }
442
- const reader = body.getReader();
443
- const decoder = new TextDecoder("utf-8");
444
- let pending = "";
445
- let eventType = "message";
446
- let dataLines = [];
447
- let sawData = false;
448
- const onAbort = () => {
449
- void reader.cancel().catch(() => {
450
- });
451
- };
452
- signal?.addEventListener("abort", onAbort, { once: true });
453
- const resetEvent = () => {
454
- eventType = "message";
455
- dataLines = [];
456
- sawData = false;
457
- };
458
- const dispatch = () => {
459
- if (!sawData) {
460
- resetEvent();
461
- return void 0;
462
- }
463
- const out = { event: eventType, data: dataLines.join(LF) };
464
- resetEvent();
465
- return out;
466
- };
467
- const consumeLine = (line) => {
468
- if (line === "") {
469
- return dispatch();
470
- }
471
- if (line.startsWith(":")) {
472
- return void 0;
473
- }
474
- const colon = line.indexOf(":");
475
- let field;
476
- let value;
477
- if (colon === -1) {
478
- field = line;
479
- value = "";
480
- } else {
481
- field = line.slice(0, colon);
482
- value = line.slice(colon + 1);
483
- if (value.startsWith(" ")) {
484
- value = value.slice(1);
485
- }
486
- }
487
- switch (field) {
488
- case "event":
489
- eventType = value;
490
- break;
491
- case "data":
492
- dataLines.push(value);
493
- sawData = true;
494
- break;
495
- // "id" and "retry" are valid SSE fields but irrelevant to LLM streams.
496
- default:
497
- break;
498
- }
499
- return void 0;
500
- };
501
- function* drainLines(atEnd) {
502
- let start = 0;
503
- let i = 0;
504
- while (i < pending.length) {
505
- const ch = pending[i];
506
- if (ch === LF) {
507
- yield pending.slice(start, i);
508
- i += 1;
509
- start = i;
510
- } else if (ch === CR) {
511
- if (i === pending.length - 1 && !atEnd) {
512
- break;
513
- }
514
- yield pending.slice(start, i);
515
- if (pending[i + 1] === LF) {
516
- i += 2;
517
- } else {
518
- i += 1;
519
- }
520
- start = i;
521
- } else {
522
- i += 1;
523
- }
524
- }
525
- pending = pending.slice(start);
526
- if (atEnd && pending.length > 0) {
527
- const last = pending;
528
- pending = "";
529
- yield last;
530
- }
531
- }
532
- try {
533
- for (; ; ) {
534
- if (signal?.aborted) {
535
- throw gatewayError("aborted", "request aborted while reading the event stream");
536
- }
537
- const { value, done } = await reader.read();
538
- if (done) {
539
- break;
540
- }
541
- pending += decoder.decode(value, { stream: true });
542
- for (const line of drainLines(false)) {
543
- const ev = consumeLine(line);
544
- if (ev !== void 0) {
545
- yield ev;
546
- }
547
- }
548
- }
549
- pending += decoder.decode();
550
- for (const line of drainLines(true)) {
551
- const ev = consumeLine(line);
552
- if (ev !== void 0) {
553
- yield ev;
554
- }
555
- }
556
- } catch (cause) {
557
- if (signal?.aborted) {
558
- throw gatewayError("aborted", "request aborted while reading the event stream", { cause });
559
- }
560
- if (cause instanceof Error && cause.name === "GatewayError") {
561
- throw cause;
562
- }
563
- throw gatewayError("transport", "failed reading the server-sent event stream", { cause });
564
- } finally {
565
- signal?.removeEventListener("abort", onAbort);
566
- reader.releaseLock();
567
- }
568
- }
569
-
570
- // src/llmgateway/conversion/reduce.ts
571
- var EMPTY_USAGE = { inputTokens: 0, outputTokens: 0 };
572
- function initial() {
573
- return {
574
- thinking: "",
575
- text: "",
576
- order: [],
577
- calls: /* @__PURE__ */ new Map(),
578
- usage: EMPTY_USAGE,
579
- stop: "complete"
580
- };
581
- }
582
- function ensureCall(state, id, name) {
583
- const existing = state.calls.get(id);
584
- if (existing === void 0) {
585
- state.order.push(id);
586
- state.calls.set(id, { name, args: "" });
587
- } else if (name !== "" && existing.name === "") {
588
- existing.name = name;
589
- }
590
- }
591
- function step(state, emission) {
592
- switch (emission.kind) {
593
- case "text":
594
- state.text += emission.delta;
595
- break;
596
- case "thinking":
597
- state.thinking += emission.delta;
598
- break;
599
- case "tool_call_start":
600
- ensureCall(state, emission.id, emission.name);
601
- break;
602
- case "tool_call_delta": {
603
- ensureCall(state, emission.id, "");
604
- const slot = state.calls.get(emission.id);
605
- if (slot !== void 0) {
606
- slot.args += emission.argsDelta;
607
- }
608
- break;
609
- }
610
- case "usage":
611
- state.usage = emission.usage;
612
- break;
613
- case "stop":
614
- state.stop = emission.stop;
615
- break;
616
- // `done` and `error` are terminal envelopes, not deltas to fold; a caller
617
- // that hands them to the reducer simply contributes nothing.
618
- case "done":
619
- case "error":
620
- break;
621
- }
622
- }
623
- function parseArgs(raw) {
624
- const trimmed = raw.trim();
625
- if (trimmed === "") {
626
- return {};
627
- }
628
- try {
629
- return JSON.parse(trimmed);
630
- } catch {
631
- return raw;
632
- }
633
- }
634
- function toBlocks(state) {
635
- const blocks = [];
636
- if (state.thinking !== "") {
637
- const block = { kind: "thinking", text: state.thinking };
638
- blocks.push(block);
639
- }
640
- if (state.text !== "") {
641
- const block = { kind: "text", text: state.text };
642
- blocks.push(block);
643
- }
644
- for (const id of state.order) {
645
- const call = state.calls.get(id);
646
- if (call === void 0) {
647
- continue;
648
- }
649
- const block = {
650
- kind: "tool_call",
651
- id,
652
- name: call.name,
653
- input: parseArgs(call.args)
654
- };
655
- blocks.push(block);
656
- }
657
- return blocks;
658
- }
659
- function foldReply(model, emissions) {
660
- const state = initial();
661
- for (const emission of emissions) {
662
- step(state, emission);
663
- }
664
- const blocks = toBlocks(state);
665
- let stop = state.stop;
666
- if (stop === "complete" && state.order.length > 0) {
667
- stop = "tool_calls";
668
- }
669
- return {
670
- role: "assistant",
671
- model,
672
- blocks,
673
- usage: state.usage,
674
- stop
675
- };
676
- }
677
-
678
- // src/llmgateway/streaming/channel.ts
679
- function channelOf(gen) {
680
- return {
681
- [Symbol.asyncIterator]() {
682
- return gen();
683
- }
684
- };
685
- }
686
- async function collectReply(channel) {
687
- const buffer = [];
688
- let model = "unknown";
689
- for await (const emission of channel) {
690
- if (emission.kind === "done") {
691
- return emission.reply;
692
- }
693
- if (emission.kind === "error") {
694
- throw emission.error;
695
- }
696
- buffer.push(emission);
697
- }
698
- if (buffer.length === 0) {
699
- throw gatewayError("transport", "channel closed without emitting any data");
700
- }
701
- return foldReply(model, buffer);
702
- }
703
-
704
- // src/llmgateway/conversion/mappers.ts
705
- function stringifyToolOutput(output) {
706
- if (typeof output === "string") {
707
- return output;
708
- }
709
- try {
710
- return JSON.stringify(output);
711
- } catch {
712
- return String(output);
713
- }
714
- }
715
- function toArgumentString(input) {
716
- if (typeof input === "string") {
717
- return input;
718
- }
719
- try {
720
- return JSON.stringify(input ?? {});
721
- } catch {
722
- return "{}";
723
- }
724
- }
725
- function toOpenAIChatMessages(c) {
726
- const messages = [];
727
- if (c.system !== void 0 && c.system !== "") {
728
- messages.push({ role: "system", content: c.system });
729
- }
730
- for (const turn of c.turns) {
731
- switch (turn.role) {
732
- case "user":
733
- messages.push(openAiUserMessage(turn.blocks));
734
- break;
735
- case "assistant":
736
- messages.push(openAiAssistantMessage(turn.blocks));
737
- break;
738
- case "tool":
739
- for (const message of openAiToolMessages(turn.blocks)) {
740
- messages.push(message);
741
- }
742
- break;
743
- }
744
- }
745
- return messages;
746
- }
747
- function openAiUserMessage(blocks) {
748
- const parts = [];
749
- let hasImage = false;
750
- for (const block of blocks) {
751
- if (block.kind === "text") {
752
- parts.push({ type: "text", text: block.text });
753
- } else if (block.kind === "image") {
754
- hasImage = true;
755
- parts.push({
756
- type: "image_url",
757
- image_url: { url: `data:${block.mediaType};base64,${block.dataBase64}` }
758
- });
759
- }
760
- }
761
- if (!hasImage) {
762
- const text = parts.map((p) => p.text ?? "").join("");
763
- return { role: "user", content: text };
764
- }
765
- return { role: "user", content: parts };
766
- }
767
- function openAiAssistantMessage(blocks) {
768
- let text = "";
769
- const toolCalls = [];
770
- for (const block of blocks) {
771
- if (block.kind === "text") {
772
- text += block.text;
773
- } else if (block.kind === "tool_call") {
774
- toolCalls.push({
775
- id: block.id,
776
- type: "function",
777
- function: { name: block.name, arguments: toArgumentString(block.input) }
778
- });
779
- }
780
- }
781
- const message = { role: "assistant", content: text === "" ? null : text };
782
- if (toolCalls.length > 0) {
783
- message.tool_calls = toolCalls;
784
- }
785
- return message;
786
- }
787
- function openAiToolMessages(blocks) {
788
- const out = [];
789
- for (const block of blocks) {
790
- if (block.kind === "tool_result") {
791
- out.push({
792
- role: "tool",
793
- tool_call_id: block.callId,
794
- content: stringifyToolOutput(block.output)
795
- });
796
- }
797
- }
798
- return out;
799
- }
800
- function toOpenAITools(tools) {
801
- if (tools === void 0 || tools.length === 0) {
802
- return void 0;
803
- }
804
- return tools.map((tool) => ({
805
- type: "function",
806
- function: {
807
- name: tool.name,
808
- description: tool.description,
809
- parameters: tool.parameters
810
- }
811
- }));
812
- }
813
- function toOpenAIToolChoice(choice) {
814
- if (choice === void 0) {
815
- return void 0;
816
- }
817
- return choice;
818
- }
819
- function anthropicThinkingBudget(level, maxOutput) {
820
- const fraction = {
821
- low: 0.2,
822
- medium: 0.4,
823
- high: 0.6,
824
- max: 0.8
825
- };
826
- if (level === "off") {
827
- return 0;
828
- }
829
- const budget = Math.floor(maxOutput * fraction[level]);
830
- return Math.max(1024, budget);
831
- }
832
- function toAnthropicRequest(c, model, opts) {
833
- const body = {
834
- model: model.id,
835
- max_tokens: opts.maxOutputTokens ?? model.maxOutputTokens,
836
- messages: toAnthropicMessages(c)
837
- };
838
- if (c.system !== void 0 && c.system !== "") {
839
- body.system = c.system;
840
- }
841
- const tools = toAnthropicTools(c.tools);
842
- if (tools !== void 0) {
843
- body.tools = tools;
844
- }
845
- const toolChoice = toAnthropicToolChoice(opts.toolChoice);
846
- if (toolChoice !== void 0) {
847
- body.tool_choice = toolChoice;
848
- }
849
- if (opts.temperature !== void 0) {
850
- body.temperature = opts.temperature;
851
- }
852
- if (opts.topP !== void 0) {
853
- body.top_p = opts.topP;
854
- }
855
- if (model.reasoning && opts.thinking !== void 0 && opts.thinking !== "off") {
856
- const max = opts.maxOutputTokens ?? model.maxOutputTokens;
857
- body.thinking = { type: "enabled", budget_tokens: anthropicThinkingBudget(opts.thinking, max) };
858
- }
859
- return body;
860
- }
861
- function toAnthropicMessages(c) {
862
- const messages = [];
863
- for (const turn of c.turns) {
864
- if (turn.role === "tool") {
865
- messages.push({ role: "user", content: anthropicContent(turn) });
866
- } else {
867
- messages.push({ role: turn.role, content: anthropicContent(turn) });
868
- }
869
- }
870
- return messages;
871
- }
872
- function anthropicContent(turn) {
873
- const content = [];
874
- for (const block of turn.blocks) {
875
- switch (block.kind) {
876
- case "text":
877
- content.push({ type: "text", text: block.text });
878
- break;
879
- case "thinking":
880
- content.push(
881
- block.signature !== void 0 ? { type: "thinking", thinking: block.text, signature: block.signature } : { type: "thinking", thinking: block.text }
882
- );
883
- break;
884
- case "tool_call":
885
- content.push({
886
- type: "tool_use",
887
- id: block.id,
888
- name: block.name,
889
- input: typeof block.input === "string" ? safeParse(block.input) : block.input ?? {}
890
- });
891
- break;
892
- case "tool_result":
893
- content.push({
894
- type: "tool_result",
895
- tool_use_id: block.callId,
896
- content: stringifyToolOutput(block.output),
897
- ...block.isError === true ? { is_error: true } : {}
898
- });
899
- break;
900
- case "image":
901
- content.push({
902
- type: "image",
903
- source: { type: "base64", media_type: block.mediaType, data: block.dataBase64 }
904
- });
905
- break;
906
- }
907
- }
908
- return content;
909
- }
910
- function toAnthropicTools(tools) {
911
- if (tools === void 0 || tools.length === 0) {
912
- return void 0;
913
- }
914
- return tools.map((tool) => ({
915
- name: tool.name,
916
- description: tool.description,
917
- input_schema: tool.parameters
918
- }));
919
- }
920
- function toAnthropicToolChoice(choice) {
921
- switch (choice) {
922
- case "auto":
923
- return { type: "auto" };
924
- case "required":
925
- return { type: "any" };
926
- case "none":
927
- return { type: "none" };
928
- default:
929
- return void 0;
930
- }
931
- }
932
- function toGoogleContents(c) {
933
- const contents = [];
934
- for (const turn of c.turns) {
935
- const role = turn.role === "assistant" ? "model" : "user";
936
- contents.push({ role, parts: googleParts(turn) });
937
- }
938
- return contents;
939
- }
940
- function googleParts(turn) {
941
- const parts = [];
942
- for (const block of turn.blocks) {
943
- switch (block.kind) {
944
- case "text":
945
- parts.push({ text: block.text });
946
- break;
947
- case "thinking":
948
- parts.push({ text: block.text, thought: true });
949
- break;
950
- case "tool_call":
951
- parts.push({
952
- functionCall: {
953
- name: block.name,
954
- args: typeof block.input === "string" ? safeParse(block.input) : block.input ?? {}
955
- }
956
- });
957
- break;
958
- case "tool_result":
959
- parts.push({
960
- functionResponse: {
961
- name: block.callId,
962
- response: { result: stringifyToolOutput(block.output) }
963
- }
964
- });
965
- break;
966
- case "image":
967
- parts.push({ inlineData: { mimeType: block.mediaType, data: block.dataBase64 } });
968
- break;
969
- }
970
- }
971
- return parts;
972
- }
973
- function toGoogleSystemInstruction(c) {
974
- if (c.system === void 0 || c.system === "") {
975
- return void 0;
976
- }
977
- return { role: "system", parts: [{ text: c.system }] };
978
- }
979
- function toGoogleTools(tools) {
980
- if (tools === void 0 || tools.length === 0) {
981
- return void 0;
982
- }
983
- return [
984
- {
985
- functionDeclarations: tools.map((tool) => ({
986
- name: tool.name,
987
- description: tool.description,
988
- parameters: tool.parameters
989
- }))
990
- }
991
- ];
992
- }
993
- function toResponsesInput(c) {
994
- const input = [];
995
- for (const turn of c.turns) {
996
- switch (turn.role) {
997
- case "user":
998
- input.push({ type: "message", role: "user", content: responsesUserContent(turn.blocks) });
999
- break;
1000
- case "assistant":
1001
- for (const item of responsesAssistantItems(turn.blocks)) {
1002
- input.push(item);
1003
- }
1004
- break;
1005
- case "tool":
1006
- for (const block of turn.blocks) {
1007
- if (block.kind === "tool_result") {
1008
- input.push({
1009
- type: "function_call_output",
1010
- call_id: block.callId,
1011
- output: stringifyToolOutput(block.output)
1012
- });
1013
- }
1014
- }
1015
- break;
1016
- }
1017
- }
1018
- return input;
1019
- }
1020
- function responsesUserContent(blocks) {
1021
- const parts = [];
1022
- for (const block of blocks) {
1023
- if (block.kind === "text") {
1024
- parts.push({ type: "input_text", text: block.text });
1025
- } else if (block.kind === "image") {
1026
- parts.push({
1027
- type: "input_image",
1028
- image_url: `data:${block.mediaType};base64,${block.dataBase64}`
1029
- });
1030
- }
1031
- }
1032
- return parts;
1033
- }
1034
- function responsesAssistantItems(blocks) {
1035
- const items = [];
1036
- const content = [];
1037
- for (const block of blocks) {
1038
- if (block.kind === "text") {
1039
- content.push({ type: "output_text", text: block.text });
1040
- } else if (block.kind === "tool_call") {
1041
- items.push({
1042
- type: "function_call",
1043
- call_id: block.id,
1044
- name: block.name,
1045
- arguments: toArgumentString(block.input)
1046
- });
1047
- }
1048
- }
1049
- if (content.length > 0) {
1050
- items.unshift({ type: "message", role: "assistant", content });
1051
- }
1052
- return items;
1053
- }
1054
- function toResponsesTools(tools) {
1055
- if (tools === void 0 || tools.length === 0) {
1056
- return void 0;
1057
- }
1058
- return tools.map((tool) => ({
1059
- type: "function",
1060
- name: tool.name,
1061
- description: tool.description,
1062
- parameters: tool.parameters
1063
- }));
1064
- }
1065
- function safeParse(raw) {
1066
- try {
1067
- return JSON.parse(raw);
1068
- } catch {
1069
- return {};
1070
- }
1071
- }
1072
-
1073
- // src/llmgateway/connectors/anthropic.ts
1074
- var DEFAULT_BASE_URL = "https://api.anthropic.com";
1075
- var ANTHROPIC_VERSION = "2023-06-01";
1076
- function isObject(v) {
1077
- return typeof v === "object" && v !== null;
1078
- }
1079
- function readString(o, key) {
1080
- const v = o[key];
1081
- return typeof v === "string" ? v : void 0;
1082
- }
1083
- function readNumber(o, key) {
1084
- const v = o[key];
1085
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1086
- }
1087
- function mapStopReason(reason) {
1088
- switch (reason) {
1089
- case "end_turn":
1090
- case "stop_sequence":
1091
- return "complete";
1092
- case "tool_use":
1093
- return "tool_calls";
1094
- case "max_tokens":
1095
- return "max_output";
1096
- case "refusal":
1097
- return "refusal";
1098
- case null:
1099
- case void 0:
1100
- case "":
1101
- return void 0;
1102
- default:
1103
- return "complete";
1104
- }
1105
- }
1106
- function mergeUsage(current, raw) {
1107
- if (!isObject(raw)) {
1108
- return current;
1109
- }
1110
- const next = { ...current };
1111
- const input = readNumber(raw, "input_tokens");
1112
- if (input !== void 0) {
1113
- next.inputTokens = input;
1114
- }
1115
- const output = readNumber(raw, "output_tokens");
1116
- if (output !== void 0) {
1117
- next.outputTokens = output;
1118
- }
1119
- const cacheRead = readNumber(raw, "cache_read_input_tokens");
1120
- if (cacheRead !== void 0) {
1121
- next.cacheReadTokens = cacheRead;
1122
- }
1123
- const cacheWrite = readNumber(raw, "cache_creation_input_tokens");
1124
- if (cacheWrite !== void 0) {
1125
- next.cacheWriteTokens = cacheWrite;
1126
- }
1127
- return next;
1128
- }
1129
- function parseEventData(event, provider) {
1130
- if (event.data === "") {
1131
- return void 0;
1132
- }
1133
- let parsed;
1134
- try {
1135
- parsed = JSON.parse(event.data);
1136
- } catch (cause) {
1137
- throw gatewayError("parse", "could not decode an Anthropic stream event", { provider, cause });
1138
- }
1139
- return isObject(parsed) ? parsed : void 0;
1140
- }
1141
- function* emitFromEvent(type, payload, state) {
1142
- switch (type) {
1143
- case "message_start": {
1144
- const message = payload.message;
1145
- if (isObject(message)) {
1146
- state.usage = mergeUsage(state.usage, message.usage);
1147
- yield { kind: "usage", usage: state.usage };
1148
- }
1149
- return;
1150
- }
1151
- case "content_block_start": {
1152
- yield* emitBlockStart(payload, state);
1153
- return;
1154
- }
1155
- case "content_block_delta": {
1156
- yield* emitBlockDelta(payload, state);
1157
- return;
1158
- }
1159
- case "content_block_stop": {
1160
- return;
1161
- }
1162
- case "message_delta": {
1163
- const delta = payload.delta;
1164
- if (isObject(delta)) {
1165
- const stop = mapStopReason(readString(delta, "stop_reason"));
1166
- if (stop !== void 0) {
1167
- yield { kind: "stop", stop };
1168
- }
1169
- }
1170
- const usage = payload.usage;
1171
- if (usage !== void 0) {
1172
- state.usage = mergeUsage(state.usage, usage);
1173
- yield { kind: "usage", usage: state.usage };
1174
- }
1175
- return;
1176
- }
1177
- case "message_stop":
1178
- case "ping":
1179
- return;
1180
- case "error": {
1181
- const error = payload.error;
1182
- const detail = isObject(error) ? readString(error, "message") : void 0;
1183
- throw gatewayError("http", `Anthropic reported a stream error${detail !== void 0 ? `: ${detail}` : ""}`);
1184
- }
1185
- default:
1186
- return;
1187
- }
1188
- }
1189
- function* emitBlockStart(payload, state) {
1190
- const index = readNumber(payload, "index") ?? 0;
1191
- const block = payload.content_block;
1192
- if (!isObject(block)) {
1193
- return;
1194
- }
1195
- if (readString(block, "type") === "tool_use") {
1196
- const id = readString(block, "id") ?? `tool_${index}`;
1197
- const name = readString(block, "name") ?? "";
1198
- state.toolIds.set(index, id);
1199
- yield { kind: "tool_call_start", id, name };
1200
- }
1201
- }
1202
- function* emitBlockDelta(payload, state) {
1203
- const index = readNumber(payload, "index") ?? 0;
1204
- const delta = payload.delta;
1205
- if (!isObject(delta)) {
1206
- return;
1207
- }
1208
- switch (readString(delta, "type")) {
1209
- case "text_delta": {
1210
- const text = readString(delta, "text");
1211
- if (text !== void 0 && text !== "") {
1212
- yield { kind: "text", delta: text };
1213
- }
1214
- return;
1215
- }
1216
- case "thinking_delta": {
1217
- const thinking = readString(delta, "thinking");
1218
- if (thinking !== void 0 && thinking !== "") {
1219
- yield { kind: "thinking", delta: thinking };
1220
- }
1221
- return;
1222
- }
1223
- case "input_json_delta": {
1224
- const fragment = readString(delta, "partial_json");
1225
- if (fragment !== void 0 && fragment !== "") {
1226
- const id = state.toolIds.get(index);
1227
- if (id !== void 0) {
1228
- yield { kind: "tool_call_delta", id, argsDelta: fragment };
1229
- }
1230
- }
1231
- return;
1232
- }
1233
- // `signature_delta` (thinking signatures) carries no user-visible content.
1234
- default:
1235
- return;
1236
- }
1237
- }
1238
- function endpointFor(model) {
1239
- const base = (model.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
1240
- return `${base}/v1/messages`;
1241
- }
1242
- async function postMessages(url, apiKey, body, signal) {
1243
- let response;
1244
- try {
1245
- response = await fetch(url, {
1246
- method: "POST",
1247
- headers: {
1248
- "content-type": "application/json",
1249
- "x-api-key": apiKey,
1250
- "anthropic-version": ANTHROPIC_VERSION
1251
- },
1252
- body: JSON.stringify(body),
1253
- ...signal !== void 0 ? { signal } : {}
1254
- });
1255
- } catch (cause) {
1256
- if (signal?.aborted) {
1257
- throw gatewayError("aborted", "request canceled before Anthropic responded", {
1258
- provider: "anthropic",
1259
- cause
1260
- });
1261
- }
1262
- throw gatewayError("transport", "network call to Anthropic failed", { provider: "anthropic", cause });
1263
- }
1264
- if (!response.ok) {
1265
- const detail = await readErrorBody(response);
1266
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
1267
- throw gatewayError(kind, `Anthropic returned HTTP ${response.status}${detail}`, {
1268
- provider: "anthropic",
1269
- status: response.status
1270
- });
1271
- }
1272
- if (response.body === null) {
1273
- throw gatewayError("transport", "Anthropic response arrived with no body", {
1274
- provider: "anthropic",
1275
- status: response.status
1276
- });
1277
- }
1278
- return response;
1279
- }
1280
- async function readErrorBody(response) {
1281
- try {
1282
- const text = await response.text();
1283
- return text === "" ? "" : `: ${text.slice(0, 500)}`;
1284
- } catch {
1285
- return "";
1286
- }
1287
- }
1288
- function asGatewayError(cause) {
1289
- if (cause instanceof Error && cause.name === "GatewayError") {
1290
- return cause;
1291
- }
1292
- return gatewayError("transport", "Anthropic stream failed", { provider: "anthropic", cause });
1293
- }
1294
- function createanthropicConnector(deps2) {
1295
- const api = "anthropic-messages";
1296
- async function requireKey(options) {
1297
- const key = await deps2.resolveSecret("anthropic", options.apiKey);
1298
- if (key === void 0 || key === "") {
1299
- throw gatewayError("auth", "no Anthropic API key found (set ANTHROPIC_API_KEY or pass options.apiKey)", {
1300
- provider: "anthropic"
1301
- });
1302
- }
1303
- return key;
1304
- }
1305
- function stream2(model, conversation, options) {
1306
- return channelOf(async function* run() {
1307
- const collected = [];
1308
- try {
1309
- const apiKey = await requireKey(options);
1310
- const body = toAnthropicRequest(conversation, model, options);
1311
- body.stream = true;
1312
- const response = await postMessages(endpointFor(model), apiKey, body, options.signal);
1313
- const wire = response.body;
1314
- const state = { toolIds: /* @__PURE__ */ new Map(), usage: { inputTokens: 0, outputTokens: 0 } };
1315
- for await (const event of sseEvents(wire, options.signal)) {
1316
- const payload = parseEventData(event, "anthropic");
1317
- if (payload === void 0) {
1318
- continue;
1319
- }
1320
- const type = event.event !== "message" ? event.event : readString(payload, "type") ?? event.event;
1321
- for (const emission of emitFromEvent(type, payload, state)) {
1322
- collected.push(emission);
1323
- yield emission;
1324
- }
1325
- }
1326
- const reply = foldReply(model.id, collected);
1327
- yield { kind: "done", reply };
1328
- } catch (cause) {
1329
- yield { kind: "error", error: asGatewayError(cause) };
1330
- }
1331
- });
1332
- }
1333
- function complete2(model, conversation, options) {
1334
- return collectReply(stream2(model, conversation, options));
1335
- }
1336
- return {
1337
- id: "anthropic",
1338
- api,
1339
- stream: stream2,
1340
- complete: complete2
1341
- };
1342
- }
1343
-
1344
- // src/llmgateway/conversion/openai-compatible.ts
1345
- function isObject2(v) {
1346
- return typeof v === "object" && v !== null;
1347
- }
1348
- function str(o, key) {
1349
- const v = o[key];
1350
- return typeof v === "string" ? v : void 0;
1351
- }
1352
- function num(o, key) {
1353
- const v = o[key];
1354
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1355
- }
1356
- function mapFinishReason(reason) {
1357
- switch (reason) {
1358
- case "stop":
1359
- return "complete";
1360
- case "length":
1361
- return "max_output";
1362
- case "tool_calls":
1363
- case "function_call":
1364
- return "tool_calls";
1365
- case "content_filter":
1366
- return "refusal";
1367
- case null:
1368
- case void 0:
1369
- case "":
1370
- return void 0;
1371
- default:
1372
- return "complete";
1373
- }
1374
- }
1375
- function readUsage(chunk) {
1376
- const usage = chunk.usage;
1377
- if (!isObject2(usage)) {
1378
- return void 0;
1379
- }
1380
- const inputTokens = num(usage, "prompt_tokens") ?? 0;
1381
- const outputTokens = num(usage, "completion_tokens") ?? 0;
1382
- const result = { inputTokens, outputTokens };
1383
- const details = usage.prompt_tokens_details;
1384
- if (isObject2(details)) {
1385
- const cached = num(details, "cached_tokens");
1386
- if (cached !== void 0) {
1387
- result.cacheReadTokens = cached;
1388
- }
1389
- }
1390
- return result;
1391
- }
1392
- function buildBody(model, c, opts, cfg, stream2) {
1393
- const body = {
1394
- model: model.id,
1395
- messages: toOpenAIChatMessages(c),
1396
- stream: stream2
1397
- };
1398
- if (stream2) {
1399
- body.stream_options = { include_usage: true };
1400
- }
1401
- const tools = toOpenAITools(c.tools);
1402
- if (tools !== void 0) {
1403
- body.tools = tools;
1404
- const choice = toOpenAIToolChoice(opts.toolChoice);
1405
- if (choice !== void 0) {
1406
- body.tool_choice = choice;
1407
- }
1408
- }
1409
- const maxTokens = opts.maxOutputTokens ?? model.maxOutputTokens;
1410
- if (maxTokens > 0) {
1411
- body.max_tokens = maxTokens;
1412
- }
1413
- if (opts.temperature !== void 0) {
1414
- body.temperature = opts.temperature;
1415
- }
1416
- if (opts.topP !== void 0) {
1417
- body.top_p = opts.topP;
1418
- }
1419
- if (cfg.bodyExtra !== void 0) {
1420
- for (const [k, v] of Object.entries(cfg.bodyExtra)) {
1421
- body[k] = v;
1422
- }
1423
- }
1424
- return body;
1425
- }
1426
- async function postChat(cfg, body, provider, signal) {
1427
- const headers = { "content-type": "application/json", ...cfg.headers };
1428
- let response;
1429
- try {
1430
- response = await fetch(cfg.url, {
1431
- method: "POST",
1432
- headers,
1433
- body: JSON.stringify(body),
1434
- ...signal !== void 0 ? { signal } : {}
1435
- });
1436
- } catch (cause) {
1437
- if (signal?.aborted) {
1438
- throw gatewayError("aborted", "request aborted before a response arrived", { provider, cause });
1439
- }
1440
- throw gatewayError("transport", "network request to the provider failed", { provider, cause });
1441
- }
1442
- if (!response.ok) {
1443
- const detail = await readErrorBody2(response);
1444
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
1445
- throw gatewayError(kind, `provider returned HTTP ${response.status}${detail}`, {
1446
- provider,
1447
- status: response.status
1448
- });
1449
- }
1450
- if (response.body === null) {
1451
- throw gatewayError("transport", "provider response had no body", { provider, status: response.status });
1452
- }
1453
- return response;
1454
- }
1455
- async function readErrorBody2(response) {
1456
- try {
1457
- const text = await response.text();
1458
- return text === "" ? "" : `: ${text.slice(0, 500)}`;
1459
- } catch {
1460
- return "";
1461
- }
1462
- }
1463
- function* emitFromChunk(chunk, tracker) {
1464
- const usage = readUsage(chunk);
1465
- if (usage !== void 0) {
1466
- yield { kind: "usage", usage };
1467
- }
1468
- const choices = chunk.choices;
1469
- if (!Array.isArray(choices) || choices.length === 0) {
1470
- return;
1471
- }
1472
- const choice = choices[0];
1473
- if (!isObject2(choice)) {
1474
- return;
1475
- }
1476
- const delta = choice.delta;
1477
- if (isObject2(delta)) {
1478
- const content = str(delta, "content");
1479
- if (content !== void 0 && content !== "") {
1480
- yield { kind: "text", delta: content };
1481
- }
1482
- const reasoning = str(delta, "reasoning_content") ?? str(delta, "reasoning");
1483
- if (reasoning !== void 0 && reasoning !== "") {
1484
- yield { kind: "thinking", delta: reasoning };
1485
- }
1486
- const toolCalls = delta.tool_calls;
1487
- if (Array.isArray(toolCalls)) {
1488
- for (const tc of toolCalls) {
1489
- yield* emitToolCall(tc, tracker);
1490
- }
1491
- }
1492
- }
1493
- const finish = mapFinishReason(str(choice, "finish_reason"));
1494
- if (finish !== void 0) {
1495
- yield { kind: "stop", stop: finish };
1496
- }
1497
- }
1498
- function* emitToolCall(tc, tracker) {
1499
- if (!isObject2(tc)) {
1500
- return;
1501
- }
1502
- const index = num(tc, "index") ?? 0;
1503
- const explicitId = str(tc, "id");
1504
- const fn = tc.function;
1505
- const name = isObject2(fn) ? str(fn, "name") : void 0;
1506
- const args = isObject2(fn) ? str(fn, "arguments") : void 0;
1507
- let id = tracker.ids.get(index);
1508
- if (id === void 0) {
1509
- id = explicitId ?? `call_${index}`;
1510
- tracker.ids.set(index, id);
1511
- yield { kind: "tool_call_start", id, name: name ?? "" };
1512
- } else if (explicitId !== void 0 && explicitId !== id) {
1513
- }
1514
- if (args !== void 0 && args !== "") {
1515
- yield { kind: "tool_call_delta", id, argsDelta: args };
1516
- }
1517
- }
1518
- function streamOpenAICompatibleChat(cfg, model, c, opts) {
1519
- return channelOf(async function* run() {
1520
- const provider = model.provider;
1521
- const collected = [];
1522
- try {
1523
- const body = buildBody(model, c, opts, cfg, true);
1524
- const response = await postChat(cfg, body, provider, opts.signal);
1525
- const stream2 = response.body;
1526
- const tracker = { ids: /* @__PURE__ */ new Map() };
1527
- for await (const sse of sseEvents(stream2, opts.signal)) {
1528
- const payload = sse.data;
1529
- if (payload === "[DONE]") {
1530
- break;
1531
- }
1532
- let chunk;
1533
- try {
1534
- chunk = JSON.parse(payload);
1535
- } catch (cause) {
1536
- throw gatewayError("parse", "failed to parse an OpenAI stream chunk", { provider, cause });
1537
- }
1538
- if (!isObject2(chunk)) {
1539
- continue;
1540
- }
1541
- for (const emission of emitFromChunk(chunk, tracker)) {
1542
- collected.push(emission);
1543
- yield emission;
1544
- }
1545
- }
1546
- const reply = foldReply(model.id, collected);
1547
- yield { kind: "done", reply };
1548
- } catch (cause) {
1549
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("transport", "OpenAI-compatible stream failed", { provider, cause });
1550
- yield { kind: "error", error };
1551
- }
1552
- });
1553
- }
1554
-
1555
- // src/llmgateway/connectors/openai-chat.ts
1556
- var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
1557
- function endpointFor2(model) {
1558
- const base = (model.baseUrl ?? DEFAULT_OPENAI_BASE_URL).replace(/\/+$/, "");
1559
- return `${base}/chat/completions`;
1560
- }
1561
- var OpenAIChatConnector = class {
1562
- constructor(deps2) {
1563
- this.deps = deps2;
1564
- }
1565
- deps;
1566
- id = "openai-chat";
1567
- api = "openai-completions";
1568
- stream(model, conversation, options) {
1569
- const deps2 = this.deps;
1570
- return channelOf(async function* run() {
1571
- let cfg;
1572
- try {
1573
- cfg = await resolveConfig(deps2, model, options);
1574
- } catch (cause) {
1575
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("auth", "could not prepare the OpenAI request", {
1576
- provider: model.provider,
1577
- cause
1578
- });
1579
- yield { kind: "error", error };
1580
- return;
1581
- }
1582
- yield* streamOpenAICompatibleChat(cfg, model, conversation, options);
1583
- });
1584
- }
1585
- async complete(model, conversation, options) {
1586
- return collectReply(this.stream(model, conversation, options));
1587
- }
1588
- };
1589
- async function resolveConfig(deps2, model, options) {
1590
- const key = await deps2.resolveSecret(model.provider, options.apiKey);
1591
- if (key === void 0 || key === "") {
1592
- throw gatewayError(
1593
- "auth",
1594
- "no OpenAI credential found \u2014 set OPENAI_API_KEY or pass options.apiKey",
1595
- { provider: model.provider }
1596
- );
1597
- }
1598
- return {
1599
- url: endpointFor2(model),
1600
- headers: { authorization: `Bearer ${key}` }
1601
- };
1602
- }
1603
- function createopenaichatConnector(deps2) {
1604
- return new OpenAIChatConnector(deps2);
1605
- }
1606
-
1607
- // src/llmgateway/connectors/openai-responses.ts
1608
- var DEFAULT_ORIGIN = "https://api.openai.com/v1";
1609
- function isObject3(v) {
1610
- return typeof v === "object" && v !== null && !Array.isArray(v);
1611
- }
1612
- function readString2(o, key) {
1613
- const v = o[key];
1614
- return typeof v === "string" ? v : void 0;
1615
- }
1616
- function readNumber2(o, key) {
1617
- const v = o[key];
1618
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1619
- }
1620
- function reasoningEffort(level) {
1621
- switch (level) {
1622
- case "low":
1623
- return "low";
1624
- case "medium":
1625
- return "medium";
1626
- case "high":
1627
- case "max":
1628
- return "high";
1629
- }
1630
- }
1631
- function mapStatus(status, incompleteReason) {
1632
- switch (status) {
1633
- case "completed":
1634
- return "complete";
1635
- case "incomplete":
1636
- return incompleteReason === "max_output_tokens" ? "max_output" : "complete";
1637
- case "failed":
1638
- case "cancelled":
1639
- return "error";
1640
- default:
1641
- return "complete";
1642
- }
1643
- }
1644
- function joinUrl(origin, path) {
1645
- return origin.endsWith("/") ? origin.slice(0, -1) + path : origin + path;
1646
- }
1647
- function buildBody2(model, c, opts) {
1648
- const body = {
1649
- model: model.id,
1650
- input: toResponsesInput(c),
1651
- stream: true
1652
- };
1653
- if (c.system !== void 0 && c.system !== "") {
1654
- body.instructions = c.system;
1655
- }
1656
- const tools = toResponsesTools(c.tools);
1657
- if (tools !== void 0) {
1658
- body.tools = tools;
1659
- if (opts.toolChoice !== void 0) {
1660
- body.tool_choice = opts.toolChoice;
1661
- }
1662
- }
1663
- const ceiling = opts.maxOutputTokens ?? model.maxOutputTokens;
1664
- if (ceiling > 0) {
1665
- body.max_output_tokens = ceiling;
1666
- }
1667
- if (opts.temperature !== void 0) {
1668
- body.temperature = opts.temperature;
1669
- }
1670
- if (opts.topP !== void 0) {
1671
- body.top_p = opts.topP;
1672
- }
1673
- if (model.reasoning && opts.thinking !== void 0 && opts.thinking !== "off") {
1674
- body.reasoning = { effort: reasoningEffort(opts.thinking) };
1675
- }
1676
- return body;
1677
- }
1678
- async function postResponses(url, apiKey, body, provider, signal) {
1679
- let response;
1680
- try {
1681
- response = await fetch(url, {
1682
- method: "POST",
1683
- headers: {
1684
- "content-type": "application/json",
1685
- authorization: `Bearer ${apiKey}`
1686
- },
1687
- body: JSON.stringify(body),
1688
- ...signal !== void 0 ? { signal } : {}
1689
- });
1690
- } catch (cause) {
1691
- if (signal?.aborted) {
1692
- throw gatewayError("aborted", "the Responses request was cancelled before a reply arrived", {
1693
- provider,
1694
- cause
1695
- });
1696
- }
1697
- throw gatewayError("transport", "could not reach the OpenAI Responses endpoint", { provider, cause });
1698
- }
1699
- if (!response.ok) {
1700
- const detail = await describeFailure(response);
1701
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
1702
- throw gatewayError(kind, `OpenAI Responses replied with HTTP ${response.status}${detail}`, {
1703
- provider,
1704
- status: response.status
1705
- });
1706
- }
1707
- if (response.body === null) {
1708
- throw gatewayError("transport", "OpenAI Responses returned an empty body", {
1709
- provider,
1710
- status: response.status
1711
- });
1712
- }
1713
- return response;
1714
- }
1715
- async function describeFailure(response) {
1716
- try {
1717
- const text = await response.text();
1718
- return text === "" ? "" : ` \u2014 ${text.slice(0, 500)}`;
1719
- } catch {
1720
- return "";
1721
- }
1722
- }
1723
- function extractUsage(response) {
1724
- const usage = response.usage;
1725
- if (!isObject3(usage)) {
1726
- return void 0;
1727
- }
1728
- const inputTokens = readNumber2(usage, "input_tokens") ?? 0;
1729
- const outputTokens = readNumber2(usage, "output_tokens") ?? 0;
1730
- const result = { inputTokens, outputTokens };
1731
- const inputDetails = usage.input_tokens_details;
1732
- if (isObject3(inputDetails)) {
1733
- const cached = readNumber2(inputDetails, "cached_tokens");
1734
- if (cached !== void 0) {
1735
- result.cacheReadTokens = cached;
1736
- }
1737
- }
1738
- return result;
1739
- }
1740
- function* translateEvent(payload, calls) {
1741
- const type = readString2(payload, "type");
1742
- switch (type) {
1743
- case "response.output_text.delta": {
1744
- const delta = readString2(payload, "delta");
1745
- if (delta !== void 0 && delta !== "") {
1746
- yield { kind: "text", delta };
1747
- }
1748
- return;
1749
- }
1750
- case "response.reasoning_summary_text.delta":
1751
- case "response.reasoning_text.delta": {
1752
- const delta = readString2(payload, "delta");
1753
- if (delta !== void 0 && delta !== "") {
1754
- yield { kind: "thinking", delta };
1755
- }
1756
- return;
1757
- }
1758
- case "response.output_item.added": {
1759
- yield* announceItem(payload, calls);
1760
- return;
1761
- }
1762
- case "response.function_call_arguments.delta": {
1763
- const itemId = readString2(payload, "item_id");
1764
- const delta = readString2(payload, "delta");
1765
- if (itemId === void 0 || delta === void 0 || delta === "") {
1766
- return;
1767
- }
1768
- const id = calls.byItem.get(itemId) ?? itemId;
1769
- yield { kind: "tool_call_delta", id, argsDelta: delta };
1770
- return;
1771
- }
1772
- case "response.completed":
1773
- case "response.incomplete":
1774
- case "response.failed": {
1775
- yield* finishResponse(payload);
1776
- return;
1777
- }
1778
- default:
1779
- return;
1780
- }
1781
- }
1782
- function* announceItem(payload, calls) {
1783
- const item = payload.item;
1784
- if (!isObject3(item)) {
1785
- return;
1786
- }
1787
- if (readString2(item, "type") !== "function_call") {
1788
- return;
1789
- }
1790
- const name = readString2(item, "name") ?? "";
1791
- const callId = readString2(item, "call_id") ?? readString2(item, "id") ?? `call_${calls.byItem.size}`;
1792
- const itemId = readString2(item, "id");
1793
- if (itemId !== void 0) {
1794
- calls.byItem.set(itemId, callId);
1795
- }
1796
- yield { kind: "tool_call_start", id: callId, name };
1797
- }
1798
- function* finishResponse(payload) {
1799
- const response = isObject3(payload.response) ? payload.response : payload;
1800
- const usage = extractUsage(response);
1801
- if (usage !== void 0) {
1802
- yield { kind: "usage", usage };
1803
- }
1804
- const status = readString2(response, "status");
1805
- const incomplete = isObject3(response.incomplete_details) ? readString2(response.incomplete_details, "reason") : void 0;
1806
- yield { kind: "stop", stop: mapStatus(status, incomplete) };
1807
- }
1808
- function createopenairesponsesConnector(deps2) {
1809
- const { resolveSecret: resolveSecret2 } = deps2;
1810
- const stream2 = (model, conversation, options) => {
1811
- return channelOf(async function* run() {
1812
- const provider = model.provider;
1813
- const collected = [];
1814
- try {
1815
- const apiKey = await resolveSecret2(provider, options.apiKey);
1816
- if (apiKey === void 0 || apiKey === "") {
1817
- throw gatewayError("auth", "no OpenAI API key was found for the Responses endpoint", { provider });
1818
- }
1819
- const origin = model.baseUrl ?? DEFAULT_ORIGIN;
1820
- const url = joinUrl(origin, "/responses");
1821
- const body = buildBody2(model, conversation, options);
1822
- const response = await postResponses(url, apiKey, body, provider, options.signal);
1823
- const wire = response.body;
1824
- const calls = { byItem: /* @__PURE__ */ new Map() };
1825
- for await (const sse of sseEvents(wire, options.signal)) {
1826
- const raw = sse.data;
1827
- if (raw === "" || raw === "[DONE]") {
1828
- continue;
1829
- }
1830
- let payload;
1831
- try {
1832
- payload = JSON.parse(raw);
1833
- } catch (cause) {
1834
- throw gatewayError("parse", "could not parse an OpenAI Responses stream event", {
1835
- provider,
1836
- cause
1837
- });
1838
- }
1839
- if (!isObject3(payload)) {
1840
- continue;
1841
- }
1842
- for (const emission of translateEvent(payload, calls)) {
1843
- collected.push(emission);
1844
- yield emission;
1845
- }
1846
- }
1847
- yield { kind: "done", reply: foldReply(model.id, collected) };
1848
- } catch (cause) {
1849
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("transport", "the OpenAI Responses stream failed", { provider, cause });
1850
- yield { kind: "error", error };
1851
- }
1852
- });
1853
- };
1854
- const complete2 = (model, conversation, options) => {
1855
- return collectReply(stream2(model, conversation, options));
1856
- };
1857
- return {
1858
- id: "openai-responses",
1859
- api: "openai-responses",
1860
- stream: stream2,
1861
- complete: complete2
1862
- };
1863
- }
1864
-
1865
- // src/llmgateway/streaming/ndjson.ts
1866
- async function* ndjsonLines(body, signal) {
1867
- if (signal?.aborted) {
1868
- throw gatewayError("aborted", "request aborted before reading the ndjson stream");
1869
- }
1870
- const reader = body.getReader();
1871
- const decoder = new TextDecoder("utf-8");
1872
- let pending = "";
1873
- const onAbort = () => {
1874
- void reader.cancel().catch(() => {
1875
- });
1876
- };
1877
- signal?.addEventListener("abort", onAbort, { once: true });
1878
- const parseLine = (raw) => {
1879
- const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
1880
- const trimmed = line.trim();
1881
- if (trimmed === "") {
1882
- return void 0;
1883
- }
1884
- try {
1885
- return JSON.parse(trimmed);
1886
- } catch (cause) {
1887
- throw gatewayError("parse", "failed to parse an ndjson line as JSON", { cause });
1888
- }
1889
- };
1890
- try {
1891
- for (; ; ) {
1892
- if (signal?.aborted) {
1893
- throw gatewayError("aborted", "request aborted while reading the ndjson stream");
1894
- }
1895
- const { value, done } = await reader.read();
1896
- if (done) {
1897
- break;
1898
- }
1899
- pending += decoder.decode(value, { stream: true });
1900
- let nl = pending.indexOf("\n");
1901
- while (nl !== -1) {
1902
- const raw = pending.slice(0, nl);
1903
- pending = pending.slice(nl + 1);
1904
- const parsed = parseLine(raw);
1905
- if (parsed !== void 0) {
1906
- yield parsed;
1907
- }
1908
- nl = pending.indexOf("\n");
1909
- }
1910
- }
1911
- pending += decoder.decode();
1912
- const tail = parseLine(pending);
1913
- if (tail !== void 0) {
1914
- yield tail;
1915
- }
1916
- } catch (cause) {
1917
- if (signal?.aborted) {
1918
- throw gatewayError("aborted", "request aborted while reading the ndjson stream", { cause });
1919
- }
1920
- if (cause instanceof Error && cause.name === "GatewayError") {
1921
- throw cause;
1922
- }
1923
- throw gatewayError("transport", "failed reading the ndjson stream", { cause });
1924
- } finally {
1925
- signal?.removeEventListener("abort", onAbort);
1926
- reader.releaseLock();
1927
- }
1928
- }
1929
-
1930
- // src/llmgateway/connectors/google.ts
1931
- var DEFAULT_BASE_URL2 = "https://generativelanguage.googleapis.com";
1932
- var PROVIDER = "google";
1933
- function isObject4(value) {
1934
- return typeof value === "object" && value !== null;
1935
- }
1936
- function readString3(o, key) {
1937
- const v = o[key];
1938
- return typeof v === "string" ? v : void 0;
1939
- }
1940
- function readNumber3(o, key) {
1941
- const v = o[key];
1942
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1943
- }
1944
- function geminiThinkingBudget(level, maxOutput) {
1945
- const fraction = {
1946
- low: 0.2,
1947
- medium: 0.4,
1948
- high: 0.6,
1949
- max: 0.8
1950
- };
1951
- const budget = Math.floor(maxOutput * fraction[level]);
1952
- return Math.max(1024, budget);
1953
- }
1954
- function buildGenerationConfig(model, opts) {
1955
- const maxOutputTokens = opts.maxOutputTokens ?? model.maxOutputTokens;
1956
- const config = { maxOutputTokens };
1957
- if (opts.temperature !== void 0) {
1958
- config.temperature = opts.temperature;
1959
- }
1960
- if (opts.topP !== void 0) {
1961
- config.topP = opts.topP;
1962
- }
1963
- if (model.reasoning && opts.thinking !== void 0 && opts.thinking !== "off") {
1964
- config.thinkingConfig = {
1965
- includeThoughts: true,
1966
- thinkingBudget: geminiThinkingBudget(opts.thinking, maxOutputTokens)
1967
- };
1968
- }
1969
- return config;
1970
- }
1971
- function buildRequestBody(model, conversation, opts) {
1972
- const body = {
1973
- contents: toGoogleContents(conversation),
1974
- generationConfig: buildGenerationConfig(model, opts)
1975
- };
1976
- const systemInstruction = toGoogleSystemInstruction(conversation);
1977
- if (systemInstruction !== void 0) {
1978
- body.systemInstruction = systemInstruction;
1979
- }
1980
- const tools = toGoogleTools(conversation.tools);
1981
- if (tools !== void 0) {
1982
- body.tools = tools;
1983
- }
1984
- return body;
1985
- }
1986
- function streamEndpoint(model) {
1987
- const base = (model.baseUrl ?? DEFAULT_BASE_URL2).replace(/\/+$/u, "");
1988
- return `${base}/v1beta/models/${model.id}:streamGenerateContent?alt=sse`;
1989
- }
1990
- async function openStream(url, apiKey, body, signal) {
1991
- let response;
1992
- try {
1993
- response = await fetch(url, {
1994
- method: "POST",
1995
- headers: {
1996
- "content-type": "application/json",
1997
- "x-goog-api-key": apiKey
1998
- },
1999
- body: JSON.stringify(body),
2000
- ...signal !== void 0 ? { signal } : {}
2001
- });
2002
- } catch (cause) {
2003
- if (signal?.aborted) {
2004
- throw gatewayError("aborted", "the Gemini request was aborted before a response arrived", {
2005
- provider: PROVIDER,
2006
- cause
2007
- });
2008
- }
2009
- throw gatewayError("transport", "could not reach the Gemini endpoint", {
2010
- provider: PROVIDER,
2011
- cause
2012
- });
2013
- }
2014
- if (!response.ok) {
2015
- const detail = await readErrorDetail(response);
2016
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
2017
- throw gatewayError(kind, `Gemini replied with HTTP ${response.status}${detail}`, {
2018
- provider: PROVIDER,
2019
- status: response.status
2020
- });
2021
- }
2022
- if (response.body === null) {
2023
- throw gatewayError("transport", "the Gemini response carried no body to stream", {
2024
- provider: PROVIDER,
2025
- status: response.status
2026
- });
2027
- }
2028
- return response;
2029
- }
2030
- async function readErrorDetail(response) {
2031
- try {
2032
- const text = await response.text();
2033
- return text === "" ? "" : `: ${text.slice(0, 500)}`;
2034
- } catch {
2035
- return "";
2036
- }
2037
- }
2038
- function mapFinishReason2(reason) {
2039
- switch (reason) {
2040
- case "STOP":
2041
- return "complete";
2042
- case "MAX_TOKENS":
2043
- return "max_output";
2044
- case "SAFETY":
2045
- case "RECITATION":
2046
- case "BLOCKLIST":
2047
- case "PROHIBITED_CONTENT":
2048
- case "SPII":
2049
- return "refusal";
2050
- case void 0:
2051
- case "":
2052
- case "FINISH_REASON_UNSPECIFIED":
2053
- case "OTHER":
2054
- return void 0;
2055
- default:
2056
- return "complete";
2057
- }
2058
- }
2059
- function readUsage2(frame) {
2060
- const meta = frame.usageMetadata;
2061
- if (!isObject4(meta)) {
2062
- return void 0;
2063
- }
2064
- const inputTokens = readNumber3(meta, "promptTokenCount") ?? 0;
2065
- const outputTokens = readNumber3(meta, "candidatesTokenCount") ?? 0;
2066
- const usage = { inputTokens, outputTokens };
2067
- const cachedRead = readNumber3(meta, "cachedContentTokenCount");
2068
- if (cachedRead !== void 0) {
2069
- usage.cacheReadTokens = cachedRead;
2070
- }
2071
- return usage;
2072
- }
2073
- function* emitFromParts(parts, tracker) {
2074
- for (const part of parts) {
2075
- if (!isObject4(part)) {
2076
- continue;
2077
- }
2078
- const text = readString3(part, "text");
2079
- if (text !== void 0 && text !== "") {
2080
- if (part.thought === true) {
2081
- yield { kind: "thinking", delta: text };
2082
- } else {
2083
- yield { kind: "text", delta: text };
2084
- }
2085
- continue;
2086
- }
2087
- const functionCall = part.functionCall;
2088
- if (isObject4(functionCall)) {
2089
- const name = readString3(functionCall, "name") ?? "";
2090
- const id = `gemini_call_${tracker.next}`;
2091
- tracker.next += 1;
2092
- yield { kind: "tool_call_start", id, name };
2093
- const args = "args" in functionCall ? functionCall.args : {};
2094
- yield { kind: "tool_call_delta", id, argsDelta: serializeArgs(args) };
2095
- }
2096
- }
2097
- }
2098
- function serializeArgs(args) {
2099
- if (typeof args === "string") {
2100
- return args;
2101
- }
2102
- try {
2103
- return JSON.stringify(args ?? {});
2104
- } catch {
2105
- return "{}";
2106
- }
2107
- }
2108
- function* emitFromFrame(frame, tracker) {
2109
- const usage = readUsage2(frame);
2110
- if (usage !== void 0) {
2111
- yield { kind: "usage", usage };
2112
- }
2113
- const candidates = frame.candidates;
2114
- if (!Array.isArray(candidates) || candidates.length === 0) {
2115
- return;
2116
- }
2117
- const candidate = candidates[0];
2118
- if (!isObject4(candidate)) {
2119
- return;
2120
- }
2121
- const content = candidate.content;
2122
- if (isObject4(content) && Array.isArray(content.parts)) {
2123
- yield* emitFromParts(content.parts, tracker);
2124
- }
2125
- const stop = mapFinishReason2(readString3(candidate, "finishReason"));
2126
- if (stop !== void 0) {
2127
- yield { kind: "stop", stop };
2128
- }
2129
- }
2130
- function creategoogleConnector(deps2) {
2131
- const { resolveSecret: resolveSecret2 } = deps2;
2132
- return {
2133
- id: "google-generative",
2134
- api: "google-generative",
2135
- stream(model, conversation, options) {
2136
- return channelOf(async function* run() {
2137
- const collected = [];
2138
- try {
2139
- const apiKey = await resolveSecret2(PROVIDER, options.apiKey);
2140
- if (apiKey === void 0 || apiKey === "") {
2141
- throw gatewayError("auth", "no Gemini API key was found (set GEMINI_API_KEY or pass apiKey)", {
2142
- provider: PROVIDER
2143
- });
2144
- }
2145
- const url = streamEndpoint(model);
2146
- const body = buildRequestBody(model, conversation, options);
2147
- const response = await openStream(url, apiKey, body, options.signal);
2148
- const wire = response.body;
2149
- const tracker = { next: 0 };
2150
- for await (const event of sseEvents(wire, options.signal)) {
2151
- const payload = event.data;
2152
- if (payload === "" || payload === "[DONE]") {
2153
- continue;
2154
- }
2155
- let frame;
2156
- try {
2157
- frame = JSON.parse(payload);
2158
- } catch (cause) {
2159
- throw gatewayError("parse", "could not parse a Gemini stream frame", {
2160
- provider: PROVIDER,
2161
- cause
2162
- });
2163
- }
2164
- if (!isObject4(frame)) {
2165
- continue;
2166
- }
2167
- for (const emission of emitFromFrame(frame, tracker)) {
2168
- collected.push(emission);
2169
- yield emission;
2170
- }
2171
- }
2172
- const reply = foldReply(model.id, collected);
2173
- yield { kind: "done", reply };
2174
- } catch (cause) {
2175
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("transport", "the Gemini stream failed", { provider: PROVIDER, cause });
2176
- yield { kind: "error", error };
2177
- }
2178
- });
2179
- },
2180
- complete(model, conversation, options) {
2181
- return collectReply(this.stream(model, conversation, options));
2182
- }
2183
- };
2184
- }
2185
-
2186
- // src/llmgateway/connectors/google-vertex.ts
2187
- var PROVIDER2 = "google-vertex";
2188
- var API_KIND = "google-vertex";
2189
- var DEFAULT_LOCATION = "us-central1";
2190
- var defaultBaseUrl = (location) => `https://${location}-aiplatform.googleapis.com`;
2191
- function envValue(name) {
2192
- const raw = process.env[name];
2193
- if (raw === void 0) {
2194
- return void 0;
2195
- }
2196
- const trimmed = raw.trim();
2197
- return trimmed.length > 0 ? trimmed : void 0;
2198
- }
2199
- function firstEnv(names) {
2200
- for (const name of names) {
2201
- const value = envValue(name);
2202
- if (value !== void 0) {
2203
- return value;
2204
- }
2205
- }
2206
- return void 0;
2207
- }
2208
- function resolveTarget(model) {
2209
- const project = firstEnv(["GOOGLE_VERTEX_PROJECT", "GOOGLE_CLOUD_PROJECT"]);
2210
- if (project === void 0) {
2211
- throw gatewayError(
2212
- "auth",
2213
- "no Vertex project found; set GOOGLE_VERTEX_PROJECT or GOOGLE_CLOUD_PROJECT",
2214
- { provider: PROVIDER2 }
2215
- );
2216
- }
2217
- const location = firstEnv(["GOOGLE_VERTEX_LOCATION", "CLOUD_ML_REGION"]) ?? DEFAULT_LOCATION;
2218
- const host = (model.baseUrl ?? defaultBaseUrl(location)).replace(/\/+$/, "");
2219
- const url = `${host}/v1/projects/${encodeURIComponent(project)}/locations/${encodeURIComponent(location)}/publishers/google/models/${encodeURIComponent(model.id)}:streamGenerateContent?alt=sse`;
2220
- return { project, location, url };
2221
- }
2222
- function toFunctionCallingConfig(choice) {
2223
- switch (choice) {
2224
- case "auto":
2225
- return { functionCallingConfig: { mode: "AUTO" } };
2226
- case "required":
2227
- return { functionCallingConfig: { mode: "ANY" } };
2228
- case "none":
2229
- return { functionCallingConfig: { mode: "NONE" } };
2230
- default:
2231
- return void 0;
2232
- }
2233
- }
2234
- function thinkingBudget(level, maxOutput) {
2235
- if (level === void 0 || level === "off") {
2236
- return void 0;
2237
- }
2238
- const fraction = {
2239
- low: 0.2,
2240
- medium: 0.4,
2241
- high: 0.6,
2242
- max: 0.8
2243
- };
2244
- return Math.max(0, Math.floor(maxOutput * fraction[level]));
2245
- }
2246
- function buildBody3(model, c, opts) {
2247
- const body = {
2248
- contents: toGoogleContents(c)
2249
- };
2250
- const systemInstruction = toGoogleSystemInstruction(c);
2251
- if (systemInstruction !== void 0) {
2252
- body.systemInstruction = systemInstruction;
2253
- }
2254
- const tools = toGoogleTools(c.tools);
2255
- if (tools !== void 0) {
2256
- body.tools = tools;
2257
- const toolConfig = toFunctionCallingConfig(opts.toolChoice);
2258
- if (toolConfig !== void 0) {
2259
- body.toolConfig = toolConfig;
2260
- }
2261
- }
2262
- const generationConfig = {};
2263
- const maxTokens = opts.maxOutputTokens ?? model.maxOutputTokens;
2264
- if (maxTokens > 0) {
2265
- generationConfig.maxOutputTokens = maxTokens;
2266
- }
2267
- if (opts.temperature !== void 0) {
2268
- generationConfig.temperature = opts.temperature;
2269
- }
2270
- if (opts.topP !== void 0) {
2271
- generationConfig.topP = opts.topP;
2272
- }
2273
- if (model.reasoning) {
2274
- const budget = thinkingBudget(opts.thinking, maxTokens);
2275
- if (budget !== void 0) {
2276
- generationConfig.thinkingConfig = { thinkingBudget: budget };
2277
- }
2278
- }
2279
- if (Object.keys(generationConfig).length > 0) {
2280
- body.generationConfig = generationConfig;
2281
- }
2282
- return body;
2283
- }
2284
- function isObject5(v) {
2285
- return typeof v === "object" && v !== null;
2286
- }
2287
- function readString4(o, key) {
2288
- const v = o[key];
2289
- return typeof v === "string" ? v : void 0;
2290
- }
2291
- function readNumber4(o, key) {
2292
- const v = o[key];
2293
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
2294
- }
2295
- function readBool(o, key) {
2296
- return o[key] === true;
2297
- }
2298
- function mapFinishReason3(reason) {
2299
- switch (reason) {
2300
- case void 0:
2301
- case "":
2302
- case "FINISH_REASON_UNSPECIFIED":
2303
- return void 0;
2304
- case "STOP":
2305
- return "complete";
2306
- case "MAX_TOKENS":
2307
- return "max_output";
2308
- case "SAFETY":
2309
- case "RECITATION":
2310
- case "BLOCKLIST":
2311
- case "PROHIBITED_CONTENT":
2312
- case "SPII":
2313
- return "refusal";
2314
- default:
2315
- return "complete";
2316
- }
2317
- }
2318
- function readUsage3(chunk) {
2319
- const meta = chunk.usageMetadata;
2320
- if (!isObject5(meta)) {
2321
- return void 0;
2322
- }
2323
- const inputTokens = readNumber4(meta, "promptTokenCount") ?? 0;
2324
- const candidate = readNumber4(meta, "candidatesTokenCount") ?? 0;
2325
- const thoughts = readNumber4(meta, "thoughtsTokenCount") ?? 0;
2326
- const result = {
2327
- inputTokens,
2328
- outputTokens: candidate + thoughts
2329
- };
2330
- const cached = readNumber4(meta, "cachedContentTokenCount");
2331
- if (cached !== void 0) {
2332
- result.cacheReadTokens = cached;
2333
- }
2334
- return result;
2335
- }
2336
- function* emitFromChunk2(chunk, tracker) {
2337
- const usage = readUsage3(chunk);
2338
- if (usage !== void 0) {
2339
- yield { kind: "usage", usage };
2340
- }
2341
- const candidates = chunk.candidates;
2342
- if (!Array.isArray(candidates) || candidates.length === 0) {
2343
- return;
2344
- }
2345
- const candidate = candidates[0];
2346
- if (!isObject5(candidate)) {
2347
- return;
2348
- }
2349
- const content = candidate.content;
2350
- if (isObject5(content)) {
2351
- const parts = content.parts;
2352
- if (Array.isArray(parts)) {
2353
- for (const part of parts) {
2354
- yield* emitFromPart(part, tracker);
2355
- }
2356
- }
2357
- }
2358
- const finish = mapFinishReason3(readString4(candidate, "finishReason"));
2359
- if (finish !== void 0) {
2360
- yield { kind: "stop", stop: finish };
2361
- }
2362
- }
2363
- function* emitFromPart(part, tracker) {
2364
- if (!isObject5(part)) {
2365
- return;
2366
- }
2367
- const functionCall = part.functionCall;
2368
- if (isObject5(functionCall)) {
2369
- const name = readString4(functionCall, "name") ?? "";
2370
- const id = `vertex_call_${tracker.next}`;
2371
- tracker.next += 1;
2372
- yield { kind: "tool_call_start", id, name };
2373
- const args = functionCall.args;
2374
- const argsDelta = serializeArgs2(args);
2375
- if (argsDelta !== "") {
2376
- yield { kind: "tool_call_delta", id, argsDelta };
2377
- }
2378
- return;
2379
- }
2380
- const text = readString4(part, "text");
2381
- if (text !== void 0 && text !== "") {
2382
- if (readBool(part, "thought")) {
2383
- yield { kind: "thinking", delta: text };
2384
- } else {
2385
- yield { kind: "text", delta: text };
2386
- }
2387
- }
2388
- }
2389
- function serializeArgs2(args) {
2390
- if (args === void 0 || args === null) {
2391
- return "";
2392
- }
2393
- if (typeof args === "string") {
2394
- return args;
2395
- }
2396
- try {
2397
- return JSON.stringify(args);
2398
- } catch {
2399
- return "";
2400
- }
2401
- }
2402
- async function postStream(url, token, body, signal) {
2403
- let response;
2404
- try {
2405
- response = await fetch(url, {
2406
- method: "POST",
2407
- headers: {
2408
- "content-type": "application/json",
2409
- authorization: `Bearer ${token}`
2410
- },
2411
- body: JSON.stringify(body),
2412
- ...signal !== void 0 ? { signal } : {}
2413
- });
2414
- } catch (cause) {
2415
- if (signal?.aborted) {
2416
- throw gatewayError("aborted", "Vertex request was aborted before a response arrived", {
2417
- provider: PROVIDER2,
2418
- cause
2419
- });
2420
- }
2421
- throw gatewayError("transport", "network request to Vertex AI failed", {
2422
- provider: PROVIDER2,
2423
- cause
2424
- });
2425
- }
2426
- if (!response.ok) {
2427
- const detail = await readErrorBody3(response);
2428
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
2429
- throw gatewayError(kind, `Vertex AI returned HTTP ${response.status}${detail}`, {
2430
- provider: PROVIDER2,
2431
- status: response.status
2432
- });
2433
- }
2434
- if (response.body === null) {
2435
- throw gatewayError("transport", "Vertex AI response carried no body", {
2436
- provider: PROVIDER2,
2437
- status: response.status
2438
- });
2439
- }
2440
- return response;
2441
- }
2442
- async function readErrorBody3(response) {
2443
- try {
2444
- const text = await response.text();
2445
- return text === "" ? "" : `: ${text.slice(0, 500)}`;
2446
- } catch {
2447
- return "";
2448
- }
2449
- }
2450
- function creategooglevertexConnector(deps2) {
2451
- const { resolveSecret: resolveSecret2 } = deps2;
2452
- function stream2(model, conversation, options) {
2453
- return channelOf(async function* run() {
2454
- const collected = [];
2455
- try {
2456
- const token = await resolveSecret2(PROVIDER2, options.apiKey);
2457
- if (token === void 0 || token === "") {
2458
- throw gatewayError(
2459
- "auth",
2460
- "no Google access token available for Vertex AI; provide one via apiKey or the environment",
2461
- { provider: PROVIDER2 }
2462
- );
2463
- }
2464
- const target = resolveTarget(model);
2465
- const body = buildBody3(model, conversation, options);
2466
- const response = await postStream(target.url, token, body, options.signal);
2467
- const sseBody = response.body;
2468
- const tracker = { next: 0 };
2469
- for await (const event of sseEvents(sseBody, options.signal)) {
2470
- const payload = event.data;
2471
- if (payload === "" || payload === "[DONE]") {
2472
- continue;
2473
- }
2474
- let chunk;
2475
- try {
2476
- chunk = JSON.parse(payload);
2477
- } catch (cause) {
2478
- throw gatewayError("parse", "failed to parse a Vertex AI stream chunk", {
2479
- provider: PROVIDER2,
2480
- cause
2481
- });
2482
- }
2483
- if (!isObject5(chunk)) {
2484
- continue;
2485
- }
2486
- for (const emission of emitFromChunk2(chunk, tracker)) {
2487
- collected.push(emission);
2488
- yield emission;
2489
- }
2490
- }
2491
- yield { kind: "done", reply: foldReply(model.id, collected) };
2492
- } catch (cause) {
2493
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("transport", "Vertex AI stream failed", { provider: PROVIDER2, cause });
2494
- yield { kind: "error", error };
2495
- }
2496
- });
2497
- }
2498
- function complete2(model, conversation, options) {
2499
- return collectReply(stream2(model, conversation, options));
2500
- }
2501
- return {
2502
- id: "google-vertex",
2503
- api: API_KIND,
2504
- stream: stream2,
2505
- complete: complete2
2506
- };
2507
- }
2508
-
2509
- // src/llmgateway/connectors/bedrock.ts
2510
- var PROVIDER3 = "amazon";
2511
- var DIALECT = "amazon-bedrock";
2512
- var FALLBACK_REGION = "us-east-1";
2513
- function discoverRegion() {
2514
- const env = (typeof process !== "undefined" ? process.env : void 0) ?? {};
2515
- const region = env.AWS_REGION ?? env.AWS_DEFAULT_REGION ?? env.AWS_BEDROCK_REGION;
2516
- const trimmed = region?.trim();
2517
- return trimmed !== void 0 && trimmed !== "" ? trimmed : void 0;
2518
- }
2519
- function converseStreamUrl(model, region) {
2520
- const base = model.baseUrl !== void 0 && model.baseUrl !== "" ? model.baseUrl.replace(/\/+$/, "") : `https://bedrock-runtime.${region}.amazonaws.com`;
2521
- return `${base}/model/${encodeURIComponent(model.id)}/converse-stream`;
2522
- }
2523
- function stringifyOutput(output) {
2524
- if (typeof output === "string") {
2525
- return output;
2526
- }
2527
- try {
2528
- return JSON.stringify(output);
2529
- } catch {
2530
- return String(output);
2531
- }
2532
- }
2533
- function toJsonInput(input) {
2534
- if (input !== null && typeof input === "object" && !Array.isArray(input)) {
2535
- return input;
2536
- }
2537
- if (typeof input === "string") {
2538
- try {
2539
- const parsed = JSON.parse(input);
2540
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
2541
- return parsed;
2542
- }
2543
- } catch {
2544
- }
2545
- }
2546
- return { value: input };
2547
- }
2548
- function toContentBlocks(block) {
2549
- switch (block.kind) {
2550
- case "text":
2551
- return [{ text: block.text }];
2552
- case "thinking":
2553
- return [
2554
- {
2555
- reasoningContent: {
2556
- reasoningText: block.signature !== void 0 ? { text: block.text, signature: block.signature } : { text: block.text }
2557
- }
2558
- }
2559
- ];
2560
- case "image": {
2561
- const slash = block.mediaType.indexOf("/");
2562
- const format = slash >= 0 ? block.mediaType.slice(slash + 1) : block.mediaType;
2563
- return [
2564
- {
2565
- image: {
2566
- format,
2567
- source: { bytes: block.dataBase64 }
2568
- }
2569
- }
2570
- ];
2571
- }
2572
- case "tool_call":
2573
- return [
2574
- {
2575
- toolUse: {
2576
- toolUseId: block.id,
2577
- name: block.name,
2578
- input: toJsonInput(block.input)
2579
- }
2580
- }
2581
- ];
2582
- case "tool_result":
2583
- return [
2584
- {
2585
- toolResult: {
2586
- toolUseId: block.callId,
2587
- content: [{ text: stringifyOutput(block.output) }],
2588
- ...block.isError === true ? { status: "error" } : {}
2589
- }
2590
- }
2591
- ];
2592
- case "command": {
2593
- const argv = block.args && block.args.length > 0 ? ` ${block.args.join(" ")}` : "";
2594
- return [{ text: `$ ${block.command}${argv}` }];
2595
- }
2596
- }
2597
- }
2598
- function converseRole(turn) {
2599
- return turn.role === "assistant" ? "assistant" : "user";
2600
- }
2601
- function toConverseMessages(conversation) {
2602
- const messages = [];
2603
- for (const turn of conversation.turns) {
2604
- const content = [];
2605
- for (const block of turn.blocks) {
2606
- for (const wire of toContentBlocks(block)) {
2607
- content.push(wire);
2608
- }
2609
- }
2610
- if (content.length > 0) {
2611
- messages.push({ role: converseRole(turn), content });
2612
- }
2613
- }
2614
- return messages;
2615
- }
2616
- function toConverseSystem(conversation) {
2617
- if (conversation.system === void 0 || conversation.system === "") {
2618
- return void 0;
2619
- }
2620
- return [{ text: conversation.system }];
2621
- }
2622
- function toConverseTools(tools) {
2623
- if (tools === void 0 || tools.length === 0) {
2624
- return void 0;
2625
- }
2626
- return tools.map((tool) => ({
2627
- toolSpec: {
2628
- name: tool.name,
2629
- description: tool.description,
2630
- inputSchema: { json: tool.parameters }
2631
- }
2632
- }));
2633
- }
2634
- function toConverseToolChoice(options) {
2635
- switch (options.toolChoice) {
2636
- case "auto":
2637
- return { auto: {} };
2638
- case "required":
2639
- return { any: {} };
2640
- case "none":
2641
- case void 0:
2642
- return void 0;
2643
- }
2644
- }
2645
- function toInferenceConfig(model, options) {
2646
- const config = {
2647
- maxTokens: options.maxOutputTokens ?? model.maxOutputTokens
2648
- };
2649
- if (options.temperature !== void 0) {
2650
- config.temperature = options.temperature;
2651
- }
2652
- if (options.topP !== void 0) {
2653
- config.topP = options.topP;
2654
- }
2655
- return config;
2656
- }
2657
- function buildConverseBody(model, conversation, options) {
2658
- const body = {
2659
- messages: toConverseMessages(conversation),
2660
- inferenceConfig: toInferenceConfig(model, options)
2661
- };
2662
- const system = toConverseSystem(conversation);
2663
- if (system !== void 0) {
2664
- body.system = system;
2665
- }
2666
- const tools = toConverseTools(conversation.tools);
2667
- if (tools !== void 0) {
2668
- const toolConfig = { tools };
2669
- const choice = toConverseToolChoice(options);
2670
- if (choice !== void 0) {
2671
- toolConfig.toolChoice = choice;
2672
- }
2673
- body.toolConfig = toolConfig;
2674
- }
2675
- return body;
2676
- }
2677
- async function requireSignedTransport(resolveSecret2, options) {
2678
- const credential = await resolveSecret2(PROVIDER3, options.apiKey);
2679
- const region = discoverRegion() ?? FALLBACK_REGION;
2680
- void credential;
2681
- void region;
2682
- throw gatewayError(
2683
- "unsupported",
2684
- "bedrock streaming requires SigV4 (todo)",
2685
- { provider: PROVIDER3 }
2686
- );
2687
- }
2688
- function createbedrockConnector(deps2) {
2689
- const { resolveSecret: resolveSecret2 } = deps2;
2690
- return {
2691
- id: "bedrock",
2692
- api: DIALECT,
2693
- stream(model, conversation, options) {
2694
- return channelOf(async function* () {
2695
- const region = discoverRegion() ?? FALLBACK_REGION;
2696
- const url = converseStreamUrl(model, region);
2697
- const body = buildConverseBody(model, conversation, options);
2698
- void url;
2699
- void body;
2700
- await requireSignedTransport(resolveSecret2, options);
2701
- });
2702
- },
2703
- complete(model, conversation, options) {
2704
- return collectReply(this.stream(model, conversation, options));
2705
- }
2706
- };
2707
- }
2708
-
2709
- // src/llmgateway/connectors/azure-openai.ts
2710
- var AZURE_API_VERSION = "2024-08-01-preview";
2711
- function deploymentName(model) {
2712
- const id = model.id.trim();
2713
- if (id === "") {
2714
- throw gatewayError(
2715
- "unsupported",
2716
- "azure card is missing an id to use as the deployment name",
2717
- { provider: model.provider }
2718
- );
2719
- }
2720
- return id;
2721
- }
2722
- function endpointFor3(model) {
2723
- const base = model.baseUrl?.replace(/\/+$/, "");
2724
- if (base === void 0 || base === "") {
2725
- throw gatewayError(
2726
- "unsupported",
2727
- "azure card has no baseUrl; set it to the resource endpoint, e.g. https://<resource>.openai.azure.com",
2728
- { provider: model.provider }
2729
- );
2730
- }
2731
- const deployment = encodeURIComponent(deploymentName(model));
2732
- const query = new URLSearchParams({ "api-version": AZURE_API_VERSION });
2733
- return `${base}/openai/deployments/${deployment}/chat/completions?${query.toString()}`;
2734
- }
2735
- var AzureOpenAIConnector = class {
2736
- constructor(deps2) {
2737
- this.deps = deps2;
2738
- }
2739
- deps;
2740
- id = "azure-openai";
2741
- api = "azure-openai";
2742
- stream(model, conversation, options) {
2743
- const deps2 = this.deps;
2744
- return channelOf(async function* run() {
2745
- let cfg;
2746
- try {
2747
- cfg = await resolveConfig2(deps2, model, options);
2748
- } catch (cause) {
2749
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("auth", "could not prepare the Azure OpenAI request", {
2750
- provider: model.provider,
2751
- cause
2752
- });
2753
- yield { kind: "error", error };
2754
- return;
2755
- }
2756
- yield* streamOpenAICompatibleChat(cfg, model, conversation, options);
2757
- });
2758
- }
2759
- async complete(model, conversation, options) {
2760
- return collectReply(this.stream(model, conversation, options));
2761
- }
2762
- };
2763
- async function resolveConfig2(deps2, model, options) {
2764
- const url = endpointFor3(model);
2765
- const key = await deps2.resolveSecret(model.provider, options.apiKey);
2766
- if (key === void 0 || key === "") {
2767
- throw gatewayError(
2768
- "auth",
2769
- "no Azure OpenAI credential found \u2014 set AZURE_OPENAI_API_KEY (or AZURE_API_KEY), or pass options.apiKey",
2770
- { provider: model.provider }
2771
- );
2772
- }
2773
- return {
2774
- url,
2775
- // Azure authenticates with an api-key header, not an OpenAI bearer token.
2776
- headers: { "api-key": key }
2777
- };
2778
- }
2779
- function createazureopenaiConnector(deps2) {
2780
- return new AzureOpenAIConnector(deps2);
2781
- }
2782
-
2783
- // src/llmgateway/connectors/nvidia.ts
2784
- var DEFAULT_NVIDIA_BASE_URL = "https://integrate.api.nvidia.com/v1";
2785
- function endpointFor4(model) {
2786
- const base = (model.baseUrl ?? DEFAULT_NVIDIA_BASE_URL).replace(/\/+$/, "");
2787
- return `${base}/chat/completions`;
2788
- }
2789
- function bodyOverridesFor(model) {
2790
- if (!model.reasoning) {
2791
- return void 0;
2792
- }
2793
- return { chat_template_kwargs: { thinking: true } };
2794
- }
2795
- var NvidiaConnector = class {
2796
- constructor(deps2) {
2797
- this.deps = deps2;
2798
- }
2799
- deps;
2800
- id = "nvidia";
2801
- api = "nvidia-openai-compatible";
2802
- stream(model, conversation, options) {
2803
- const deps2 = this.deps;
2804
- return channelOf(async function* run() {
2805
- let cfg;
2806
- try {
2807
- cfg = await assembleConfig(deps2, model, options);
2808
- } catch (cause) {
2809
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("auth", "unable to prepare the NVIDIA request", {
2810
- provider: model.provider,
2811
- cause
2812
- });
2813
- yield { kind: "error", error };
2814
- return;
2815
- }
2816
- yield* streamOpenAICompatibleChat(cfg, model, conversation, options);
2817
- });
2818
- }
2819
- async complete(model, conversation, options) {
2820
- return collectReply(this.stream(model, conversation, options));
2821
- }
2822
- };
2823
- async function assembleConfig(deps2, model, options) {
2824
- const key = await deps2.resolveSecret(model.provider, options.apiKey);
2825
- if (key === void 0 || key === "") {
2826
- throw gatewayError(
2827
- "auth",
2828
- "missing NVIDIA credential \u2014 set NVIDIA_API_KEY or pass options.apiKey",
2829
- { provider: model.provider }
2830
- );
2831
- }
2832
- const bodyExtra = bodyOverridesFor(model);
2833
- return {
2834
- url: endpointFor4(model),
2835
- headers: { authorization: `Bearer ${key}` },
2836
- ...bodyExtra ? { bodyExtra } : {}
2837
- };
2838
- }
2839
- function createnvidiaConnector(deps2) {
2840
- return new NvidiaConnector(deps2);
2841
- }
2842
-
2843
- // src/llmgateway/connectors/kimi.ts
2844
- var DEFAULT_MOONSHOT_BASE_URL = "https://api.moonshot.ai/v1";
2845
- function endpointFor5(model) {
2846
- const base = (model.baseUrl ?? DEFAULT_MOONSHOT_BASE_URL).replace(/\/+$/, "");
2847
- return `${base}/chat/completions`;
2848
- }
2849
- var KimiConnector = class {
2850
- constructor(deps2) {
2851
- this.deps = deps2;
2852
- }
2853
- deps;
2854
- id = "kimi";
2855
- api = "kimi-openai-compatible";
2856
- stream(model, conversation, options) {
2857
- const deps2 = this.deps;
2858
- return channelOf(async function* run() {
2859
- let cfg;
2860
- try {
2861
- cfg = await resolveConfig3(deps2, model, options);
2862
- } catch (cause) {
2863
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("auth", "could not prepare the Kimi request", {
2864
- provider: model.provider,
2865
- cause
2866
- });
2867
- yield { kind: "error", error };
2868
- return;
2869
- }
2870
- yield* streamOpenAICompatibleChat(cfg, model, conversation, options);
2871
- });
2872
- }
2873
- async complete(model, conversation, options) {
2874
- return collectReply(this.stream(model, conversation, options));
2875
- }
2876
- };
2877
- async function resolveConfig3(deps2, model, options) {
2878
- const key = await deps2.resolveSecret(model.provider, options.apiKey);
2879
- if (key === void 0 || key === "") {
2880
- throw gatewayError(
2881
- "auth",
2882
- "no Kimi credential found \u2014 set MOONSHOT_API_KEY (or KIMI_API_KEY), or pass options.apiKey",
2883
- { provider: model.provider }
2884
- );
2885
- }
2886
- return {
2887
- url: endpointFor5(model),
2888
- headers: { authorization: `Bearer ${key}` }
2889
- };
2890
- }
2891
- function createkimiConnector(deps2) {
2892
- return new KimiConnector(deps2);
2893
- }
2894
-
2895
- // src/llmgateway/connectors/ollama.ts
2896
- var DEFAULT_BASE_URL3 = "http://localhost:11434";
2897
- var PROVIDER4 = "ollama";
2898
- function isObject6(value) {
2899
- return typeof value === "object" && value !== null;
2900
- }
2901
- function readString5(o, key) {
2902
- const v = o[key];
2903
- return typeof v === "string" ? v : void 0;
2904
- }
2905
- function readNumber5(o, key) {
2906
- const v = o[key];
2907
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
2908
- }
2909
- function buildOptions(model, opts) {
2910
- const options = {};
2911
- const numPredict = opts.maxOutputTokens ?? model.maxOutputTokens;
2912
- if (numPredict > 0) {
2913
- options.num_predict = numPredict;
2914
- }
2915
- if (opts.temperature !== void 0) {
2916
- options.temperature = opts.temperature;
2917
- }
2918
- if (opts.topP !== void 0) {
2919
- options.top_p = opts.topP;
2920
- }
2921
- return Object.keys(options).length > 0 ? options : void 0;
2922
- }
2923
- function buildRequestBody2(model, conversation, opts) {
2924
- const body = {
2925
- model: model.id,
2926
- messages: toOpenAIChatMessages(conversation),
2927
- stream: true
2928
- };
2929
- const tools = toOpenAITools(conversation.tools);
2930
- if (tools !== void 0) {
2931
- body.tools = tools;
2932
- }
2933
- const options = buildOptions(model, opts);
2934
- if (options !== void 0) {
2935
- body.options = options;
2936
- }
2937
- return body;
2938
- }
2939
- function chatEndpoint(model) {
2940
- const base = (model.baseUrl ?? DEFAULT_BASE_URL3).replace(/\/+$/u, "");
2941
- return `${base}/api/chat`;
2942
- }
2943
- function buildHeaders(secret) {
2944
- const headers = { "content-type": "application/json" };
2945
- if (secret !== void 0 && secret !== "") {
2946
- headers.authorization = `Bearer ${secret}`;
2947
- }
2948
- return headers;
2949
- }
2950
- async function openStream2(url, headers, body, signal) {
2951
- let response;
2952
- try {
2953
- response = await fetch(url, {
2954
- method: "POST",
2955
- headers,
2956
- body: JSON.stringify(body),
2957
- ...signal !== void 0 ? { signal } : {}
2958
- });
2959
- } catch (cause) {
2960
- if (signal?.aborted) {
2961
- throw gatewayError("aborted", "the Ollama request was aborted before a response arrived", {
2962
- provider: PROVIDER4,
2963
- cause
2964
- });
2965
- }
2966
- throw gatewayError("transport", "could not reach the Ollama daemon (is `ollama serve` running?)", {
2967
- provider: PROVIDER4,
2968
- cause
2969
- });
2970
- }
2971
- if (!response.ok) {
2972
- const detail = await readErrorDetail2(response);
2973
- const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
2974
- throw gatewayError(kind, `Ollama replied with HTTP ${response.status}${detail}`, {
2975
- provider: PROVIDER4,
2976
- status: response.status
2977
- });
2978
- }
2979
- if (response.body === null) {
2980
- throw gatewayError("transport", "the Ollama response carried no body to stream", {
2981
- provider: PROVIDER4,
2982
- status: response.status
2983
- });
2984
- }
2985
- return response;
2986
- }
2987
- async function readErrorDetail2(response) {
2988
- try {
2989
- const text = await response.text();
2990
- return text === "" ? "" : `: ${text.slice(0, 500)}`;
2991
- } catch {
2992
- return "";
2993
- }
2994
- }
2995
- function mapDoneReason(reason) {
2996
- switch (reason) {
2997
- case "stop":
2998
- return "complete";
2999
- case "length":
3000
- return "max_output";
3001
- case void 0:
3002
- case "":
3003
- return void 0;
3004
- default:
3005
- return "complete";
3006
- }
3007
- }
3008
- function readUsage4(line) {
3009
- const inputTokens = readNumber5(line, "prompt_eval_count");
3010
- const outputTokens = readNumber5(line, "eval_count");
3011
- if (inputTokens === void 0 && outputTokens === void 0) {
3012
- return void 0;
3013
- }
3014
- return {
3015
- inputTokens: inputTokens ?? 0,
3016
- outputTokens: outputTokens ?? 0
3017
- };
3018
- }
3019
- function serializeArgs3(args) {
3020
- if (typeof args === "string") {
3021
- return args;
3022
- }
3023
- try {
3024
- return JSON.stringify(args ?? {});
3025
- } catch {
3026
- return "{}";
3027
- }
3028
- }
3029
- function* emitToolCalls(toolCalls, tracker) {
3030
- for (const entry of toolCalls) {
3031
- if (!isObject6(entry)) {
3032
- continue;
3033
- }
3034
- const fn = entry.function;
3035
- if (!isObject6(fn)) {
3036
- continue;
3037
- }
3038
- const name = readString5(fn, "name") ?? "";
3039
- const id = `ollama_call_${tracker.next}`;
3040
- tracker.next += 1;
3041
- yield { kind: "tool_call_start", id, name };
3042
- const args = "arguments" in fn ? fn.arguments : {};
3043
- yield { kind: "tool_call_delta", id, argsDelta: serializeArgs3(args) };
3044
- }
3045
- }
3046
- function* emitFromLine(line, tracker) {
3047
- const message = line.message;
3048
- if (isObject6(message)) {
3049
- const content = readString5(message, "content");
3050
- if (content !== void 0 && content !== "") {
3051
- yield { kind: "text", delta: content };
3052
- }
3053
- const toolCalls = message.tool_calls;
3054
- if (Array.isArray(toolCalls)) {
3055
- yield* emitToolCalls(toolCalls, tracker);
3056
- }
3057
- }
3058
- if (line.done === true) {
3059
- const usage = readUsage4(line);
3060
- if (usage !== void 0) {
3061
- yield { kind: "usage", usage };
3062
- }
3063
- const stop = mapDoneReason(readString5(line, "done_reason"));
3064
- if (stop !== void 0) {
3065
- yield { kind: "stop", stop };
3066
- }
3067
- }
3068
- }
3069
- function createollamaConnector(deps2) {
3070
- const { resolveSecret: resolveSecret2 } = deps2;
3071
- return {
3072
- id: "ollama",
3073
- api: "ollama",
3074
- stream(model, conversation, options) {
3075
- return channelOf(async function* run() {
3076
- const collected = [];
3077
- try {
3078
- const secret = await resolveSecret2(PROVIDER4, options.apiKey);
3079
- const url = chatEndpoint(model);
3080
- const headers = buildHeaders(secret);
3081
- const body = buildRequestBody2(model, conversation, options);
3082
- const response = await openStream2(url, headers, body, options.signal);
3083
- const wire = response.body;
3084
- const tracker = { next: 0 };
3085
- for await (const value of ndjsonLines(wire, options.signal)) {
3086
- if (!isObject6(value)) {
3087
- continue;
3088
- }
3089
- for (const emission of emitFromLine(value, tracker)) {
3090
- collected.push(emission);
3091
- yield emission;
3092
- }
3093
- if (value.done === true) {
3094
- break;
3095
- }
3096
- }
3097
- const reply = foldReply(model.id, collected);
3098
- yield { kind: "done", reply };
3099
- } catch (cause) {
3100
- const error = cause instanceof Error && cause.name === "GatewayError" ? cause : gatewayError("transport", "the Ollama stream failed", { provider: PROVIDER4, cause });
3101
- yield { kind: "error", error };
3102
- }
3103
- });
3104
- },
3105
- complete(model, conversation, options) {
3106
- return collectReply(this.stream(model, conversation, options));
3107
- }
3108
- };
3109
- }
3110
-
3111
- // src/llmgateway/connectors/mock.ts
3112
- var ECHO_CALL_ID = "mock_call_0";
3113
- var SCRIPTED_USAGE = {
3114
- inputTokens: 8,
3115
- outputTokens: 5
3116
- };
3117
- function scriptedDeltas() {
3118
- return [
3119
- { kind: "text", delta: "Hello" },
3120
- { kind: "text", delta: " world" },
3121
- { kind: "tool_call_start", id: ECHO_CALL_ID, name: "echo" },
3122
- { kind: "tool_call_delta", id: ECHO_CALL_ID, argsDelta: '{"msg":"hi"}' },
3123
- { kind: "usage", usage: { ...SCRIPTED_USAGE } },
3124
- { kind: "stop", stop: "tool_calls" }
3125
- ];
3126
- }
3127
- function finalDeltas() {
3128
- return [
3129
- { kind: "text", delta: "Hello world" },
3130
- { kind: "usage", usage: { ...SCRIPTED_USAGE } },
3131
- { kind: "stop", stop: "complete" }
3132
- ];
3133
- }
3134
- function hasToolResult(conversation) {
3135
- return conversation.turns.some((turn) => turn.blocks.some((block) => block.kind === "tool_result"));
3136
- }
3137
- function echoOffered(conversation) {
3138
- return (conversation.tools ?? []).some((tool) => tool.name === "echo");
3139
- }
3140
- function pickDeltas(conversation) {
3141
- return !hasToolResult(conversation) && echoOffered(conversation) ? scriptedDeltas() : finalDeltas();
3142
- }
3143
- var MockConnector = class {
3144
- id = "mock";
3145
- api = "mock";
3146
- // The resolver is accepted for factory symmetry with the live connectors; the
3147
- // mock dialect needs no credential, so it is intentionally not retained.
3148
- constructor(_deps) {
3149
- }
3150
- stream(model, conversation, options) {
3151
- const isAborted = () => options.signal?.aborted ?? false;
3152
- const deltas = pickDeltas(conversation);
3153
- return channelOf(async function* run() {
3154
- if (isAborted()) {
3155
- yield abortedDone(model.id);
3156
- return;
3157
- }
3158
- for (const delta of deltas) {
3159
- if (isAborted()) {
3160
- yield abortedDone(model.id);
3161
- return;
3162
- }
3163
- yield delta;
3164
- }
3165
- yield { kind: "done", reply: foldReply(model.id, deltas) };
3166
- });
3167
- }
3168
- async complete(model, conversation, options) {
3169
- return collectReply(this.stream(model, conversation, options));
3170
- }
3171
- };
3172
- function abortedDone(modelId) {
3173
- const reply = {
3174
- role: "assistant",
3175
- model: modelId,
3176
- blocks: [],
3177
- usage: { inputTokens: 0, outputTokens: 0 },
3178
- stop: "aborted"
3179
- };
3180
- return { kind: "done", reply };
3181
- }
3182
- function createmockConnector(deps2) {
3183
- return new MockConnector(deps2);
3184
- }
3185
-
3186
- // src/llmgateway/connectors/index.ts
3187
- var deps = { resolveSecret };
3188
- var CONNECTOR_REGISTRY = {
3189
- "anthropic-messages": createanthropicConnector(deps),
3190
- "openai-completions": createopenaichatConnector(deps),
3191
- "openai-responses": createopenairesponsesConnector(deps),
3192
- "google-generative": creategoogleConnector(deps),
3193
- "google-vertex": creategooglevertexConnector(deps),
3194
- "amazon-bedrock": createbedrockConnector(deps),
3195
- "azure-openai": createazureopenaiConnector(deps),
3196
- "nvidia-openai-compatible": createnvidiaConnector(deps),
3197
- "kimi-openai-compatible": createkimiConnector(deps),
3198
- ollama: createollamaConnector(deps),
3199
- mock: createmockConnector(deps)
3200
- };
3201
- function connectorForApi(api) {
3202
- return CONNECTOR_REGISTRY[api];
3203
- }
3204
-
3205
- // src/llmgateway/gateway.ts
3206
- var NO_OPTIONS = {};
3207
- function stream(modelId, conversation, options) {
3208
- const card = getCard(modelId);
3209
- if (card === void 0) {
3210
- throw gatewayError("unsupported", `unknown model: ${modelId}`);
3211
- }
3212
- return streamWithCard(card, conversation, options);
3213
- }
3214
- function streamWithCard(card, conversation, options) {
3215
- const connector = connectorForApi(card.api);
3216
- return connector.stream(card, conversation, options ?? NO_OPTIONS);
3217
- }
3218
- function complete(modelId, conversation, options) {
3219
- const card = getCard(modelId);
3220
- if (card === void 0) {
3221
- throw gatewayError("unsupported", `unknown model: ${modelId}`);
3222
- }
3223
- return completeWithCard(card, conversation, options);
3224
- }
3225
- function completeWithCard(card, conversation, options) {
3226
- const connector = connectorForApi(card.api);
3227
- return connector.complete(card, conversation, options ?? NO_OPTIONS);
3228
- }
3229
- export {
3230
- CONNECTOR_REGISTRY,
3231
- CardSelection,
3232
- GatewayError,
3233
- MODEL_CARDS,
3234
- complete,
3235
- completeWithCard,
3236
- connectorForApi,
3237
- estimateCost,
3238
- gatewayError,
3239
- getCard,
3240
- models,
3241
- stream,
3242
- streamWithCard
3243
- };