@dotsetlabs/bellwether 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/CHANGELOG.md +291 -0
  2. package/LICENSE +21 -0
  3. package/README.md +739 -0
  4. package/dist/auth/credentials.d.ts +64 -0
  5. package/dist/auth/credentials.js +218 -0
  6. package/dist/auth/index.d.ts +6 -0
  7. package/dist/auth/index.js +6 -0
  8. package/dist/auth/keychain.d.ts +64 -0
  9. package/dist/auth/keychain.js +268 -0
  10. package/dist/baseline/ab-testing.d.ts +80 -0
  11. package/dist/baseline/ab-testing.js +236 -0
  12. package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
  13. package/dist/baseline/ai-compatibility-scorer.js +606 -0
  14. package/dist/baseline/calibration.d.ts +77 -0
  15. package/dist/baseline/calibration.js +136 -0
  16. package/dist/baseline/category-matching.d.ts +85 -0
  17. package/dist/baseline/category-matching.js +289 -0
  18. package/dist/baseline/change-impact-analyzer.d.ts +98 -0
  19. package/dist/baseline/change-impact-analyzer.js +592 -0
  20. package/dist/baseline/comparator.d.ts +64 -0
  21. package/dist/baseline/comparator.js +916 -0
  22. package/dist/baseline/confidence.d.ts +55 -0
  23. package/dist/baseline/confidence.js +122 -0
  24. package/dist/baseline/converter.d.ts +61 -0
  25. package/dist/baseline/converter.js +585 -0
  26. package/dist/baseline/dependency-analyzer.d.ts +89 -0
  27. package/dist/baseline/dependency-analyzer.js +567 -0
  28. package/dist/baseline/deprecation-tracker.d.ts +133 -0
  29. package/dist/baseline/deprecation-tracker.js +322 -0
  30. package/dist/baseline/diff.d.ts +55 -0
  31. package/dist/baseline/diff.js +1584 -0
  32. package/dist/baseline/documentation-scorer.d.ts +205 -0
  33. package/dist/baseline/documentation-scorer.js +466 -0
  34. package/dist/baseline/embeddings.d.ts +118 -0
  35. package/dist/baseline/embeddings.js +251 -0
  36. package/dist/baseline/error-analyzer.d.ts +198 -0
  37. package/dist/baseline/error-analyzer.js +721 -0
  38. package/dist/baseline/evaluation/evaluator.d.ts +42 -0
  39. package/dist/baseline/evaluation/evaluator.js +323 -0
  40. package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
  41. package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
  42. package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
  43. package/dist/baseline/evaluation/golden-dataset.js +717 -0
  44. package/dist/baseline/evaluation/index.d.ts +15 -0
  45. package/dist/baseline/evaluation/index.js +15 -0
  46. package/dist/baseline/evaluation/types.d.ts +186 -0
  47. package/dist/baseline/evaluation/types.js +8 -0
  48. package/dist/baseline/external-dependency-detector.d.ts +181 -0
  49. package/dist/baseline/external-dependency-detector.js +524 -0
  50. package/dist/baseline/golden-output.d.ts +162 -0
  51. package/dist/baseline/golden-output.js +636 -0
  52. package/dist/baseline/health-scorer.d.ts +174 -0
  53. package/dist/baseline/health-scorer.js +451 -0
  54. package/dist/baseline/incremental-checker.d.ts +97 -0
  55. package/dist/baseline/incremental-checker.js +174 -0
  56. package/dist/baseline/index.d.ts +31 -0
  57. package/dist/baseline/index.js +42 -0
  58. package/dist/baseline/migration-generator.d.ts +137 -0
  59. package/dist/baseline/migration-generator.js +554 -0
  60. package/dist/baseline/migrations.d.ts +60 -0
  61. package/dist/baseline/migrations.js +197 -0
  62. package/dist/baseline/performance-tracker.d.ts +214 -0
  63. package/dist/baseline/performance-tracker.js +577 -0
  64. package/dist/baseline/pr-comment-generator.d.ts +117 -0
  65. package/dist/baseline/pr-comment-generator.js +546 -0
  66. package/dist/baseline/response-fingerprint.d.ts +127 -0
  67. package/dist/baseline/response-fingerprint.js +728 -0
  68. package/dist/baseline/response-schema-tracker.d.ts +129 -0
  69. package/dist/baseline/response-schema-tracker.js +420 -0
  70. package/dist/baseline/risk-scorer.d.ts +54 -0
  71. package/dist/baseline/risk-scorer.js +434 -0
  72. package/dist/baseline/saver.d.ts +89 -0
  73. package/dist/baseline/saver.js +554 -0
  74. package/dist/baseline/scenario-generator.d.ts +151 -0
  75. package/dist/baseline/scenario-generator.js +905 -0
  76. package/dist/baseline/schema-compare.d.ts +86 -0
  77. package/dist/baseline/schema-compare.js +557 -0
  78. package/dist/baseline/schema-evolution.d.ts +189 -0
  79. package/dist/baseline/schema-evolution.js +467 -0
  80. package/dist/baseline/semantic.d.ts +203 -0
  81. package/dist/baseline/semantic.js +908 -0
  82. package/dist/baseline/synonyms.d.ts +60 -0
  83. package/dist/baseline/synonyms.js +386 -0
  84. package/dist/baseline/telemetry.d.ts +165 -0
  85. package/dist/baseline/telemetry.js +294 -0
  86. package/dist/baseline/test-pruner.d.ts +120 -0
  87. package/dist/baseline/test-pruner.js +387 -0
  88. package/dist/baseline/types.d.ts +449 -0
  89. package/dist/baseline/types.js +5 -0
  90. package/dist/baseline/version.d.ts +138 -0
  91. package/dist/baseline/version.js +206 -0
  92. package/dist/cache/index.d.ts +5 -0
  93. package/dist/cache/index.js +5 -0
  94. package/dist/cache/response-cache.d.ts +151 -0
  95. package/dist/cache/response-cache.js +287 -0
  96. package/dist/ci/index.d.ts +60 -0
  97. package/dist/ci/index.js +342 -0
  98. package/dist/cli/commands/auth.d.ts +12 -0
  99. package/dist/cli/commands/auth.js +352 -0
  100. package/dist/cli/commands/badge.d.ts +3 -0
  101. package/dist/cli/commands/badge.js +74 -0
  102. package/dist/cli/commands/baseline-accept.d.ts +15 -0
  103. package/dist/cli/commands/baseline-accept.js +178 -0
  104. package/dist/cli/commands/baseline-migrate.d.ts +12 -0
  105. package/dist/cli/commands/baseline-migrate.js +164 -0
  106. package/dist/cli/commands/baseline.d.ts +14 -0
  107. package/dist/cli/commands/baseline.js +449 -0
  108. package/dist/cli/commands/beta.d.ts +10 -0
  109. package/dist/cli/commands/beta.js +231 -0
  110. package/dist/cli/commands/check.d.ts +11 -0
  111. package/dist/cli/commands/check.js +820 -0
  112. package/dist/cli/commands/cloud/badge.d.ts +3 -0
  113. package/dist/cli/commands/cloud/badge.js +74 -0
  114. package/dist/cli/commands/cloud/diff.d.ts +6 -0
  115. package/dist/cli/commands/cloud/diff.js +79 -0
  116. package/dist/cli/commands/cloud/history.d.ts +6 -0
  117. package/dist/cli/commands/cloud/history.js +102 -0
  118. package/dist/cli/commands/cloud/link.d.ts +9 -0
  119. package/dist/cli/commands/cloud/link.js +119 -0
  120. package/dist/cli/commands/cloud/login.d.ts +7 -0
  121. package/dist/cli/commands/cloud/login.js +499 -0
  122. package/dist/cli/commands/cloud/projects.d.ts +6 -0
  123. package/dist/cli/commands/cloud/projects.js +44 -0
  124. package/dist/cli/commands/cloud/shared.d.ts +7 -0
  125. package/dist/cli/commands/cloud/shared.js +42 -0
  126. package/dist/cli/commands/cloud/teams.d.ts +8 -0
  127. package/dist/cli/commands/cloud/teams.js +169 -0
  128. package/dist/cli/commands/cloud/upload.d.ts +8 -0
  129. package/dist/cli/commands/cloud/upload.js +181 -0
  130. package/dist/cli/commands/contract.d.ts +11 -0
  131. package/dist/cli/commands/contract.js +280 -0
  132. package/dist/cli/commands/discover.d.ts +3 -0
  133. package/dist/cli/commands/discover.js +82 -0
  134. package/dist/cli/commands/eval.d.ts +9 -0
  135. package/dist/cli/commands/eval.js +187 -0
  136. package/dist/cli/commands/explore.d.ts +11 -0
  137. package/dist/cli/commands/explore.js +437 -0
  138. package/dist/cli/commands/feedback.d.ts +9 -0
  139. package/dist/cli/commands/feedback.js +174 -0
  140. package/dist/cli/commands/golden.d.ts +12 -0
  141. package/dist/cli/commands/golden.js +407 -0
  142. package/dist/cli/commands/history.d.ts +10 -0
  143. package/dist/cli/commands/history.js +202 -0
  144. package/dist/cli/commands/init.d.ts +9 -0
  145. package/dist/cli/commands/init.js +219 -0
  146. package/dist/cli/commands/interview.d.ts +3 -0
  147. package/dist/cli/commands/interview.js +903 -0
  148. package/dist/cli/commands/link.d.ts +10 -0
  149. package/dist/cli/commands/link.js +169 -0
  150. package/dist/cli/commands/login.d.ts +7 -0
  151. package/dist/cli/commands/login.js +499 -0
  152. package/dist/cli/commands/preset.d.ts +33 -0
  153. package/dist/cli/commands/preset.js +297 -0
  154. package/dist/cli/commands/profile.d.ts +33 -0
  155. package/dist/cli/commands/profile.js +286 -0
  156. package/dist/cli/commands/registry.d.ts +11 -0
  157. package/dist/cli/commands/registry.js +146 -0
  158. package/dist/cli/commands/shared.d.ts +79 -0
  159. package/dist/cli/commands/shared.js +196 -0
  160. package/dist/cli/commands/teams.d.ts +8 -0
  161. package/dist/cli/commands/teams.js +169 -0
  162. package/dist/cli/commands/test.d.ts +9 -0
  163. package/dist/cli/commands/test.js +500 -0
  164. package/dist/cli/commands/upload.d.ts +8 -0
  165. package/dist/cli/commands/upload.js +223 -0
  166. package/dist/cli/commands/validate-config.d.ts +6 -0
  167. package/dist/cli/commands/validate-config.js +35 -0
  168. package/dist/cli/commands/verify.d.ts +11 -0
  169. package/dist/cli/commands/verify.js +283 -0
  170. package/dist/cli/commands/watch.d.ts +12 -0
  171. package/dist/cli/commands/watch.js +253 -0
  172. package/dist/cli/index.d.ts +3 -0
  173. package/dist/cli/index.js +178 -0
  174. package/dist/cli/interactive.d.ts +47 -0
  175. package/dist/cli/interactive.js +216 -0
  176. package/dist/cli/output/terminal-reporter.d.ts +19 -0
  177. package/dist/cli/output/terminal-reporter.js +104 -0
  178. package/dist/cli/output.d.ts +226 -0
  179. package/dist/cli/output.js +438 -0
  180. package/dist/cli/utils/env.d.ts +5 -0
  181. package/dist/cli/utils/env.js +14 -0
  182. package/dist/cli/utils/progress.d.ts +59 -0
  183. package/dist/cli/utils/progress.js +206 -0
  184. package/dist/cli/utils/server-context.d.ts +10 -0
  185. package/dist/cli/utils/server-context.js +36 -0
  186. package/dist/cloud/auth.d.ts +144 -0
  187. package/dist/cloud/auth.js +374 -0
  188. package/dist/cloud/client.d.ts +24 -0
  189. package/dist/cloud/client.js +65 -0
  190. package/dist/cloud/http-client.d.ts +38 -0
  191. package/dist/cloud/http-client.js +215 -0
  192. package/dist/cloud/index.d.ts +23 -0
  193. package/dist/cloud/index.js +25 -0
  194. package/dist/cloud/mock-client.d.ts +107 -0
  195. package/dist/cloud/mock-client.js +545 -0
  196. package/dist/cloud/types.d.ts +515 -0
  197. package/dist/cloud/types.js +15 -0
  198. package/dist/config/defaults.d.ts +160 -0
  199. package/dist/config/defaults.js +169 -0
  200. package/dist/config/loader.d.ts +24 -0
  201. package/dist/config/loader.js +122 -0
  202. package/dist/config/template.d.ts +42 -0
  203. package/dist/config/template.js +647 -0
  204. package/dist/config/validator.d.ts +2112 -0
  205. package/dist/config/validator.js +658 -0
  206. package/dist/constants/cloud.d.ts +107 -0
  207. package/dist/constants/cloud.js +110 -0
  208. package/dist/constants/core.d.ts +521 -0
  209. package/dist/constants/core.js +556 -0
  210. package/dist/constants/testing.d.ts +1283 -0
  211. package/dist/constants/testing.js +1568 -0
  212. package/dist/constants.d.ts +10 -0
  213. package/dist/constants.js +10 -0
  214. package/dist/contract/index.d.ts +6 -0
  215. package/dist/contract/index.js +5 -0
  216. package/dist/contract/validator.d.ts +177 -0
  217. package/dist/contract/validator.js +574 -0
  218. package/dist/cost/index.d.ts +6 -0
  219. package/dist/cost/index.js +5 -0
  220. package/dist/cost/tracker.d.ts +134 -0
  221. package/dist/cost/tracker.js +313 -0
  222. package/dist/discovery/discovery.d.ts +16 -0
  223. package/dist/discovery/discovery.js +173 -0
  224. package/dist/discovery/types.d.ts +51 -0
  225. package/dist/discovery/types.js +2 -0
  226. package/dist/docs/agents.d.ts +3 -0
  227. package/dist/docs/agents.js +995 -0
  228. package/dist/docs/contract.d.ts +51 -0
  229. package/dist/docs/contract.js +1681 -0
  230. package/dist/docs/generator.d.ts +4 -0
  231. package/dist/docs/generator.js +4 -0
  232. package/dist/docs/html-reporter.d.ts +9 -0
  233. package/dist/docs/html-reporter.js +757 -0
  234. package/dist/docs/index.d.ts +10 -0
  235. package/dist/docs/index.js +11 -0
  236. package/dist/docs/junit-reporter.d.ts +18 -0
  237. package/dist/docs/junit-reporter.js +210 -0
  238. package/dist/docs/report.d.ts +14 -0
  239. package/dist/docs/report.js +44 -0
  240. package/dist/docs/sarif-reporter.d.ts +19 -0
  241. package/dist/docs/sarif-reporter.js +335 -0
  242. package/dist/docs/shared.d.ts +35 -0
  243. package/dist/docs/shared.js +162 -0
  244. package/dist/docs/templates.d.ts +12 -0
  245. package/dist/docs/templates.js +76 -0
  246. package/dist/errors/index.d.ts +6 -0
  247. package/dist/errors/index.js +6 -0
  248. package/dist/errors/retry.d.ts +92 -0
  249. package/dist/errors/retry.js +323 -0
  250. package/dist/errors/types.d.ts +321 -0
  251. package/dist/errors/types.js +584 -0
  252. package/dist/index.d.ts +32 -0
  253. package/dist/index.js +32 -0
  254. package/dist/interview/dependency-resolver.d.ts +11 -0
  255. package/dist/interview/dependency-resolver.js +32 -0
  256. package/dist/interview/interviewer.d.ts +232 -0
  257. package/dist/interview/interviewer.js +1939 -0
  258. package/dist/interview/mock-response-generator.d.ts +7 -0
  259. package/dist/interview/mock-response-generator.js +102 -0
  260. package/dist/interview/orchestrator.d.ts +237 -0
  261. package/dist/interview/orchestrator.js +1296 -0
  262. package/dist/interview/rate-limiter.d.ts +15 -0
  263. package/dist/interview/rate-limiter.js +55 -0
  264. package/dist/interview/response-validator.d.ts +10 -0
  265. package/dist/interview/response-validator.js +132 -0
  266. package/dist/interview/schema-inferrer.d.ts +8 -0
  267. package/dist/interview/schema-inferrer.js +71 -0
  268. package/dist/interview/schema-test-generator.d.ts +71 -0
  269. package/dist/interview/schema-test-generator.js +834 -0
  270. package/dist/interview/smart-value-generator.d.ts +155 -0
  271. package/dist/interview/smart-value-generator.js +554 -0
  272. package/dist/interview/stateful-test-runner.d.ts +19 -0
  273. package/dist/interview/stateful-test-runner.js +106 -0
  274. package/dist/interview/types.d.ts +561 -0
  275. package/dist/interview/types.js +2 -0
  276. package/dist/llm/anthropic.d.ts +41 -0
  277. package/dist/llm/anthropic.js +355 -0
  278. package/dist/llm/client.d.ts +123 -0
  279. package/dist/llm/client.js +42 -0
  280. package/dist/llm/factory.d.ts +38 -0
  281. package/dist/llm/factory.js +145 -0
  282. package/dist/llm/fallback.d.ts +140 -0
  283. package/dist/llm/fallback.js +379 -0
  284. package/dist/llm/index.d.ts +18 -0
  285. package/dist/llm/index.js +15 -0
  286. package/dist/llm/ollama.d.ts +37 -0
  287. package/dist/llm/ollama.js +330 -0
  288. package/dist/llm/openai.d.ts +25 -0
  289. package/dist/llm/openai.js +320 -0
  290. package/dist/llm/token-budget.d.ts +161 -0
  291. package/dist/llm/token-budget.js +395 -0
  292. package/dist/logging/logger.d.ts +70 -0
  293. package/dist/logging/logger.js +130 -0
  294. package/dist/metrics/collector.d.ts +106 -0
  295. package/dist/metrics/collector.js +547 -0
  296. package/dist/metrics/index.d.ts +7 -0
  297. package/dist/metrics/index.js +7 -0
  298. package/dist/metrics/prometheus.d.ts +20 -0
  299. package/dist/metrics/prometheus.js +241 -0
  300. package/dist/metrics/types.d.ts +209 -0
  301. package/dist/metrics/types.js +5 -0
  302. package/dist/persona/builtins.d.ts +54 -0
  303. package/dist/persona/builtins.js +219 -0
  304. package/dist/persona/index.d.ts +8 -0
  305. package/dist/persona/index.js +8 -0
  306. package/dist/persona/loader.d.ts +30 -0
  307. package/dist/persona/loader.js +190 -0
  308. package/dist/persona/types.d.ts +144 -0
  309. package/dist/persona/types.js +5 -0
  310. package/dist/persona/validation.d.ts +94 -0
  311. package/dist/persona/validation.js +332 -0
  312. package/dist/prompts/index.d.ts +5 -0
  313. package/dist/prompts/index.js +5 -0
  314. package/dist/prompts/templates.d.ts +180 -0
  315. package/dist/prompts/templates.js +431 -0
  316. package/dist/registry/client.d.ts +49 -0
  317. package/dist/registry/client.js +191 -0
  318. package/dist/registry/index.d.ts +7 -0
  319. package/dist/registry/index.js +6 -0
  320. package/dist/registry/types.d.ts +140 -0
  321. package/dist/registry/types.js +6 -0
  322. package/dist/scenarios/evaluator.d.ts +43 -0
  323. package/dist/scenarios/evaluator.js +206 -0
  324. package/dist/scenarios/index.d.ts +10 -0
  325. package/dist/scenarios/index.js +9 -0
  326. package/dist/scenarios/loader.d.ts +20 -0
  327. package/dist/scenarios/loader.js +285 -0
  328. package/dist/scenarios/types.d.ts +153 -0
  329. package/dist/scenarios/types.js +8 -0
  330. package/dist/security/index.d.ts +17 -0
  331. package/dist/security/index.js +18 -0
  332. package/dist/security/payloads.d.ts +61 -0
  333. package/dist/security/payloads.js +268 -0
  334. package/dist/security/security-tester.d.ts +42 -0
  335. package/dist/security/security-tester.js +582 -0
  336. package/dist/security/types.d.ts +166 -0
  337. package/dist/security/types.js +8 -0
  338. package/dist/transport/base-transport.d.ts +59 -0
  339. package/dist/transport/base-transport.js +38 -0
  340. package/dist/transport/http-transport.d.ts +67 -0
  341. package/dist/transport/http-transport.js +238 -0
  342. package/dist/transport/mcp-client.d.ts +141 -0
  343. package/dist/transport/mcp-client.js +496 -0
  344. package/dist/transport/sse-transport.d.ts +88 -0
  345. package/dist/transport/sse-transport.js +316 -0
  346. package/dist/transport/stdio-transport.d.ts +43 -0
  347. package/dist/transport/stdio-transport.js +238 -0
  348. package/dist/transport/types.d.ts +125 -0
  349. package/dist/transport/types.js +16 -0
  350. package/dist/utils/concurrency.d.ts +123 -0
  351. package/dist/utils/concurrency.js +213 -0
  352. package/dist/utils/formatters.d.ts +16 -0
  353. package/dist/utils/formatters.js +37 -0
  354. package/dist/utils/index.d.ts +8 -0
  355. package/dist/utils/index.js +8 -0
  356. package/dist/utils/jsonpath.d.ts +87 -0
  357. package/dist/utils/jsonpath.js +326 -0
  358. package/dist/utils/markdown.d.ts +113 -0
  359. package/dist/utils/markdown.js +265 -0
  360. package/dist/utils/network.d.ts +14 -0
  361. package/dist/utils/network.js +17 -0
  362. package/dist/utils/sanitize.d.ts +92 -0
  363. package/dist/utils/sanitize.js +191 -0
  364. package/dist/utils/semantic.d.ts +194 -0
  365. package/dist/utils/semantic.js +1051 -0
  366. package/dist/utils/smart-truncate.d.ts +94 -0
  367. package/dist/utils/smart-truncate.js +361 -0
  368. package/dist/utils/timeout.d.ts +153 -0
  369. package/dist/utils/timeout.js +205 -0
  370. package/dist/utils/yaml-parser.d.ts +58 -0
  371. package/dist/utils/yaml-parser.js +86 -0
  372. package/dist/validation/index.d.ts +32 -0
  373. package/dist/validation/index.js +32 -0
  374. package/dist/validation/semantic-test-generator.d.ts +50 -0
  375. package/dist/validation/semantic-test-generator.js +176 -0
  376. package/dist/validation/semantic-types.d.ts +66 -0
  377. package/dist/validation/semantic-types.js +94 -0
  378. package/dist/validation/semantic-validator.d.ts +38 -0
  379. package/dist/validation/semantic-validator.js +340 -0
  380. package/dist/verification/index.d.ts +6 -0
  381. package/dist/verification/index.js +5 -0
  382. package/dist/verification/types.d.ts +133 -0
  383. package/dist/verification/types.js +5 -0
  384. package/dist/verification/verifier.d.ts +30 -0
  385. package/dist/verification/verifier.js +309 -0
  386. package/dist/version.d.ts +19 -0
  387. package/dist/version.js +48 -0
  388. package/dist/workflow/auto-generator.d.ts +27 -0
  389. package/dist/workflow/auto-generator.js +513 -0
  390. package/dist/workflow/discovery.d.ts +40 -0
  391. package/dist/workflow/discovery.js +195 -0
  392. package/dist/workflow/executor.d.ts +82 -0
  393. package/dist/workflow/executor.js +611 -0
  394. package/dist/workflow/index.d.ts +10 -0
  395. package/dist/workflow/index.js +10 -0
  396. package/dist/workflow/loader.d.ts +24 -0
  397. package/dist/workflow/loader.js +194 -0
  398. package/dist/workflow/state-tracker.d.ts +98 -0
  399. package/dist/workflow/state-tracker.js +424 -0
  400. package/dist/workflow/types.d.ts +337 -0
  401. package/dist/workflow/types.js +5 -0
  402. package/package.json +94 -0
  403. package/schemas/bellwether-check.schema.json +651 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Ollama LLM client implementation for local models.
