bikky 0.3.1 → 0.3.2

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 (329) hide show
  1. package/README.md +79 -26
  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 +77 -0
  24. package/dist/daemon/episode-summary.d.ts.map +1 -0
  25. package/dist/daemon/episode-summary.js +239 -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 +68 -0
  73. package/dist/daemon/workstream-summary.d.ts.map +1 -0
  74. package/dist/daemon/workstream-summary.js +253 -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 +38 -20
  255. package/dist/mcp/index.js.map +1 -1
  256. package/dist/mcp/taxonomy.d.ts +237 -31
  257. package/dist/mcp/taxonomy.d.ts.map +1 -1
  258. package/dist/mcp/taxonomy.js +533 -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 +338 -302
  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 +74 -0
  288. package/dist/prompts/distill.js.map +1 -0
  289. package/dist/prompts/extraction.d.ts +14 -0
  290. package/dist/prompts/extraction.d.ts.map +1 -0
  291. package/dist/prompts/extraction.js +87 -0
  292. package/dist/prompts/extraction.js.map +1 -0
  293. package/dist/prompts/index.d.ts +50 -0
  294. package/dist/prompts/index.d.ts.map +1 -0
  295. package/dist/prompts/index.js +102 -0
  296. package/dist/prompts/index.js.map +1 -0
  297. package/dist/prompts/prompts.test.d.ts +8 -0
  298. package/dist/prompts/prompts.test.d.ts.map +1 -0
  299. package/dist/prompts/prompts.test.js +140 -0
  300. package/dist/prompts/prompts.test.js.map +1 -0
  301. package/dist/prompts/relations.d.ts +17 -0
  302. package/dist/prompts/relations.d.ts.map +1 -0
  303. package/dist/prompts/relations.js +72 -0
  304. package/dist/prompts/relations.js.map +1 -0
  305. package/dist/render.d.ts +41 -0
  306. package/dist/render.d.ts.map +1 -0
  307. package/dist/render.js +173 -0
  308. package/dist/render.js.map +1 -0
  309. package/dist/render.test.d.ts +8 -0
  310. package/dist/render.test.d.ts.map +1 -0
  311. package/dist/render.test.js +212 -0
  312. package/dist/render.test.js.map +1 -0
  313. package/package.json +9 -2
  314. package/dist/llm/embedding.d.ts +0 -13
  315. package/dist/llm/embedding.d.ts.map +0 -1
  316. package/dist/llm/embedding.js +0 -127
  317. package/dist/llm/embedding.js.map +0 -1
  318. package/dist/llm/embedding.test.d.ts +0 -8
  319. package/dist/llm/embedding.test.d.ts.map +0 -1
  320. package/dist/llm/embedding.test.js +0 -117
  321. package/dist/llm/embedding.test.js.map +0 -1
  322. package/dist/llm/inference.d.ts +0 -12
  323. package/dist/llm/inference.d.ts.map +0 -1
  324. package/dist/llm/inference.js +0 -146
  325. package/dist/llm/inference.js.map +0 -1
  326. package/dist/llm/inference.test.d.ts +0 -8
  327. package/dist/llm/inference.test.d.ts.map +0 -1
  328. package/dist/llm/inference.test.js +0 -117
  329. package/dist/llm/inference.test.js.map +0 -1
