bikky 0.3.1 → 0.3.3

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 (342) hide show
  1. package/README.md +124 -35
  2. package/dist/cli.d.ts +1 -0
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +7 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +22 -3
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +61 -6
  9. package/dist/config.js.map +1 -1
  10. package/dist/config.test.js +17 -9
  11. package/dist/config.test.js.map +1 -1
  12. package/dist/daemon/capture-policy.d.ts +95 -0
  13. package/dist/daemon/capture-policy.d.ts.map +1 -0
  14. package/dist/daemon/capture-policy.js +139 -0
  15. package/dist/daemon/capture-policy.js.map +1 -0
  16. package/dist/daemon/capture-policy.test.d.ts +2 -0
  17. package/dist/daemon/capture-policy.test.d.ts.map +1 -0
  18. package/dist/daemon/capture-policy.test.js +46 -0
  19. package/dist/daemon/capture-policy.test.js.map +1 -0
  20. package/dist/daemon/consolidation.d.ts.map +1 -1
  21. package/dist/daemon/consolidation.js +84 -98
  22. package/dist/daemon/consolidation.js.map +1 -1
  23. package/dist/daemon/episode-summary.d.ts +72 -0
  24. package/dist/daemon/episode-summary.d.ts.map +1 -0
  25. package/dist/daemon/episode-summary.js +208 -0
  26. package/dist/daemon/episode-summary.js.map +1 -0
  27. package/dist/daemon/episode-summary.test.d.ts +2 -0
  28. package/dist/daemon/episode-summary.test.d.ts.map +1 -0
  29. package/dist/daemon/episode-summary.test.js +101 -0
  30. package/dist/daemon/episode-summary.test.js.map +1 -0
  31. package/dist/daemon/extraction.d.ts +25 -0
  32. package/dist/daemon/extraction.d.ts.map +1 -1
  33. package/dist/daemon/extraction.js +244 -124
  34. package/dist/daemon/extraction.js.map +1 -1
  35. package/dist/daemon/extraction.test.d.ts +2 -0
  36. package/dist/daemon/extraction.test.d.ts.map +1 -0
  37. package/dist/daemon/extraction.test.js +106 -0
  38. package/dist/daemon/extraction.test.js.map +1 -0
  39. package/dist/daemon/loop.d.ts.map +1 -1
  40. package/dist/daemon/loop.js +8 -6
  41. package/dist/daemon/loop.js.map +1 -1
  42. package/dist/daemon/qdrant.d.ts +59 -8
  43. package/dist/daemon/qdrant.d.ts.map +1 -1
  44. package/dist/daemon/qdrant.js +74 -23
  45. package/dist/daemon/qdrant.js.map +1 -1
  46. package/dist/daemon/qdrant.test.js +2 -2
  47. package/dist/daemon/qdrant.test.js.map +1 -1
  48. package/dist/daemon/relations.d.ts +6 -1
  49. package/dist/daemon/relations.d.ts.map +1 -1
  50. package/dist/daemon/relations.js +44 -63
  51. package/dist/daemon/relations.js.map +1 -1
  52. package/dist/daemon/session-index.d.ts +60 -0
  53. package/dist/daemon/session-index.d.ts.map +1 -0
  54. package/dist/daemon/session-index.js +136 -0
  55. package/dist/daemon/session-index.js.map +1 -0
  56. package/dist/daemon/session-index.test.d.ts +2 -0
  57. package/dist/daemon/session-index.test.d.ts.map +1 -0
  58. package/dist/daemon/session-index.test.js +54 -0
  59. package/dist/daemon/session-index.test.js.map +1 -0
  60. package/dist/daemon/session-summary.d.ts +69 -0
  61. package/dist/daemon/session-summary.d.ts.map +1 -0
  62. package/dist/daemon/session-summary.js +200 -0
  63. package/dist/daemon/session-summary.js.map +1 -0
  64. package/dist/daemon/session-summary.test.d.ts +2 -0
  65. package/dist/daemon/session-summary.test.d.ts.map +1 -0
  66. package/dist/daemon/session-summary.test.js +160 -0
  67. package/dist/daemon/session-summary.test.js.map +1 -0
  68. package/dist/daemon/staleness.test.d.ts +7 -0
  69. package/dist/daemon/staleness.test.d.ts.map +1 -0
  70. package/dist/daemon/staleness.test.js +128 -0
  71. package/dist/daemon/staleness.test.js.map +1 -0
  72. package/dist/daemon/workstream-summary.d.ts +61 -0
  73. package/dist/daemon/workstream-summary.d.ts.map +1 -0
  74. package/dist/daemon/workstream-summary.js +220 -0
  75. package/dist/daemon/workstream-summary.js.map +1 -0
  76. package/dist/daemon/workstream-summary.test.d.ts +2 -0
  77. package/dist/daemon/workstream-summary.test.d.ts.map +1 -0
  78. package/dist/daemon/workstream-summary.test.js +86 -0
  79. package/dist/daemon/workstream-summary.test.js.map +1 -0
  80. package/dist/lib/qdrant-client.d.ts +6 -1
  81. package/dist/lib/qdrant-client.d.ts.map +1 -1
  82. package/dist/lib/qdrant-client.js +3 -4
  83. package/dist/lib/qdrant-client.js.map +1 -1
  84. package/dist/lib/qdrant-client.test.js +21 -2
  85. package/dist/lib/qdrant-client.test.js.map +1 -1
  86. package/dist/lifecycle.test.d.ts +8 -0
  87. package/dist/lifecycle.test.d.ts.map +1 -0
  88. package/dist/lifecycle.test.js +74 -0
  89. package/dist/lifecycle.test.js.map +1 -0
  90. package/dist/llm/embedding/index.d.ts +42 -0
  91. package/dist/llm/embedding/index.d.ts.map +1 -0
  92. package/dist/llm/embedding/index.js +78 -0
  93. package/dist/llm/embedding/index.js.map +1 -0
  94. package/dist/llm/embedding/index.test.d.ts +8 -0
  95. package/dist/llm/embedding/index.test.d.ts.map +1 -0
  96. package/dist/llm/embedding/index.test.js +100 -0
  97. package/dist/llm/embedding/index.test.js.map +1 -0
  98. package/dist/llm/embedding/providers/bedrock.d.ts +16 -0
  99. package/dist/llm/embedding/providers/bedrock.d.ts.map +1 -0
  100. package/dist/llm/embedding/providers/bedrock.js +90 -0
  101. package/dist/llm/embedding/providers/bedrock.js.map +1 -0
  102. package/dist/llm/embedding/providers/bedrock.test.d.ts +2 -0
  103. package/dist/llm/embedding/providers/bedrock.test.d.ts.map +1 -0
  104. package/dist/llm/embedding/providers/bedrock.test.js +24 -0
  105. package/dist/llm/embedding/providers/bedrock.test.js.map +1 -0
  106. package/dist/llm/embedding/providers/index.d.ts +9 -0
  107. package/dist/llm/embedding/providers/index.d.ts.map +1 -0
  108. package/dist/llm/embedding/providers/index.js +9 -0
  109. package/dist/llm/embedding/providers/index.js.map +1 -0
  110. package/dist/llm/embedding/providers/ollama.d.ts +6 -0
  111. package/dist/llm/embedding/providers/ollama.d.ts.map +1 -0
  112. package/dist/llm/embedding/providers/ollama.js +39 -0
  113. package/dist/llm/embedding/providers/ollama.js.map +1 -0
  114. package/dist/llm/embedding/providers/ollama.test.d.ts +2 -0
  115. package/dist/llm/embedding/providers/ollama.test.d.ts.map +1 -0
  116. package/dist/llm/embedding/providers/ollama.test.js +54 -0
  117. package/dist/llm/embedding/providers/ollama.test.js.map +1 -0
  118. package/dist/llm/embedding/providers/openai.d.ts +6 -0
  119. package/dist/llm/embedding/providers/openai.d.ts.map +1 -0
  120. package/dist/llm/embedding/providers/openai.js +44 -0
  121. package/dist/llm/embedding/providers/openai.js.map +1 -0
  122. package/dist/llm/embedding/providers/openai.test.d.ts +2 -0
  123. package/dist/llm/embedding/providers/openai.test.d.ts.map +1 -0
  124. package/dist/llm/embedding/providers/openai.test.js +48 -0
  125. package/dist/llm/embedding/providers/openai.test.js.map +1 -0
  126. package/dist/llm/embedding/providers/portkey.d.ts +15 -0
  127. package/dist/llm/embedding/providers/portkey.d.ts.map +1 -0
  128. package/dist/llm/embedding/providers/portkey.js +58 -0
  129. package/dist/llm/embedding/providers/portkey.js.map +1 -0
  130. package/dist/llm/embedding/providers/portkey.test.d.ts +2 -0
  131. package/dist/llm/embedding/providers/portkey.test.d.ts.map +1 -0
  132. package/dist/llm/embedding/providers/portkey.test.js +56 -0
  133. package/dist/llm/embedding/providers/portkey.test.js.map +1 -0
  134. package/dist/llm/embedding/registry.d.ts +14 -0
  135. package/dist/llm/embedding/registry.d.ts.map +1 -0
  136. package/dist/llm/embedding/registry.js +27 -0
  137. package/dist/llm/embedding/registry.js.map +1 -0
  138. package/dist/llm/embedding/registry.test.d.ts +7 -0
  139. package/dist/llm/embedding/registry.test.d.ts.map +1 -0
  140. package/dist/llm/embedding/registry.test.js +68 -0
  141. package/dist/llm/embedding/registry.test.js.map +1 -0
  142. package/dist/llm/embedding/types.d.ts +55 -0
  143. package/dist/llm/embedding/types.d.ts.map +1 -0
  144. package/dist/llm/embedding/types.js +12 -0
  145. package/dist/llm/embedding/types.js.map +1 -0
  146. package/dist/llm/errors.d.ts +95 -0
  147. package/dist/llm/errors.d.ts.map +1 -0
  148. package/dist/llm/errors.js +164 -0
  149. package/dist/llm/errors.js.map +1 -0
  150. package/dist/llm/errors.test.d.ts +2 -0
  151. package/dist/llm/errors.test.d.ts.map +1 -0
  152. package/dist/llm/errors.test.js +103 -0
  153. package/dist/llm/errors.test.js.map +1 -0
  154. package/dist/llm/fetch.d.ts +39 -0
  155. package/dist/llm/fetch.d.ts.map +1 -0
  156. package/dist/llm/fetch.js +52 -0
  157. package/dist/llm/fetch.js.map +1 -0
  158. package/dist/llm/index.d.ts +6 -3
  159. package/dist/llm/index.d.ts.map +1 -1
  160. package/dist/llm/index.js +2 -2
  161. package/dist/llm/index.js.map +1 -1
  162. package/dist/llm/inference/index.d.ts +39 -0
  163. package/dist/llm/inference/index.d.ts.map +1 -0
  164. package/dist/llm/inference/index.js +118 -0
  165. package/dist/llm/inference/index.js.map +1 -0
  166. package/dist/llm/inference/index.test.d.ts +6 -0
  167. package/dist/llm/inference/index.test.d.ts.map +1 -0
  168. package/dist/llm/inference/index.test.js +109 -0
  169. package/dist/llm/inference/index.test.js.map +1 -0
  170. package/dist/llm/inference/providers/bedrock.d.ts +18 -0
  171. package/dist/llm/inference/providers/bedrock.d.ts.map +1 -0
  172. package/dist/llm/inference/providers/bedrock.js +105 -0
  173. package/dist/llm/inference/providers/bedrock.js.map +1 -0
  174. package/dist/llm/inference/providers/bedrock.test.d.ts +2 -0
  175. package/dist/llm/inference/providers/bedrock.test.d.ts.map +1 -0
  176. package/dist/llm/inference/providers/bedrock.test.js +21 -0
  177. package/dist/llm/inference/providers/bedrock.test.js.map +1 -0
  178. package/dist/llm/inference/providers/index.d.ts +10 -0
  179. package/dist/llm/inference/providers/index.d.ts.map +1 -0
  180. package/dist/llm/inference/providers/index.js +10 -0
  181. package/dist/llm/inference/providers/index.js.map +1 -0
  182. package/dist/llm/inference/providers/ollama.d.ts +8 -0
  183. package/dist/llm/inference/providers/ollama.d.ts.map +1 -0
  184. package/dist/llm/inference/providers/ollama.js +63 -0
  185. package/dist/llm/inference/providers/ollama.js.map +1 -0
  186. package/dist/llm/inference/providers/ollama.test.d.ts +2 -0
  187. package/dist/llm/inference/providers/ollama.test.d.ts.map +1 -0
  188. package/dist/llm/inference/providers/ollama.test.js +57 -0
  189. package/dist/llm/inference/providers/ollama.test.js.map +1 -0
  190. package/dist/llm/inference/providers/openai.d.ts +11 -0
  191. package/dist/llm/inference/providers/openai.d.ts.map +1 -0
  192. package/dist/llm/inference/providers/openai.js +73 -0
  193. package/dist/llm/inference/providers/openai.js.map +1 -0
  194. package/dist/llm/inference/providers/openai.test.d.ts +2 -0
  195. package/dist/llm/inference/providers/openai.test.d.ts.map +1 -0
  196. package/dist/llm/inference/providers/openai.test.js +46 -0
  197. package/dist/llm/inference/providers/openai.test.js.map +1 -0
  198. package/dist/llm/inference/providers/portkey.d.ts +13 -0
  199. package/dist/llm/inference/providers/portkey.d.ts.map +1 -0
  200. package/dist/llm/inference/providers/portkey.js +80 -0
  201. package/dist/llm/inference/providers/portkey.js.map +1 -0
  202. package/dist/llm/inference/providers/portkey.test.d.ts +2 -0
  203. package/dist/llm/inference/providers/portkey.test.d.ts.map +1 -0
  204. package/dist/llm/inference/providers/portkey.test.js +48 -0
  205. package/dist/llm/inference/providers/portkey.test.js.map +1 -0
  206. package/dist/llm/inference/registry.d.ts +15 -0
  207. package/dist/llm/inference/registry.d.ts.map +1 -0
  208. package/dist/llm/inference/registry.js +28 -0
  209. package/dist/llm/inference/registry.js.map +1 -0
  210. package/dist/llm/inference/registry.test.d.ts +6 -0
  211. package/dist/llm/inference/registry.test.d.ts.map +1 -0
  212. package/dist/llm/inference/registry.test.js +63 -0
  213. package/dist/llm/inference/registry.test.js.map +1 -0
  214. package/dist/llm/inference/types.d.ts +84 -0
  215. package/dist/llm/inference/types.d.ts.map +1 -0
  216. package/dist/llm/inference/types.js +9 -0
  217. package/dist/llm/inference/types.js.map +1 -0
  218. package/dist/llm/telemetry.d.ts +25 -0
  219. package/dist/llm/telemetry.d.ts.map +1 -0
  220. package/dist/llm/telemetry.js +43 -0
  221. package/dist/llm/telemetry.js.map +1 -0
  222. package/dist/llm/telemetry.test.d.ts +5 -0
  223. package/dist/llm/telemetry.test.d.ts.map +1 -0
  224. package/dist/llm/telemetry.test.js +89 -0
  225. package/dist/llm/telemetry.test.js.map +1 -0
  226. package/dist/llm/types.d.ts +4 -37
  227. package/dist/llm/types.d.ts.map +1 -1
  228. package/dist/llm/types.js +4 -1
  229. package/dist/llm/types.js.map +1 -1
  230. package/dist/logger.d.ts +18 -3
  231. package/dist/logger.d.ts.map +1 -1
  232. package/dist/logger.js +102 -20
  233. package/dist/logger.js.map +1 -1
  234. package/dist/logger.test.d.ts +5 -0
  235. package/dist/logger.test.d.ts.map +1 -0
  236. package/dist/logger.test.js +103 -0
  237. package/dist/logger.test.js.map +1 -0
  238. package/dist/mcp/api.d.ts +15 -1
  239. package/dist/mcp/api.d.ts.map +1 -1
  240. package/dist/mcp/api.js +44 -19
  241. package/dist/mcp/api.js.map +1 -1
  242. package/dist/mcp/api.test.d.ts +6 -0
  243. package/dist/mcp/api.test.d.ts.map +1 -0
  244. package/dist/mcp/api.test.js +130 -0
  245. package/dist/mcp/api.test.js.map +1 -0
  246. package/dist/mcp/helpers.d.ts +1 -0
  247. package/dist/mcp/helpers.d.ts.map +1 -1
  248. package/dist/mcp/helpers.js +62 -6
  249. package/dist/mcp/helpers.js.map +1 -1
  250. package/dist/mcp/helpers.test.js +71 -10
  251. package/dist/mcp/helpers.test.js.map +1 -1
  252. package/dist/mcp/index.d.ts +7 -1
  253. package/dist/mcp/index.d.ts.map +1 -1
  254. package/dist/mcp/index.js +46 -21
  255. package/dist/mcp/index.js.map +1 -1
  256. package/dist/mcp/taxonomy.d.ts +251 -31
  257. package/dist/mcp/taxonomy.d.ts.map +1 -1
  258. package/dist/mcp/taxonomy.js +603 -171
  259. package/dist/mcp/taxonomy.js.map +1 -1
  260. package/dist/mcp/taxonomy.test.d.ts +1 -1
  261. package/dist/mcp/taxonomy.test.js +141 -302
  262. package/dist/mcp/taxonomy.test.js.map +1 -1
  263. package/dist/mcp/tools.d.ts +1 -1
  264. package/dist/mcp/tools.d.ts.map +1 -1
  265. package/dist/mcp/tools.integration.itest.d.ts +23 -0
  266. package/dist/mcp/tools.integration.itest.d.ts.map +1 -0
  267. package/dist/mcp/tools.integration.itest.js +172 -0
  268. package/dist/mcp/tools.integration.itest.js.map +1 -0
  269. package/dist/mcp/tools.js +422 -357
  270. package/dist/mcp/tools.js.map +1 -1
  271. package/dist/mcp/tools.test.d.ts +16 -0
  272. package/dist/mcp/tools.test.d.ts.map +1 -0
  273. package/dist/mcp/tools.test.js +472 -0
  274. package/dist/mcp/tools.test.js.map +1 -0
  275. package/dist/mcp/types.d.ts +63 -8
  276. package/dist/mcp/types.d.ts.map +1 -1
  277. package/dist/prompts/brief.d.ts +19 -0
  278. package/dist/prompts/brief.d.ts.map +1 -0
  279. package/dist/prompts/brief.js +67 -0
  280. package/dist/prompts/brief.js.map +1 -0
  281. package/dist/prompts/contradiction.d.ts +24 -0
  282. package/dist/prompts/contradiction.d.ts.map +1 -0
  283. package/dist/prompts/contradiction.js +73 -0
  284. package/dist/prompts/contradiction.js.map +1 -0
  285. package/dist/prompts/distill.d.ts +21 -0
  286. package/dist/prompts/distill.d.ts.map +1 -0
  287. package/dist/prompts/distill.js +92 -0
  288. package/dist/prompts/distill.js.map +1 -0
  289. package/dist/prompts/episode-summary.d.ts +15 -0
  290. package/dist/prompts/episode-summary.d.ts.map +1 -0
  291. package/dist/prompts/episode-summary.js +60 -0
  292. package/dist/prompts/episode-summary.js.map +1 -0
  293. package/dist/prompts/extraction.d.ts +14 -0
  294. package/dist/prompts/extraction.d.ts.map +1 -0
  295. package/dist/prompts/extraction.js +110 -0
  296. package/dist/prompts/extraction.js.map +1 -0
  297. package/dist/prompts/index.d.ts +52 -0
  298. package/dist/prompts/index.d.ts.map +1 -0
  299. package/dist/prompts/index.js +104 -0
  300. package/dist/prompts/index.js.map +1 -0
  301. package/dist/prompts/prompts.test.d.ts +8 -0
  302. package/dist/prompts/prompts.test.d.ts.map +1 -0
  303. package/dist/prompts/prompts.test.js +140 -0
  304. package/dist/prompts/prompts.test.js.map +1 -0
  305. package/dist/prompts/relations.d.ts +17 -0
  306. package/dist/prompts/relations.d.ts.map +1 -0
  307. package/dist/prompts/relations.js +72 -0
  308. package/dist/prompts/relations.js.map +1 -0
  309. package/dist/prompts/workstream-summary.d.ts +17 -0
  310. package/dist/prompts/workstream-summary.d.ts.map +1 -0
  311. package/dist/prompts/workstream-summary.js +72 -0
  312. package/dist/prompts/workstream-summary.js.map +1 -0
  313. package/dist/render.d.ts +41 -0
  314. package/dist/render.d.ts.map +1 -0
  315. package/dist/render.js +185 -0
  316. package/dist/render.js.map +1 -0
  317. package/dist/render.test.d.ts +8 -0
  318. package/dist/render.test.d.ts.map +1 -0
  319. package/dist/render.test.js +243 -0
  320. package/dist/render.test.js.map +1 -0
  321. package/docs/diagrams/architecture.svg +87 -0
  322. package/docs/diagrams/team-memory.svg +250 -0
  323. package/docs/screenshots/dashboard.png +0 -0
  324. package/docs/screenshots/graph.png +0 -0
  325. package/docs/screenshots/memory.png +0 -0
  326. package/package.json +12 -3
  327. package/dist/llm/embedding.d.ts +0 -13
  328. package/dist/llm/embedding.d.ts.map +0 -1
  329. package/dist/llm/embedding.js +0 -127
  330. package/dist/llm/embedding.js.map +0 -1
  331. package/dist/llm/embedding.test.d.ts +0 -8
  332. package/dist/llm/embedding.test.d.ts.map +0 -1
  333. package/dist/llm/embedding.test.js +0 -117
  334. package/dist/llm/embedding.test.js.map +0 -1
  335. package/dist/llm/inference.d.ts +0 -12
  336. package/dist/llm/inference.d.ts.map +0 -1
  337. package/dist/llm/inference.js +0 -146
  338. package/dist/llm/inference.js.map +0 -1
  339. package/dist/llm/inference.test.d.ts +0 -8
  340. package/dist/llm/inference.test.d.ts.map +0 -1
  341. package/dist/llm/inference.test.js +0 -117
  342. package/dist/llm/inference.test.js.map +0 -1
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Public API for the inference (chat completion) layer.
3
+ *
4
+ * Importing this module registers all bundled providers via the side-effect
5
+ * barrel, so callers only need to call `initLLM(...)` and `chatCompletion(...)`.
6
+ *
7
+ * Failure contract: provider `chat()` returns `null` on any failure (auth,
8
+ * rate-limit, transient, timeout). The reason is recorded internally; callers
9
+ * that need to surface it to the user can call `getLastInferenceError()`. The
10
+ * fallback chain in `chatCompletion()` retries the secondary provider once,
11
+ * then logs a consolidated error covering both attempts.
12
+ */
13
+ import "./providers/index.js";
14
+ import { getInferenceProvider, listInferenceProviders, registerInferenceProvider, } from "./registry.js";
15
+ const DEFAULT_TIMEOUT_MS = 30_000;
16
+ const DEFAULT_RETRIES = 2;
17
+ const DEFAULT_RETRY_BASE_MS = 250;
18
+ let resolved = null;
19
+ let log = () => { };
20
+ let lastError = null;
21
+ export function initLLM(opts) {
22
+ const provider = getInferenceProvider(opts.config.provider);
23
+ if (opts.logger)
24
+ log = opts.logger;
25
+ resolved = {
26
+ provider: provider.name,
27
+ model: opts.config.model ?? provider.defaults.model,
28
+ baseUrl: (opts.config.baseUrl ?? provider.defaults.baseUrl ?? "").replace(/\/+$/, ""),
29
+ apiKey: opts.config.apiKey ?? null,
30
+ fallback: opts.config.fallback ?? null,
31
+ extra: opts.config.extra ?? {},
32
+ timeoutMs: opts.config.timeoutMs ?? DEFAULT_TIMEOUT_MS,
33
+ retries: opts.config.retries ?? DEFAULT_RETRIES,
34
+ retryBaseDelayMs: opts.config.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_MS,
35
+ };
36
+ lastError = null;
37
+ return resolved;
38
+ }
39
+ export function getInferenceConfig() {
40
+ if (!resolved)
41
+ throw new Error("Inference provider not initialized — call initLLM() first");
42
+ return resolved;
43
+ }
44
+ /**
45
+ * The most-recent classified error from the inference layer, or null if the
46
+ * last call succeeded. Used by MCP tools to surface a meaningful reason when
47
+ * `chatCompletion()` returns null.
48
+ */
49
+ export function getLastInferenceError() {
50
+ return lastError;
51
+ }
52
+ /**
53
+ * Internal hook used by providers to record the typed reason for a `null`
54
+ * return. Exported so providers in `./providers/*` can reach it; not part of
55
+ * the public API.
56
+ */
57
+ export function _recordInferenceError(err) {
58
+ lastError = err;
59
+ }
60
+ export async function chatCompletion(opts) {
61
+ const cfg = getInferenceConfig();
62
+ lastError = null;
63
+ const primary = getInferenceProvider(cfg.provider);
64
+ const result = await primary.chat(opts, cfg, log);
65
+ if (result !== null)
66
+ return result;
67
+ const primaryErr = getLastInferenceError();
68
+ if (!cfg.fallback) {
69
+ if (primaryErr) {
70
+ log("ERROR", `LLM ${cfg.provider} failed (${primaryErr.kind}): ${primaryErr.message}`);
71
+ }
72
+ return null;
73
+ }
74
+ log("INFO", `LLM: ${cfg.provider} returned null${primaryErr ? ` (${primaryErr.kind})` : ""}, falling back to ${cfg.fallback}`);
75
+ const fallback = getInferenceProvider(cfg.fallback);
76
+ const fallbackCfg = {
77
+ ...cfg,
78
+ provider: fallback.name,
79
+ model: fallback.defaults.model,
80
+ baseUrl: fallback.defaults.baseUrl ?? "",
81
+ fallback: null,
82
+ };
83
+ lastError = null;
84
+ const fbResult = await fallback.chat(opts, fallbackCfg, log);
85
+ if (fbResult !== null)
86
+ return fbResult;
87
+ const fallbackErr = getLastInferenceError();
88
+ log("ERROR", `LLM both providers failed — primary[${cfg.provider}]: ${primaryErr ? `${primaryErr.kind}: ${primaryErr.message}` : "unknown"} | ` +
89
+ `fallback[${cfg.fallback}]: ${fallbackErr ? `${fallbackErr.kind}: ${fallbackErr.message}` : "unknown"}`);
90
+ // Preserve the most actionable error (prefer auth/bad_request over transient).
91
+ lastError = pickMoreActionable(primaryErr, fallbackErr);
92
+ return null;
93
+ }
94
+ /** Test-only reset. */
95
+ export function _resetInference() {
96
+ resolved = null;
97
+ log = () => { };
98
+ lastError = null;
99
+ }
100
+ function pickMoreActionable(a, b) {
101
+ if (!a)
102
+ return b;
103
+ if (!b)
104
+ return a;
105
+ const order = (k) => {
106
+ switch (k) {
107
+ case "auth": return 0;
108
+ case "bad_request": return 1;
109
+ case "rate_limit": return 2;
110
+ case "timeout": return 3;
111
+ case "transient": return 4;
112
+ default: return 5;
113
+ }
114
+ };
115
+ return order(a.kind) <= order(b.kind) ? a : b;
116
+ }
117
+ export { registerInferenceProvider, getInferenceProvider, listInferenceProviders, };
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/inference/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for the public inference API — initLLM resolution + chatCompletion
3
+ * dispatch + fallback orchestration.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/llm/inference/index.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Tests for the public inference API — initLLM resolution + chatCompletion
3
+ * dispatch + fallback orchestration.
4
+ */
5
+ import { describe, it, beforeEach, afterEach } from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { initLLM, chatCompletion, getInferenceConfig, registerInferenceProvider, _resetInference, } from "./index.js";
8
+ import { listInferenceProviders, _resetInferenceRegistry, } from "./registry.js";
9
+ describe("initLLM — resolution", () => {
10
+ beforeEach(() => _resetInference());
11
+ it("applies ollama defaults", () => {
12
+ const cfg = initLLM({ config: { provider: "ollama" } });
13
+ assert.strictEqual(cfg.provider, "ollama");
14
+ assert.strictEqual(cfg.model, "qwen2.5:7b");
15
+ assert.strictEqual(cfg.baseUrl, "http://localhost:11434");
16
+ assert.strictEqual(cfg.fallback, null);
17
+ assert.deepStrictEqual(cfg.extra, {});
18
+ });
19
+ it("applies openai defaults", () => {
20
+ const cfg = initLLM({ config: { provider: "openai", apiKey: "k" } });
21
+ assert.strictEqual(cfg.model, "gpt-4.1-mini");
22
+ assert.strictEqual(cfg.baseUrl, "https://api.openai.com");
23
+ assert.strictEqual(cfg.apiKey, "k");
24
+ });
25
+ it("applies portkey defaults + extra", () => {
26
+ const cfg = initLLM({
27
+ config: {
28
+ provider: "portkey",
29
+ apiKey: "pk",
30
+ extra: { virtual_key: "vk-1" },
31
+ },
32
+ });
33
+ assert.strictEqual(cfg.model, "@openai/gpt-4o-mini");
34
+ assert.strictEqual(cfg.baseUrl, "https://api.portkey.ai");
35
+ assert.strictEqual(cfg.extra.virtual_key, "vk-1");
36
+ });
37
+ it("throws on unknown provider", () => {
38
+ assert.throws(() => initLLM({ config: { provider: "nope" } }), {
39
+ message: /Unknown inference provider/,
40
+ });
41
+ });
42
+ it("strips trailing slashes from baseUrl", () => {
43
+ const cfg = initLLM({ config: { provider: "ollama", baseUrl: "http://x///" } });
44
+ assert.strictEqual(cfg.baseUrl, "http://x");
45
+ });
46
+ });
47
+ describe("getInferenceConfig", () => {
48
+ it("throws when not initialised", () => {
49
+ _resetInference();
50
+ assert.throws(() => getInferenceConfig(), { message: /not initialized/ });
51
+ });
52
+ it("returns the resolved config after init", () => {
53
+ initLLM({ config: { provider: "ollama" } });
54
+ assert.strictEqual(getInferenceConfig().provider, "ollama");
55
+ });
56
+ });
57
+ describe("chatCompletion — dispatch + fallback", () => {
58
+ let snapshot;
59
+ let calls;
60
+ beforeEach(() => {
61
+ snapshot = listInferenceProviders();
62
+ _resetInferenceRegistry();
63
+ _resetInference();
64
+ calls = [];
65
+ });
66
+ afterEach(() => {
67
+ _resetInferenceRegistry();
68
+ _resetInference();
69
+ for (const p of snapshot)
70
+ registerInferenceProvider(p);
71
+ });
72
+ function fakeProvider(name, result) {
73
+ return {
74
+ name,
75
+ label: name,
76
+ browserCompatible: false,
77
+ defaults: { model: `${name}-model` },
78
+ async chat() { calls.push(name); return result; },
79
+ };
80
+ }
81
+ it("returns the primary's result when it succeeds", async () => {
82
+ registerInferenceProvider(fakeProvider("primary", "primary-said-hi"));
83
+ initLLM({ config: { provider: "primary" } });
84
+ const out = await chatCompletion({ messages: [{ role: "user", content: "hi" }] });
85
+ assert.strictEqual(out, "primary-said-hi");
86
+ assert.deepStrictEqual(calls, ["primary"]);
87
+ });
88
+ it("falls back to the configured fallback when primary returns null", async () => {
89
+ registerInferenceProvider(fakeProvider("primary", null));
90
+ registerInferenceProvider(fakeProvider("backup", "backup-said-hi"));
91
+ initLLM({ config: { provider: "primary", fallback: "backup" } });
92
+ const out = await chatCompletion({ messages: [{ role: "user", content: "hi" }] });
93
+ assert.strictEqual(out, "backup-said-hi");
94
+ assert.deepStrictEqual(calls, ["primary", "backup"]);
95
+ });
96
+ it("returns null when no fallback and primary fails", async () => {
97
+ registerInferenceProvider(fakeProvider("primary", null));
98
+ initLLM({ config: { provider: "primary" } });
99
+ const out = await chatCompletion({ messages: [{ role: "user", content: "hi" }] });
100
+ assert.strictEqual(out, null);
101
+ assert.deepStrictEqual(calls, ["primary"]);
102
+ });
103
+ it("throws if fallback name is not registered", async () => {
104
+ registerInferenceProvider(fakeProvider("primary", null));
105
+ initLLM({ config: { provider: "primary", fallback: "ghost" } });
106
+ await assert.rejects(() => chatCompletion({ messages: [{ role: "user", content: "hi" }] }), { message: /Unknown inference provider: "ghost"/ });
107
+ });
108
+ });
109
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/llm/inference/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * AWS Bedrock chat-completion provider — Converse API.
3
+ *
4
+ * The AWS SDK is dynamic-imported on first call so that users on Ollama or
5
+ * OpenAI never pay the bundle cost.
6
+ *
7
+ * Region resolution order: cfg.extra.region → AWS_BEDROCK_REGION → AWS_REGION → "us-east-1".
8
+ * Credentials follow the SDK default chain (env → shared file → SSO → IAM role).
9
+ *
10
+ * Errors: SDK exceptions are translated to typed `LlmHttpError` subclasses
11
+ * (using `$metadata.httpStatusCode`) and recorded via `_recordInferenceError`,
12
+ * matching the contract used by the HTTP-based providers.
13
+ */
14
+ import type { InferenceProvider } from "../types.js";
15
+ /** Test-only: drop the cached SDK so tests can swap or reset it. */
16
+ export declare function _resetBedrockInferenceClient(): void;
17
+ export declare const bedrockInferenceProvider: InferenceProvider;
18
+ //# sourceMappingURL=bedrock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/bedrock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAKlB,MAAM,aAAa,CAAC;AAiErB,oEAAoE;AACpE,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD;AAED,eAAO,MAAM,wBAAwB,EAAE,iBA8CtC,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * AWS Bedrock chat-completion provider — Converse API.
3
+ *
4
+ * The AWS SDK is dynamic-imported on first call so that users on Ollama or
5
+ * OpenAI never pay the bundle cost.
6
+ *
7
+ * Region resolution order: cfg.extra.region → AWS_BEDROCK_REGION → AWS_REGION → "us-east-1".
8
+ * Credentials follow the SDK default chain (env → shared file → SSO → IAM role).
9
+ *
10
+ * Errors: SDK exceptions are translated to typed `LlmHttpError` subclasses
11
+ * (using `$metadata.httpStatusCode`) and recorded via `_recordInferenceError`,
12
+ * matching the contract used by the HTTP-based providers.
13
+ */
14
+ import { registerInferenceProvider } from "../registry.js";
15
+ import { classifyHttpStatus, LlmAuthError, LlmBadRequestError, LlmRateLimitError, LlmTransientError, LlmUnknownError, } from "../../errors.js";
16
+ import { _recordInferenceError } from "../index.js";
17
+ let sdk = null;
18
+ async function ensureSdk(cfg) {
19
+ if (sdk)
20
+ return sdk;
21
+ const mod = await import("@aws-sdk/client-bedrock-runtime");
22
+ const region = cfg.extra.region
23
+ ?? process.env.AWS_BEDROCK_REGION
24
+ ?? process.env.AWS_REGION
25
+ ?? "us-east-1";
26
+ const next = {
27
+ client: new mod.BedrockRuntimeClient({ region }),
28
+ ConverseCommand: mod.ConverseCommand,
29
+ };
30
+ sdk = next;
31
+ return next;
32
+ }
33
+ function translateSdkError(err, model) {
34
+ const e = err;
35
+ const status = e.$metadata?.httpStatusCode;
36
+ const details = {
37
+ provider: "bedrock",
38
+ model,
39
+ status,
40
+ body: e.message ?? e.name,
41
+ cause: err,
42
+ };
43
+ if (status === undefined) {
44
+ return new LlmTransientError(details);
45
+ }
46
+ switch (classifyHttpStatus(status)) {
47
+ case "auth": return new LlmAuthError(details);
48
+ case "rate_limit": return new LlmRateLimitError(details);
49
+ case "bad_request": return new LlmBadRequestError(details);
50
+ case "transient": return new LlmTransientError(details);
51
+ default: return new LlmUnknownError(details);
52
+ }
53
+ }
54
+ /** Test-only: drop the cached SDK so tests can swap or reset it. */
55
+ export function _resetBedrockInferenceClient() {
56
+ sdk = null;
57
+ }
58
+ export const bedrockInferenceProvider = {
59
+ name: "bedrock",
60
+ label: "AWS Bedrock (Converse)",
61
+ browserCompatible: false,
62
+ defaults: {
63
+ model: "us.anthropic.claude-sonnet-4-20250514",
64
+ },
65
+ async chat(opts, cfg, log) {
66
+ const { client, ConverseCommand } = await ensureSdk(cfg);
67
+ const systemBlocks = [];
68
+ const messages = [];
69
+ for (const m of opts.messages) {
70
+ if (m.role === "system") {
71
+ systemBlocks.push({ text: m.content });
72
+ }
73
+ else {
74
+ messages.push({
75
+ role: m.role,
76
+ content: [{ text: m.content }],
77
+ });
78
+ }
79
+ }
80
+ try {
81
+ const command = new ConverseCommand({
82
+ modelId: cfg.model,
83
+ messages,
84
+ ...(systemBlocks.length > 0 ? { system: systemBlocks } : {}),
85
+ inferenceConfig: {
86
+ maxTokens: opts.max_tokens ?? 500,
87
+ temperature: opts.temperature ?? 0.2,
88
+ },
89
+ });
90
+ const resp = await client.send(command);
91
+ _recordInferenceError(null);
92
+ const content = resp.output?.message?.content;
93
+ const textBlock = content?.find((c) => "text" in c);
94
+ return (textBlock?.text ?? "").trim() || null;
95
+ }
96
+ catch (e) {
97
+ const err = translateSdkError(e, cfg.model);
98
+ _recordInferenceError(err);
99
+ log("WARN", `LLM Bedrock ${err.kind}${err.status !== undefined ? ` (${err.status})` : ""}: ${err.message}`);
100
+ return null;
101
+ }
102
+ },
103
+ };
104
+ registerInferenceProvider(bedrockInferenceProvider);
105
+ //# sourceMappingURL=bedrock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/bedrock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bedrock.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrock.test.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/bedrock.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { bedrockInferenceProvider, _resetBedrockInferenceClient } from "./bedrock.js";
4
+ describe("bedrock inference provider — metadata", () => {
5
+ it("declares the correct name + label", () => {
6
+ assert.strictEqual(bedrockInferenceProvider.name, "bedrock");
7
+ assert.strictEqual(bedrockInferenceProvider.label, "AWS Bedrock (Converse)");
8
+ });
9
+ it("is NOT browserCompatible", () => {
10
+ assert.strictEqual(bedrockInferenceProvider.browserCompatible, false);
11
+ });
12
+ it("defaults to Claude Sonnet 4 with no baseUrl", () => {
13
+ assert.strictEqual(bedrockInferenceProvider.defaults.model, "us.anthropic.claude-sonnet-4-20250514");
14
+ assert.strictEqual(bedrockInferenceProvider.defaults.baseUrl, undefined);
15
+ });
16
+ it("loads the AWS SDK lazily inside chat() (not at module load)", () => {
17
+ assert.strictEqual(typeof bedrockInferenceProvider.chat, "function");
18
+ assert.strictEqual(typeof _resetBedrockInferenceClient, "function");
19
+ });
20
+ });
21
+ //# sourceMappingURL=bedrock.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrock.test.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/bedrock.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEtF,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,QAAQ,CAAC,KAAK,EAAE,uCAAuC,CAAC,CAAC;QACrG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrE,MAAM,CAAC,WAAW,CAAC,OAAO,4BAA4B,EAAE,UAAU,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Inference providers barrel — importing this file registers all built-in
3
+ * providers via side effect. To add a new provider, drop a file alongside and
4
+ * add a single import line below.
5
+ */
6
+ import "./ollama.js";
7
+ import "./openai.js";
8
+ import "./bedrock.js";
9
+ import "./portkey.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,aAAa,CAAC;AACrB,OAAO,aAAa,CAAC;AACrB,OAAO,cAAc,CAAC;AACtB,OAAO,cAAc,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Inference providers barrel — importing this file registers all built-in
3
+ * providers via side effect. To add a new provider, drop a file alongside and
4
+ * add a single import line below.
5
+ */
6
+ import "./ollama.js";
7
+ import "./openai.js";
8
+ import "./bedrock.js";
9
+ import "./portkey.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,aAAa,CAAC;AACrB,OAAO,aAAa,CAAC;AACrB,OAAO,cAAc,CAAC;AACtB,OAAO,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Ollama chat-completion provider — POSTs to /v1/chat/completions (no auth).
3
+ * JSON-schema response_format is downgraded to json_object since Ollama's
4
+ * OpenAI-compatible endpoint does not implement schema enforcement.
5
+ */
6
+ import type { InferenceProvider } from "../types.js";
7
+ export declare const ollamaInferenceProvider: InferenceProvider;
8
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/ollama.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AAQrB,eAAO,MAAM,uBAAuB,EAAE,iBAiDrC,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Ollama chat-completion provider — POSTs to /v1/chat/completions (no auth).
3
+ * JSON-schema response_format is downgraded to json_object since Ollama's
4
+ * OpenAI-compatible endpoint does not implement schema enforcement.
5
+ */
6
+ import { registerInferenceProvider } from "../registry.js";
7
+ import { resilientFetch } from "../../fetch.js";
8
+ import { LlmHttpError } from "../../errors.js";
9
+ import { _recordInferenceError } from "../index.js";
10
+ const RETRY_CAP_MS = 5_000;
11
+ export const ollamaInferenceProvider = {
12
+ name: "ollama",
13
+ label: "Ollama (local)",
14
+ browserCompatible: false,
15
+ defaults: {
16
+ model: "qwen2.5:7b",
17
+ baseUrl: "http://localhost:11434",
18
+ },
19
+ async chat(opts, cfg, log) {
20
+ const body = {
21
+ model: cfg.model,
22
+ messages: opts.messages,
23
+ temperature: opts.temperature ?? 0.2,
24
+ max_tokens: opts.max_tokens ?? 500,
25
+ };
26
+ if (opts.response_format) {
27
+ body.response_format = opts.response_format.type === "json_schema"
28
+ ? { type: "json_object" }
29
+ : opts.response_format;
30
+ }
31
+ try {
32
+ const resp = await resilientFetch({
33
+ url: `${cfg.baseUrl}/v1/chat/completions`,
34
+ init: {
35
+ method: "POST",
36
+ headers: { "Content-Type": "application/json" },
37
+ body: JSON.stringify(body),
38
+ },
39
+ timeoutMs: cfg.timeoutMs,
40
+ retries: cfg.retries,
41
+ baseDelayMs: cfg.retryBaseDelayMs,
42
+ capDelayMs: RETRY_CAP_MS,
43
+ provider: "ollama",
44
+ model: cfg.model,
45
+ });
46
+ const data = (await resp.json());
47
+ _recordInferenceError(null);
48
+ return data.choices?.[0]?.message?.content?.trim() ?? null;
49
+ }
50
+ catch (e) {
51
+ if (e instanceof LlmHttpError) {
52
+ _recordInferenceError(e);
53
+ log("WARN", `LLM Ollama ${e.kind}${e.status !== undefined ? ` (${e.status})` : ""}: ${e.message}`);
54
+ }
55
+ else {
56
+ log("WARN", `LLM Ollama unreachable: ${e.message}`);
57
+ }
58
+ return null;
59
+ }
60
+ },
61
+ };
62
+ registerInferenceProvider(ollamaInferenceProvider);
63
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/ollama.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,gBAAgB;IACvB,iBAAiB,EAAE,KAAK;IACxB,QAAQ,EAAE;QACR,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,wBAAwB;KAClC;IACD,KAAK,CAAC,IAAI,CAAC,IAAwB,EAAE,GAA4B,EAAE,GAAU;QAC3E,MAAM,IAAI,GAA4B;YACpC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,GAAG;YACpC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,GAAG;SACnC,CAAC;QACF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,KAAK,aAAa;gBAChE,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE;gBACzB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC;gBAChC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,sBAAsB;gBACzC,IAAI,EAAE;oBACJ,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBAC3B;gBACD,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,WAAW,EAAE,GAAG,CAAC,gBAAgB;gBACjC,UAAU,EAAE,YAAY;gBACxB,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,GAAG,CAAC,KAAK;aACjB,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA4D,CAAC;YAC5F,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;QAC7D,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;gBAC9B,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBACzB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACrG,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,EAAE,2BAA4B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAC;AAEF,yBAAyB,CAAC,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ollama.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.test.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/ollama.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, it, beforeEach, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { ollamaInferenceProvider } from "./ollama.js";
4
+ const cfg = {
5
+ provider: "ollama",
6
+ model: "qwen2.5:7b",
7
+ baseUrl: "http://localhost:11434",
8
+ apiKey: null,
9
+ fallback: null,
10
+ extra: {},
11
+ timeoutMs: 5_000,
12
+ retries: 0,
13
+ retryBaseDelayMs: 10,
14
+ };
15
+ const log = () => { };
16
+ describe("ollama inference provider", () => {
17
+ const realFetch = globalThis.fetch;
18
+ beforeEach(() => { globalThis.fetch = realFetch; });
19
+ afterEach(() => { globalThis.fetch = realFetch; });
20
+ it("POSTs to /v1/chat/completions and returns trimmed content", async () => {
21
+ let captured = null;
22
+ globalThis.fetch = (async (url, init) => {
23
+ captured = { url, init };
24
+ return new Response(JSON.stringify({ choices: [{ message: { content: " hi " } }] }), { status: 200 });
25
+ });
26
+ const out = await ollamaInferenceProvider.chat({ messages: [{ role: "user", content: "ping" }] }, cfg, log);
27
+ assert.strictEqual(out, "hi");
28
+ const cap = captured;
29
+ assert.strictEqual(cap.url, "http://localhost:11434/v1/chat/completions");
30
+ const body = JSON.parse(cap.init.body);
31
+ assert.strictEqual(body.model, "qwen2.5:7b");
32
+ });
33
+ it("downgrades json_schema response_format to json_object", async () => {
34
+ let captured = null;
35
+ globalThis.fetch = (async (_url, init) => {
36
+ captured = init;
37
+ return new Response(JSON.stringify({ choices: [{ message: { content: "{}" } }] }), { status: 200 });
38
+ });
39
+ await ollamaInferenceProvider.chat({
40
+ messages: [{ role: "user", content: "x" }],
41
+ response_format: { type: "json_schema", json_schema: { name: "t", schema: { type: "object" } } },
42
+ }, cfg, log);
43
+ const body = JSON.parse(captured.body);
44
+ assert.deepStrictEqual(body.response_format, { type: "json_object" });
45
+ });
46
+ it("returns null on non-OK response (recoverable)", async () => {
47
+ globalThis.fetch = (async () => new Response("err", { status: 500 }));
48
+ const out = await ollamaInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, cfg, log);
49
+ assert.strictEqual(out, null);
50
+ });
51
+ it("returns null on network error (recoverable)", async () => {
52
+ globalThis.fetch = (async () => { throw new Error("ECONNREFUSED"); });
53
+ const out = await ollamaInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, cfg, log);
54
+ assert.strictEqual(out, null);
55
+ });
56
+ });
57
+ //# sourceMappingURL=ollama.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.test.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/ollama.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * OpenAI chat-completion provider — POSTs to /v1/chat/completions with bearer
3
+ * auth. Forwards `response_format` (json_object or json_schema) as-is.
4
+ *
5
+ * On failure: catches typed errors from the resilient fetch helper, records
6
+ * them via `_recordInferenceError` for surfacing by the orchestrator, and
7
+ * returns `null` to keep the fallback contract.
8
+ */
9
+ import type { InferenceProvider } from "../types.js";
10
+ export declare const openaiInferenceProvider: InferenceProvider;
11
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AAYrB,eAAO,MAAM,uBAAuB,EAAE,iBAwDrC,CAAC"}