3
+ */
4
+ import type { LLMClient, Message, CompletionOptions, ProviderInfo, StreamingOptions, StreamingResult } from './client.js';
5
+ export interface OllamaClientOptions {
6
+ /** Base URL for Ollama API (defaults to http://localhost:11434) */
7
+ baseUrl?: string;
8
+ /** Default model to use */
9
+ model?: string;
10
+ /** Callback to receive token usage from each API call */
11
+ onUsage?: (inputTokens: number, outputTokens: number) => void;
12
+ }
13
+ /**
14
+ * Ollama LLM client for local model inference.
15
+ */
16
+ export declare class OllamaClient implements LLMClient {
17
+ private baseUrl;
18
+ private defaultModel;
19
+ private logger;
20
+ private onUsage?;
21
+ constructor(options?: OllamaClientOptions);
22
+ getProviderInfo(): ProviderInfo;
23
+ chat(messages: Message[], options?: CompletionOptions): Promise<string>;
24
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
25
+ parseJSON<T>(response: string): T;
26
+ stream(prompt: string, options?: StreamingOptions): Promise<StreamingResult>;
27
+ streamChat(messages: Message[], options?: StreamingOptions): Promise<StreamingResult>;
28
+ /**
29
+ * Check if Ollama is running and accessible.
30
+ */
31
+ isAvailable(): Promise<boolean>;
32
+ /**
33
+ * List available models.
34
+ */
35
+ listModels(): Promise<string[]>;
36
+ }
37
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1,330 @@
1
+ /**
2
+ * Ollama LLM client implementation for local models.
3
+ */
4
+ import { DEFAULT_MODELS, parseJSONResponse } from './client.js';
5
+ import { withRetry, LLM_RETRY_OPTIONS } from '../errors/retry.js';
6
+ import { LLMConnectionError, BellwetherError } from '../errors/index.js';
7
+ import { getLogger } from '../logging/logger.js';
8
+ import { LLM_DEFAULTS } from '../constants.js';
9
+ /**
10
+ * Ollama LLM client for local model inference.
11
+ */
12
+ export class OllamaClient {
13
+ baseUrl;
14
+ defaultModel;
15
+ logger = getLogger('ollama');
16
+ onUsage;
17
+ constructor(options) {
18
+ this.baseUrl = options?.baseUrl ?? process.env.OLLAMA_BASE_URL ?? LLM_DEFAULTS.OLLAMA_BASE_URL;
19
+ this.defaultModel = options?.model ?? DEFAULT_MODELS.ollama;
20
+ this.onUsage = options?.onUsage;
21
+ }
22
+ getProviderInfo() {
23
+ return {
24
+ id: 'ollama',
25
+ name: 'Ollama (Local)',
26
+ supportsJSON: true, // Ollama supports format: 'json'
27
+ supportsStreaming: true,
28
+ defaultModel: this.defaultModel,
29
+ };
30
+ }
31
+ async chat(messages, options) {
32
+ const model = options?.model ?? this.defaultModel;
33
+ return withRetry(async () => {
34
+ // Build messages array with optional system prompt
35
+ const allMessages = [];
36
+ if (options?.systemPrompt) {
37
+ allMessages.push({
38
+ role: 'system',
39
+ content: options.systemPrompt,
40
+ });
41
+ }
42
+ for (const msg of messages) {
43
+ allMessages.push({
44
+ role: msg.role,
45
+ content: msg.content,
46
+ });
47
+ }
48
+ const request = {
49
+ model,
50
+ messages: allMessages,
51
+ stream: false,
52
+ options: {
53
+ temperature: options?.temperature ?? LLM_DEFAULTS.TEMPERATURE,
54
+ num_predict: options?.maxTokens ?? LLM_DEFAULTS.MAX_TOKENS,
55
+ },
56
+ };
57
+ // Add JSON format if requested
58
+ if (options?.responseFormat === 'json') {
59
+ request.format = 'json';
60
+ }
61
+ try {
62
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ },
67
+ body: JSON.stringify(request),
68
+ });
69
+ if (!response.ok) {
70
+ const errorText = await response.text();
71
+ throw new Error(`Ollama API error (${response.status}): ${errorText}`);
72
+ }
73
+ const result = await response.json();
74
+ if (!result.message?.content) {
75
+ throw new Error('No content in Ollama response');
76
+ }
77
+ // Track token usage from Ollama response
78
+ if (this.onUsage) {
79
+ const promptTokens = result.prompt_eval_count ?? 0;
80
+ const completionTokens = result.eval_count ?? 0;
81
+ if (promptTokens > 0 || completionTokens > 0) {
82
+ this.onUsage(promptTokens, completionTokens);
83
+ this.logger.debug({
84
+ promptTokens,
85
+ completionTokens,
86
+ msg: 'Ollama token usage tracked',
87
+ });
88
+ }
89
+ }
90
+ return result.message.content;
91
+ }
92
+ catch (error) {
93
+ if (error instanceof Error) {
94
+ const message = error.message.toLowerCase();
95
+ // Check for connection errors - these are retryable
96
+ if (message.includes('econnrefused') || message.includes('fetch failed')) {
97
+ throw new LLMConnectionError('ollama', model, undefined, error);
98
+ }
99
+ // Check for model not found - not retryable
100
+ if (message.includes('not found') || message.includes('does not exist')) {
101
+ throw new BellwetherError(`Model "${model}" not found. Pull it with: ollama pull ${model}`, {
102
+ code: 'LLM_MODEL_NOT_FOUND',
103
+ severity: 'high',
104
+ retryable: 'terminal',
105
+ context: { component: 'ollama', metadata: { model } },
106
+ cause: error,
107
+ });
108
+ }
109
+ }
110
+ throw error;
111
+ }
112
+ }, {
113
+ ...LLM_RETRY_OPTIONS,
114
+ maxAttempts: 2, // Ollama is local, fewer retries needed
115
+ operation: 'Ollama chat completion',
116
+ context: { component: 'ollama', metadata: { model, baseUrl: this.baseUrl } },
117
+ onRetry: (error, attempt, delayMs) => {
118
+ this.logger.debug({
119
+ attempt,
120
+ delayMs: Math.round(delayMs),
121
+ error: error instanceof Error ? error.message : String(error),
122
+ msg: `Retrying Ollama API call`,
123
+ });
124
+ },
125
+ });
126
+ }
127
+ async complete(prompt, options) {
128
+ return this.chat([{ role: 'user', content: prompt }], options);
129
+ }
130
+ parseJSON(response) {
131
+ return parseJSONResponse(response);
132
+ }
133
+ async stream(prompt, options) {
134
+ return this.streamChat([{ role: 'user', content: prompt }], options);
135
+ }
136
+ async streamChat(messages, options) {
137
+ const model = options?.model ?? this.defaultModel;
138
+ return withRetry(async () => {
139
+ // Build messages array with optional system prompt
140
+ const allMessages = [];
141
+ if (options?.systemPrompt) {
142
+ allMessages.push({
143
+ role: 'system',
144
+ content: options.systemPrompt,
145
+ });
146
+ }
147
+ for (const msg of messages) {
148
+ allMessages.push({
149
+ role: msg.role,
150
+ content: msg.content,
151
+ });
152
+ }
153
+ const request = {
154
+ model,
155
+ messages: allMessages,
156
+ stream: true, // Enable streaming
157
+ options: {
158
+ temperature: options?.temperature ?? LLM_DEFAULTS.TEMPERATURE,
159
+ num_predict: options?.maxTokens ?? LLM_DEFAULTS.MAX_TOKENS,
160
+ },
161
+ };
162
+ // Add JSON format if requested
163
+ if (options?.responseFormat === 'json') {
164
+ request.format = 'json';
165
+ }
166
+ try {
167
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
168
+ method: 'POST',
169
+ headers: {
170
+ 'Content-Type': 'application/json',
171
+ },
172
+ body: JSON.stringify(request),
173
+ });
174
+ if (!response.ok) {
175
+ const errorText = await response.text();
176
+ throw new Error(`Ollama API error (${response.status}): ${errorText}`);
177
+ }
178
+ if (!response.body) {
179
+ throw new Error('No response body for streaming');
180
+ }
181
+ // Read the NDJSON stream
182
+ const reader = response.body.getReader();
183
+ const decoder = new TextDecoder();
184
+ let fullText = '';
185
+ let promptTokens = 0;
186
+ let completionTokens = 0;
187
+ let buffer = '';
188
+ try {
189
+ let done = false;
190
+ while (!done) {
191
+ const result = await reader.read();
192
+ done = result.done;
193
+ const value = result.value;
194
+ if (done)
195
+ break;
196
+ // Decode chunk and add to buffer
197
+ buffer += decoder.decode(value, { stream: true });
198
+ // Process complete lines (NDJSON format)
199
+ const lines = buffer.split('\n');
200
+ buffer = lines.pop() ?? ''; // Keep incomplete line in buffer
201
+ for (const line of lines) {
202
+ if (!line.trim())
203
+ continue;
204
+ try {
205
+ const chunk = JSON.parse(line);
206
+ if (chunk.message?.content) {
207
+ fullText += chunk.message.content;
208
+ options?.onChunk?.(chunk.message.content);
209
+ }
210
+ // Track token counts from final chunk
211
+ if (chunk.done) {
212
+ promptTokens = chunk.prompt_eval_count ?? 0;
213
+ completionTokens = chunk.eval_count ?? 0;
214
+ }
215
+ }
216
+ catch {
217
+ // Skip malformed JSON lines
218
+ this.logger.debug({ line }, 'Skipping malformed stream line');
219
+ }
220
+ }
221
+ }
222
+ // Process any remaining buffer
223
+ if (buffer.trim()) {
224
+ try {
225
+ const chunk = JSON.parse(buffer);
226
+ if (chunk.message?.content) {
227
+ fullText += chunk.message.content;
228
+ options?.onChunk?.(chunk.message.content);
229
+ }
230
+ if (chunk.done) {
231
+ promptTokens = chunk.prompt_eval_count ?? 0;
232
+ completionTokens = chunk.eval_count ?? 0;
233
+ }
234
+ }
235
+ catch (parseError) {
236
+ // Log parse error for debugging
237
+ this.logger.debug({ buffer, error: parseError instanceof Error ? parseError.message : String(parseError) }, 'Failed to parse final buffer chunk');
238
+ }
239
+ }
240
+ }
241
+ finally {
242
+ reader.releaseLock();
243
+ }
244
+ // Track token usage
245
+ if (this.onUsage && (promptTokens > 0 || completionTokens > 0)) {
246
+ this.onUsage(promptTokens, completionTokens);
247
+ this.logger.debug({
248
+ promptTokens,
249
+ completionTokens,
250
+ msg: 'Ollama streaming token usage tracked',
251
+ });
252
+ }
253
+ if (!fullText) {
254
+ throw new Error('No content in Ollama streaming response');
255
+ }
256
+ options?.onComplete?.(fullText);
257
+ return { text: fullText, completed: true };
258
+ }
259
+ catch (error) {
260
+ options?.onError?.(error instanceof Error ? error : new Error(String(error)));
261
+ if (error instanceof Error) {
262
+ const message = error.message.toLowerCase();
263
+ // Check for connection errors - these are retryable
264
+ if (message.includes('econnrefused') || message.includes('fetch failed')) {
265
+ throw new LLMConnectionError('ollama', model, undefined, error);
266
+ }
267
+ // Check for model not found - not retryable
268
+ if (message.includes('not found') || message.includes('does not exist')) {
269
+ throw new BellwetherError(`Model "${model}" not found. Pull it with: ollama pull ${model}`, {
270
+ code: 'LLM_MODEL_NOT_FOUND',
271
+ severity: 'high',
272
+ retryable: 'terminal',
273
+ context: { component: 'ollama', metadata: { model } },
274
+ cause: error,
275
+ });
276
+ }
277
+ }
278
+ throw error;
279
+ }
280
+ }, {
281
+ ...LLM_RETRY_OPTIONS,
282
+ maxAttempts: 2, // Ollama is local, fewer retries needed
283
+ operation: 'Ollama streaming chat completion',
284
+ context: { component: 'ollama', metadata: { model, baseUrl: this.baseUrl } },
285
+ onRetry: (error, attempt, delayMs) => {
286
+ this.logger.debug({
287
+ attempt,
288
+ delayMs: Math.round(delayMs),
289
+ error: error instanceof Error ? error.message : String(error),
290
+ msg: `Retrying Ollama streaming API call`,
291
+ });
292
+ },
293
+ });
294
+ }
295
+ /**
296
+ * Check if Ollama is running and accessible.
297
+ */
298
+ async isAvailable() {
299
+ try {
300
+ const response = await fetch(`${this.baseUrl}/api/tags`, {
301
+ method: 'GET',
302
+ });
303
+ return response.ok;
304
+ }
305
+ catch (error) {
306
+ this.logger.debug({ error: error instanceof Error ? error.message : String(error) }, 'Ollama availability check failed');
307
+ return false;
308
+ }
309
+ }
310
+ /**
311
+ * List available models.
312
+ */
313
+ async listModels() {
314
+ try {
315
+ const response = await fetch(`${this.baseUrl}/api/tags`, {
316
+ method: 'GET',
317
+ });
318
+ if (!response.ok) {
319
+ return [];
320
+ }
321
+ const result = await response.json();
322
+ return result.models?.map(m => m.name) ?? [];
323
+ }
324
+ catch (error) {
325
+ this.logger.debug({ error: error instanceof Error ? error.message : String(error) }, 'Failed to list Ollama models');
326
+ return [];
327
+ }
328
+ }
329
+ }
330
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1,25 @@
1
+ import type { LLMClient, Message, CompletionOptions, ProviderInfo, StreamingOptions, StreamingResult } from './client.js';
2
+ export interface OpenAIClientOptions {
3
+ /** API key (defaults to OPENAI_API_KEY env var) */
4
+ apiKey?: string;
5
+ /** Default model to use */
6
+ model?: string;
7
+ /** Base URL for API (for proxies/alternatives) */
8
+ baseURL?: string;
9
+ /** Callback to receive token usage from each API call */
10
+ onUsage?: (inputTokens: number, outputTokens: number) => void;
11
+ }
12
+ export declare class OpenAIClient implements LLMClient {
13
+ private client;
14
+ private defaultModel;
15
+ private logger;
16
+ private onUsage?;
17
+ constructor(options?: OpenAIClientOptions);
18
+ getProviderInfo(): ProviderInfo;
19
+ chat(messages: Message[], options?: CompletionOptions): Promise<string>;
20
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
21
+ parseJSON<T>(response: string): T;
22
+ stream(prompt: string, options?: StreamingOptions): Promise<StreamingResult>;
23
+ streamChat(messages: Message[], options?: StreamingOptions): Promise<StreamingResult>;
24
+ }
25
+ //# sourceMappingURL=openai.d.ts.map