@@ -0,0 +1,73 @@
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 { registerInferenceProvider } from "../registry.js";
10
+ import { resilientFetch } from "../../fetch.js";
11
+ import { LlmAuthError, LlmHttpError, } from "../../errors.js";
12
+ import { _recordInferenceError } from "../index.js";
13
+ const RETRY_CAP_MS = 5_000;
14
+ export const openaiInferenceProvider = {
15
+ name: "openai",
16
+ label: "OpenAI",
17
+ browserCompatible: false,
18
+ defaults: {
19
+ model: "gpt-4.1-mini",
20
+ baseUrl: "https://api.openai.com",
21
+ },
22
+ async chat(opts, cfg, log) {
23
+ if (!cfg.apiKey) {
24
+ const details = { provider: "openai", model: cfg.model, body: "no API key" };
25
+ const err = new LlmAuthError(details);
26
+ _recordInferenceError(err);
27
+ log("WARN", `LLM OpenAI: no API key`);
28
+ return null;
29
+ }
30
+ const body = {
31
+ model: cfg.model,
32
+ messages: opts.messages,
33
+ temperature: opts.temperature ?? 0.2,
34
+ max_tokens: opts.max_tokens ?? 500,
35
+ };
36
+ if (opts.response_format)
37
+ body.response_format = opts.response_format;
38
+ try {
39
+ const resp = await resilientFetch({
40
+ url: `${cfg.baseUrl}/v1/chat/completions`,
41
+ init: {
42
+ method: "POST",
43
+ headers: {
44
+ "Content-Type": "application/json",
45
+ Authorization: `Bearer ${cfg.apiKey}`,
46
+ },
47
+ body: JSON.stringify(body),
48
+ },
49
+ timeoutMs: cfg.timeoutMs,
50
+ retries: cfg.retries,
51
+ baseDelayMs: cfg.retryBaseDelayMs,
52
+ capDelayMs: RETRY_CAP_MS,
53
+ provider: "openai",
54
+ model: cfg.model,
55
+ });
56
+ const data = (await resp.json());
57
+ _recordInferenceError(null);
58
+ return data.choices?.[0]?.message?.content?.trim() ?? null;
59
+ }
60
+ catch (e) {
61
+ if (e instanceof LlmHttpError) {
62
+ _recordInferenceError(e);
63
+ log("WARN", `LLM OpenAI ${e.kind}${e.status !== undefined ? ` (${e.status})` : ""}: ${e.message}`);
64
+ }
65
+ else {
66
+ log("WARN", `LLM OpenAI error: ${e.message}`);
67
+ }
68
+ return null;
69
+ }
70
+ },
71
+ };
72
+ registerInferenceProvider(openaiInferenceProvider);
73
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openai.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.test.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/openai.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, it, beforeEach, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { openaiInferenceProvider } from "./openai.js";
4
+ const cfg = {
5
+ provider: "openai",
6
+ model: "gpt-4.1-mini",
7
+ baseUrl: "https://api.openai.com",
8
+ apiKey: "sk-test",
9
+ fallback: null,
10
+ extra: {},
11
+ timeoutMs: 5_000,
12
+ retries: 0,
13
+ retryBaseDelayMs: 10,
14
+ };
15
+ const log = () => { };
16
+ describe("openai inference provider", () => {
17
+ const realFetch = globalThis.fetch;
18
+ beforeEach(() => { globalThis.fetch = realFetch; });
19
+ afterEach(() => { globalThis.fetch = realFetch; });
20
+ it("sends bearer auth header and forwards json_schema response_format unchanged", async () => {
21
+ let captured = null;
22
+ globalThis.fetch = (async (_url, init) => {
23
+ captured = init;
24
+ return new Response(JSON.stringify({ choices: [{ message: { content: "ok" } }] }), { status: 200 });
25
+ });
26
+ await openaiInferenceProvider.chat({
27
+ messages: [{ role: "user", content: "x" }],
28
+ response_format: { type: "json_schema", json_schema: { name: "t", schema: { type: "object" } } },
29
+ }, cfg, log);
30
+ const init = captured;
31
+ const headers = init.headers;
32
+ assert.strictEqual(headers["Authorization"], "Bearer sk-test");
33
+ const body = JSON.parse(init.body);
34
+ assert.strictEqual(body.response_format.type, "json_schema");
35
+ });
36
+ it("returns null when no API key is configured", async () => {
37
+ const out = await openaiInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, { ...cfg, apiKey: null }, log);
38
+ assert.strictEqual(out, null);
39
+ });
40
+ it("returns null on HTTP error (recoverable)", async () => {
41
+ globalThis.fetch = (async () => new Response("nope", { status: 401 }));
42
+ const out = await openaiInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, cfg, log);
43
+ assert.strictEqual(out, null);
44
+ });
45
+ });
46
+ //# sourceMappingURL=openai.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.test.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/openai.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Portkey gateway chat-completion provider.
3
+ *
4
+ * Portkey speaks the OpenAI chat-completions wire format with extra headers.
5
+ * Auth: `x-portkey-api-key`. Optional routing: `x-portkey-virtual-key` and/or
6
+ * `x-portkey-config` from cfg.extra.virtual_key / cfg.extra.config_id.
7
+ *
8
+ * Default model is namespaced (e.g. "@openai/gpt-4o-mini"); pass-through any
9
+ * provider/model the user prefers.
10
+ */
11
+ import type { InferenceProvider } from "../types.js";
12
+ export declare const portkeyInferenceProvider: InferenceProvider;
13
+ //# sourceMappingURL=portkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portkey.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/portkey.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AAYrB,eAAO,MAAM,wBAAwB,EAAE,iBA4DtC,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Portkey gateway chat-completion provider.
3
+ *
4
+ * Portkey speaks the OpenAI chat-completions wire format with extra headers.
5
+ * Auth: `x-portkey-api-key`. Optional routing: `x-portkey-virtual-key` and/or
6
+ * `x-portkey-config` from cfg.extra.virtual_key / cfg.extra.config_id.
7
+ *
8
+ * Default model is namespaced (e.g. "@openai/gpt-4o-mini"); pass-through any
9
+ * provider/model the user prefers.
10
+ */
11
+ import { registerInferenceProvider } from "../registry.js";
12
+ import { resilientFetch } from "../../fetch.js";
13
+ import { LlmAuthError, LlmHttpError, } from "../../errors.js";
14
+ import { _recordInferenceError } from "../index.js";
15
+ const RETRY_CAP_MS = 5_000;
16
+ export const portkeyInferenceProvider = {
17
+ name: "portkey",
18
+ label: "Portkey (gateway)",
19
+ browserCompatible: false,
20
+ defaults: {
21
+ model: "@openai/gpt-4o-mini",
22
+ baseUrl: "https://api.portkey.ai",
23
+ },
24
+ async chat(opts, cfg, log) {
25
+ if (!cfg.apiKey) {
26
+ const details = { provider: "portkey", model: cfg.model, body: "no API key" };
27
+ const err = new LlmAuthError(details);
28
+ _recordInferenceError(err);
29
+ log("WARN", `LLM Portkey: no API key`);
30
+ return null;
31
+ }
32
+ const headers = {
33
+ "Content-Type": "application/json",
34
+ "x-portkey-api-key": cfg.apiKey,
35
+ };
36
+ if (cfg.extra.virtual_key)
37
+ headers["x-portkey-virtual-key"] = cfg.extra.virtual_key;
38
+ if (cfg.extra.config_id)
39
+ headers["x-portkey-config"] = cfg.extra.config_id;
40
+ const body = {
41
+ model: cfg.model,
42
+ messages: opts.messages,
43
+ temperature: opts.temperature ?? 0.2,
44
+ max_tokens: opts.max_tokens ?? 500,
45
+ };
46
+ if (opts.response_format)
47
+ body.response_format = opts.response_format;
48
+ try {
49
+ const resp = await resilientFetch({
50
+ url: `${cfg.baseUrl}/v1/chat/completions`,
51
+ init: {
52
+ method: "POST",
53
+ headers,
54
+ body: JSON.stringify(body),
55
+ },
56
+ timeoutMs: cfg.timeoutMs,
57
+ retries: cfg.retries,
58
+ baseDelayMs: cfg.retryBaseDelayMs,
59
+ capDelayMs: RETRY_CAP_MS,
60
+ provider: "portkey",
61
+ model: cfg.model,
62
+ });
63
+ const data = (await resp.json());
64
+ _recordInferenceError(null);
65
+ return data.choices?.[0]?.message?.content?.trim() ?? null;
66
+ }
67
+ catch (e) {
68
+ if (e instanceof LlmHttpError) {
69
+ _recordInferenceError(e);
70
+ log("WARN", `LLM Portkey ${e.kind}${e.status !== undefined ? ` (${e.status})` : ""}: ${e.message}`);
71
+ }
72
+ else {
73
+ log("WARN", `LLM Portkey error: ${e.message}`);
74
+ }
75
+ return null;
76
+ }
77
+ },
78
+ };
79
+ registerInferenceProvider(portkeyInferenceProvider);
80
+ //# sourceMappingURL=portkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portkey.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/portkey.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EACL,YAAY,EACZ,YAAY,GAEb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,mBAAmB;IAC1B,iBAAiB,EAAE,KAAK;IACxB,QAAQ,EAAE;QACR,KAAK,EAAE,qBAAqB;QAC5B,OAAO,EAAE,wBAAwB;KAClC;IACD,KAAK,CAAC,IAAI,CAAC,IAAwB,EAAE,GAA4B,EAAE,GAAU;QAC3E,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,OAAO,GAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YAC/F,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;YACtC,qBAAqB,CAAC,GAAG,CAAC,CAAC;YAC3B,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,mBAAmB,EAAE,GAAG,CAAC,MAAM;SAChC,CAAC;QACF,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW;YAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC;QACpF,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QAE3E,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;YAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QAEtE,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;oBACP,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,SAAS;gBACnB,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,eAAe,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;YACtG,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,EAAE,sBAAuB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAC;AAEF,yBAAyB,CAAC,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=portkey.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portkey.test.d.ts","sourceRoot":"","sources":["../../../../src/llm/inference/providers/portkey.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { describe, it, beforeEach, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { portkeyInferenceProvider } from "./portkey.js";
4
+ const cfg = {
5
+ provider: "portkey",
6
+ model: "@openai/gpt-4o-mini",
7
+ baseUrl: "https://api.portkey.ai",
8
+ apiKey: "pk-test",
9
+ fallback: null,
10
+ extra: { virtual_key: "vk-1", config_id: "cfg-2" },
11
+ timeoutMs: 5_000,
12
+ retries: 0,
13
+ retryBaseDelayMs: 10,
14
+ };
15
+ const log = () => { };
16
+ describe("portkey inference provider", () => {
17
+ const realFetch = globalThis.fetch;
18
+ beforeEach(() => { globalThis.fetch = realFetch; });
19
+ afterEach(() => { globalThis.fetch = realFetch; });
20
+ it("sends portkey headers (api-key, virtual-key, config) when provided", async () => {
21
+ let captured = null;
22
+ globalThis.fetch = (async (_url, init) => {
23
+ captured = init;
24
+ return new Response(JSON.stringify({ choices: [{ message: { content: "ok" } }] }), { status: 200 });
25
+ });
26
+ await portkeyInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, cfg, log);
27
+ const headers = captured.headers;
28
+ assert.strictEqual(headers["x-portkey-api-key"], "pk-test");
29
+ assert.strictEqual(headers["x-portkey-virtual-key"], "vk-1");
30
+ assert.strictEqual(headers["x-portkey-config"], "cfg-2");
31
+ });
32
+ it("omits optional headers when extras are absent", async () => {
33
+ let captured = null;
34
+ globalThis.fetch = (async (_url, init) => {
35
+ captured = init;
36
+ return new Response(JSON.stringify({ choices: [{ message: { content: "ok" } }] }), { status: 200 });
37
+ });
38
+ await portkeyInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, { ...cfg, extra: {} }, log);
39
+ const headers = captured.headers;
40
+ assert.ok(!("x-portkey-virtual-key" in headers));
41
+ assert.ok(!("x-portkey-config" in headers));
42
+ });
43
+ it("returns null when no API key is configured", async () => {
44
+ const out = await portkeyInferenceProvider.chat({ messages: [{ role: "user", content: "x" }] }, { ...cfg, apiKey: null }, log);
45
+ assert.strictEqual(out, null);
46
+ });
47
+ });
48
+ //# sourceMappingURL=portkey.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portkey.test.js","sourceRoot":"","sources":["../../../../src/llm/inference/providers/portkey.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * In-process registry of inference providers.
3
+ *
4
+ * Providers self-register at module load by importing this file's
5
+ * `registerInferenceProvider`. The barrel `./providers/index.ts` is imported by
6
+ * `./index.ts` so that any consumer of the public API automatically pulls in
7
+ * the bundled providers.
8
+ */
9
+ import type { InferenceProvider } from "./types.js";
10
+ export declare function registerInferenceProvider(p: InferenceProvider): void;
11
+ export declare function getInferenceProvider(name: string): InferenceProvider;
12
+ export declare function listInferenceProviders(): InferenceProvider[];
13
+ /** Test-only: clear the registry. */
14
+ export declare function _resetInferenceRegistry(): void;
15
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/llm/inference/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAEpE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAOpE;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,EAAE,CAE5D;AAED,qCAAqC;AACrC,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * In-process registry of inference providers.
3
+ *
4
+ * Providers self-register at module load by importing this file's
5
+ * `registerInferenceProvider`. The barrel `./providers/index.ts` is imported by
6
+ * `./index.ts` so that any consumer of the public API automatically pulls in
7
+ * the bundled providers.
8
+ */
9
+ const providers = new Map();
10
+ export function registerInferenceProvider(p) {
11
+ providers.set(p.name, p);
12
+ }
13
+ export function getInferenceProvider(name) {
14
+ const p = providers.get(name);
15
+ if (!p) {
16
+ const known = Array.from(providers.keys()).sort().join(", ") || "(none)";
17
+ throw new Error(`Unknown inference provider: "${name}". Registered: ${known}`);
18
+ }
19
+ return p;
20
+ }
21
+ export function listInferenceProviders() {
22
+ return Array.from(providers.values());
23
+ }
24
+ /** Test-only: clear the registry. */
25
+ export function _resetInferenceRegistry() {
26
+ providers.clear();
27
+ }
28
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/llm/inference/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAC;AAEvD,MAAM,UAAU,yBAAyB,CAAC,CAAoB;IAC5D,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,kBAAkB,KAAK,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,uBAAuB;IACrC,SAAS,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for the inference registry — dispatch + listing.
3
+ * Provider-specific behaviour is tested in providers/*.test.ts.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.d.ts","sourceRoot":"","sources":["../../../src/llm/inference/registry.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Tests for the inference registry — dispatch + listing.
3
+ * Provider-specific behaviour is tested in providers/*.test.ts.
4
+ */
5
+ import { describe, it, beforeEach, afterEach } from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { registerInferenceProvider, getInferenceProvider, listInferenceProviders, _resetInferenceRegistry, } from "./registry.js";
8
+ const fakeProvider = {
9
+ name: "fake-inf",
10
+ label: "Fake (test)",
11
+ browserCompatible: false,
12
+ defaults: { model: "fake-model" },
13
+ async chat() { return "ok"; },
14
+ };
15
+ describe("inference registry", () => {
16
+ let snapshot;
17
+ beforeEach(() => {
18
+ snapshot = listInferenceProviders();
19
+ _resetInferenceRegistry();
20
+ });
21
+ afterEach(() => {
22
+ _resetInferenceRegistry();
23
+ for (const p of snapshot)
24
+ registerInferenceProvider(p);
25
+ });
26
+ it("registers and retrieves a provider by name", () => {
27
+ registerInferenceProvider(fakeProvider);
28
+ const got = getInferenceProvider("fake-inf");
29
+ assert.strictEqual(got.name, "fake-inf");
30
+ assert.strictEqual(got.defaults.model, "fake-model");
31
+ });
32
+ it("throws a helpful error when the provider is unknown", () => {
33
+ registerInferenceProvider(fakeProvider);
34
+ assert.throws(() => getInferenceProvider("nope"), {
35
+ message: /Unknown inference provider: "nope"\. Registered: fake-inf/,
36
+ });
37
+ });
38
+ it("lists all registered providers", () => {
39
+ registerInferenceProvider(fakeProvider);
40
+ registerInferenceProvider({ ...fakeProvider, name: "fake-2" });
41
+ const names = listInferenceProviders().map((p) => p.name).sort();
42
+ assert.deepStrictEqual(names, ["fake-2", "fake-inf"]);
43
+ });
44
+ });
45
+ describe("built-in inference providers (registered via barrel import)", () => {
46
+ it("registers ollama, openai, bedrock, portkey by importing the index", async () => {
47
+ const snap = listInferenceProviders();
48
+ _resetInferenceRegistry();
49
+ try {
50
+ await import("./providers/index.js");
51
+ const names = listInferenceProviders().map((p) => p.name).sort();
52
+ for (const expected of ["bedrock", "ollama", "openai", "portkey"]) {
53
+ assert.ok(names.includes(expected), `expected ${expected} to be registered, got ${names.join(", ")}`);
54
+ }
55
+ }
56
+ finally {
57
+ _resetInferenceRegistry();
58
+ for (const p of snap)
59
+ registerInferenceProvider(p);
60
+ }
61
+ });
62
+ });
63
+ //# sourceMappingURL=registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../src/llm/inference/registry.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAGvB,MAAM,YAAY,GAAsB;IACtC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,aAAa;IACpB,iBAAiB,EAAE,KAAK;IACxB,QAAQ,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE;IACjC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,QAA6B,CAAC;IAElC,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,GAAG,sBAAsB,EAAE,CAAC;QACpC,uBAAuB,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,uBAAuB,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,yBAAyB,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACzC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,yBAAyB,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE;YAChD,OAAO,EAAE,2DAA2D;SACrE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,yBAAyB,CAAC,YAAY,CAAC,CAAC;QACxC,yBAAyB,CAAC,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACjE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IAC3E,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,IAAI,GAAG,sBAAsB,EAAE,CAAC;QACtC,uBAAuB,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,KAAK,MAAM,QAAQ,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;gBAClE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,QAAQ,0BAA0B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxG,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,uBAAuB,EAAE,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Types for the pluggable inference (chat-completion) registry.
3
+ *
4
+ * Each provider declares a name, defaults, and a `chat()` method. The registry
5
+ * dispatches by `cfg.provider` (a string), so adding a new provider is a single
6
+ * file under ./providers/ + one line in ./providers/index.ts.
7
+ */
8
+ export interface ResolvedInferenceConfig {
9
+ /** Provider name as registered (e.g. "ollama"). */
10
+ provider: string;
11
+ /** Model identifier passed to the provider. */
12
+ model: string;
13
+ /** Base URL for HTTP providers; "" for SDK-only providers. */
14
+ baseUrl: string;
15
+ /** Auth token / API key, or null when none required. */
16
+ apiKey: string | null;
17
+ /** Optional fallback provider name — used when `chat()` returns null. */
18
+ fallback: string | null;
19
+ /** Provider-specific extras (e.g. bedrock region, portkey virtual-key). */
20
+ extra: Record<string, string | undefined>;
21
+ /** Per-request timeout in milliseconds (HTTP providers). Defaults set by initLLM. */
22
+ timeoutMs: number;
23
+ /** Max retries on transient/rate-limit/timeout failures. */
24
+ retries: number;
25
+ /** Base backoff delay in milliseconds (full-jitter exponential). */
26
+ retryBaseDelayMs: number;
27
+ }
28
+ export interface ChatMessage {
29
+ role: string;
30
+ content: string;
31
+ }
32
+ export type ResponseFormat = {
33
+ type: "json_object";
34
+ } | {
35
+ type: "json_schema";
36
+ json_schema: JsonSchemaSpec;
37
+ };
38
+ export interface JsonSchemaSpec {
39
+ name: string;
40
+ strict?: boolean;
41
+ schema: Record<string, unknown>;
42
+ }
43
+ export interface ChatCompletionOpts {
44
+ messages: ChatMessage[];
45
+ temperature?: number;
46
+ max_tokens?: number;
47
+ response_format?: ResponseFormat;
48
+ }
49
+ export interface InferenceProvider {
50
+ /** Stable identifier used in config (lowercase). */
51
+ readonly name: string;
52
+ /** Human label for logs. */
53
+ readonly label: string;
54
+ /** Defaults applied when caller omits model/baseUrl. */
55
+ readonly defaults: {
56
+ model: string;
57
+ baseUrl?: string;
58
+ };
59
+ /** Whether this provider can be called from a browser. */
60
+ readonly browserCompatible: boolean;
61
+ /**
62
+ * Run one chat completion. Return the assistant's text on success; return
63
+ * `null` on a recoverable failure (HTTP error, missing key, network) so the
64
+ * orchestrator can fall back. Throw only for programmer errors.
65
+ */
66
+ chat(opts: ChatCompletionOpts, cfg: ResolvedInferenceConfig, log: LogFn): Promise<string | null>;
67
+ }
68
+ export type LogFn = (level: string, ...args: unknown[]) => void;
69
+ export interface InitLLMInput {
70
+ provider: string;
71
+ model?: string;
72
+ baseUrl?: string;
73
+ apiKey?: string | null;
74
+ /** Provider name to fall back to when primary returns null. */
75
+ fallback?: string | null;
76
+ extra?: Record<string, string | undefined>;
77
+ /** Per-request HTTP timeout. Defaults to 30s. */
78
+ timeoutMs?: number;
79
+ /** Max retries on transient/rate-limit/timeout failures. Defaults to 2. */
80
+ retries?: number;
81
+ /** Base backoff delay (ms) for retries. Defaults to 250ms. */
82
+ retryBaseDelayMs?: number;
83
+ }
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/llm/inference/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1C,qFAAqF;IACrF,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,cAAc,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,0DAA0D;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,uBAAuB,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAClG;AAED,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Types for the pluggable inference (chat-completion) registry.
3
+ *
4
+ * Each provider declares a name, defaults, and a `chat()` method. The registry
5
+ * dispatches by `cfg.provider` (a string), so adding a new provider is a single
6
+ * file under ./providers/ + one line in ./providers/index.ts.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/llm/inference/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Lightweight LLM telemetry — appends one JSON line per call to
3
+ * ~/.bikky/logs/llm.jsonl (or BIKKY_LLM_LOG override). Rotates at
4
+ * BIKKY_LLM_LOG_MAX_BYTES (default 10 MB).
5
+ *
6
+ * Telemetry is best-effort: any failure is swallowed and logged to the
7
+ * provided logger.
8
+ */
9
+ import type { LogFn } from "./types.js";
10
+ export interface LLMTelemetryRecord {
11
+ ts: string;
12
+ prompt: string;
13
+ model: string;
14
+ provider: "ollama" | "openai" | "bedrock";
15
+ ok: boolean;
16
+ latency_ms: number;
17
+ tokens_in_est: number;
18
+ tokens_out_est: number;
19
+ error?: string;
20
+ request_id?: string;
21
+ }
22
+ /** Crude token estimator: ~4 chars per token. Good enough for trend lines. */
23
+ export declare const estimateTokens: (text: string) => number;
24
+ export declare function writeTelemetry(record: LLMTelemetryRecord, log: LogFn): Promise<void>;
25
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/llm/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKxC,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1C,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,8EAA8E;AAC9E,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,MAAoC,CAAC;AAGnF,wBAAsB,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB1F"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Lightweight LLM telemetry — appends one JSON line per call to
3
+ * ~/.bikky/logs/llm.jsonl (or BIKKY_LLM_LOG override). Rotates at
4
+ * BIKKY_LLM_LOG_MAX_BYTES (default 10 MB).
5
+ *
6
+ * Telemetry is best-effort: any failure is swallowed and logged to the
7
+ * provided logger.
8
+ */
9
+ import { promises as fs } from "node:fs";
10
+ import { existsSync } from "node:fs";
11
+ import path from "node:path";
12
+ import os from "node:os";
13
+ const DEFAULT_PATH = path.join(os.homedir(), ".bikky", "logs", "llm.jsonl");
14
+ const DEFAULT_MAX_BYTES = 10 * 1024 * 1024;
15
+ const logPath = () => process.env.BIKKY_LLM_LOG ?? DEFAULT_PATH;
16
+ const maxBytes = () => {
17
+ const v = process.env.BIKKY_LLM_LOG_MAX_BYTES;
18
+ return v ? Number.parseInt(v, 10) || DEFAULT_MAX_BYTES : DEFAULT_MAX_BYTES;
19
+ };
20
+ /** Crude token estimator: ~4 chars per token. Good enough for trend lines. */
21
+ export const estimateTokens = (text) => Math.ceil(text.length / 4);
22
+ let warned = false;
23
+ export async function writeTelemetry(record, log) {
24
+ const file = logPath();
25
+ try {
26
+ await fs.mkdir(path.dirname(file), { recursive: true });
27
+ if (existsSync(file)) {
28
+ const stat = await fs.stat(file);
29
+ if (stat.size > maxBytes()) {
30
+ const rotated = `${file}.1`;
31
+ await fs.rename(file, rotated).catch(() => { });
32
+ }
33
+ }
34
+ await fs.appendFile(file, JSON.stringify(record) + "\n", "utf8");
35
+ }
36
+ catch (e) {
37
+ if (!warned) {
38
+ warned = true;
39
+ log("WARN", `LLM telemetry disabled: ${e.message}`);
40
+ }
41
+ }
42
+ }
43
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/llm/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAIzB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AAC5E,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAe3C,MAAM,OAAO,GAAG,GAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,YAAY,CAAC;AACxE,MAAM,QAAQ,GAAG,GAAW,EAAE;IAC5B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAC9C,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;AAC7E,CAAC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAEnF,IAAI,MAAM,GAAG,KAAK,CAAC;AACnB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAA0B,EAAE,GAAU;IACzE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC;gBAC5B,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,CAAC;YACd,GAAG,CAAC,MAAM,EAAE,2BAA4B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for LLM telemetry — JSONL append, rotation, error swallowing.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=telemetry.test.d.ts.map