@syrin/cli 1.3.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 (438) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +302 -0
  3. package/dist/cli/commands/analyse.d.ts +16 -0
  4. package/dist/cli/commands/analyse.js +61 -0
  5. package/dist/cli/commands/dev.d.ts +23 -0
  6. package/dist/cli/commands/dev.js +419 -0
  7. package/dist/cli/commands/doctor.d.ts +10 -0
  8. package/dist/cli/commands/doctor.js +195 -0
  9. package/dist/cli/commands/index.d.ts +12 -0
  10. package/dist/cli/commands/index.js +12 -0
  11. package/dist/cli/commands/init.d.ts +16 -0
  12. package/dist/cli/commands/init.js +90 -0
  13. package/dist/cli/commands/list.d.ts +15 -0
  14. package/dist/cli/commands/list.js +50 -0
  15. package/dist/cli/commands/rollback.d.ts +12 -0
  16. package/dist/cli/commands/rollback.js +101 -0
  17. package/dist/cli/commands/test.d.ts +31 -0
  18. package/dist/cli/commands/test.js +88 -0
  19. package/dist/cli/commands/update.d.ts +9 -0
  20. package/dist/cli/commands/update.js +76 -0
  21. package/dist/cli/index.d.ts +13 -0
  22. package/dist/cli/index.js +342 -0
  23. package/dist/cli/prompts/index.d.ts +5 -0
  24. package/dist/cli/prompts/index.js +5 -0
  25. package/dist/cli/prompts/init-prompt.d.ts +17 -0
  26. package/dist/cli/prompts/init-prompt.js +263 -0
  27. package/dist/cli/utils/command-error-handler.d.ts +14 -0
  28. package/dist/cli/utils/command-error-handler.js +35 -0
  29. package/dist/cli/utils/common-types.d.ts +24 -0
  30. package/dist/cli/utils/common-types.js +6 -0
  31. package/dist/cli/utils/connection-handler.d.ts +37 -0
  32. package/dist/cli/utils/connection-handler.js +90 -0
  33. package/dist/cli/utils/index.d.ts +11 -0
  34. package/dist/cli/utils/index.js +11 -0
  35. package/dist/cli/utils/option-parsers.d.ts +41 -0
  36. package/dist/cli/utils/option-parsers.js +92 -0
  37. package/dist/cli/utils/output-utils.d.ts +12 -0
  38. package/dist/cli/utils/output-utils.js +21 -0
  39. package/dist/cli/utils/transport-resolver.d.ts +33 -0
  40. package/dist/cli/utils/transport-resolver.js +82 -0
  41. package/dist/cli/utils/version-banner.d.ts +10 -0
  42. package/dist/cli/utils/version-banner.js +26 -0
  43. package/dist/config/env-checker.d.ts +37 -0
  44. package/dist/config/env-checker.js +136 -0
  45. package/dist/config/generator.d.ts +19 -0
  46. package/dist/config/generator.js +196 -0
  47. package/dist/config/index.d.ts +9 -0
  48. package/dist/config/index.js +9 -0
  49. package/dist/config/loader.d.ts +19 -0
  50. package/dist/config/loader.js +57 -0
  51. package/dist/config/schema.d.ts +42 -0
  52. package/dist/config/schema.js +181 -0
  53. package/dist/config/syrin.template.yaml +127 -0
  54. package/dist/config/types.d.ts +87 -0
  55. package/dist/config/types.js +6 -0
  56. package/dist/constants/app.d.ts +9 -0
  57. package/dist/constants/app.js +9 -0
  58. package/dist/constants/commands.d.ts +43 -0
  59. package/dist/constants/commands.js +43 -0
  60. package/dist/constants/defaults.d.ts +18 -0
  61. package/dist/constants/defaults.js +18 -0
  62. package/dist/constants/env-vars.d.ts +11 -0
  63. package/dist/constants/env-vars.js +11 -0
  64. package/dist/constants/icons.d.ts +23 -0
  65. package/dist/constants/icons.js +23 -0
  66. package/dist/constants/index.d.ts +17 -0
  67. package/dist/constants/index.js +17 -0
  68. package/dist/constants/labels.d.ts +38 -0
  69. package/dist/constants/labels.js +42 -0
  70. package/dist/constants/links.d.ts +10 -0
  71. package/dist/constants/links.js +11 -0
  72. package/dist/constants/list.d.ts +10 -0
  73. package/dist/constants/list.js +9 -0
  74. package/dist/constants/llm.d.ts +26 -0
  75. package/dist/constants/llm.js +25 -0
  76. package/dist/constants/messages.d.ts +107 -0
  77. package/dist/constants/messages.js +138 -0
  78. package/dist/constants/paths.d.ts +29 -0
  79. package/dist/constants/paths.js +29 -0
  80. package/dist/constants/transport.d.ts +9 -0
  81. package/dist/constants/transport.js +8 -0
  82. package/dist/events/emitter.d.ts +64 -0
  83. package/dist/events/emitter.js +142 -0
  84. package/dist/events/event-type.d.ts +66 -0
  85. package/dist/events/event-type.js +81 -0
  86. package/dist/events/payloads/diagnostics.d.ts +24 -0
  87. package/dist/events/payloads/diagnostics.js +5 -0
  88. package/dist/events/payloads/index.d.ts +15 -0
  89. package/dist/events/payloads/index.js +6 -0
  90. package/dist/events/payloads/llm.d.ts +58 -0
  91. package/dist/events/payloads/llm.js +6 -0
  92. package/dist/events/payloads/registry.d.ts +28 -0
  93. package/dist/events/payloads/registry.js +5 -0
  94. package/dist/events/payloads/session.d.ts +32 -0
  95. package/dist/events/payloads/session.js +5 -0
  96. package/dist/events/payloads/testing.d.ts +17 -0
  97. package/dist/events/payloads/testing.js +5 -0
  98. package/dist/events/payloads/tool.d.ts +29 -0
  99. package/dist/events/payloads/tool.js +5 -0
  100. package/dist/events/payloads/transport.d.ts +30 -0
  101. package/dist/events/payloads/transport.js +5 -0
  102. package/dist/events/payloads/validation.d.ts +37 -0
  103. package/dist/events/payloads/validation.js +5 -0
  104. package/dist/events/payloads/workflow.d.ts +45 -0
  105. package/dist/events/payloads/workflow.js +5 -0
  106. package/dist/events/store/file-store.d.ts +37 -0
  107. package/dist/events/store/file-store.js +113 -0
  108. package/dist/events/store/index.d.ts +7 -0
  109. package/dist/events/store/index.js +6 -0
  110. package/dist/events/store/memory-store.d.ts +26 -0
  111. package/dist/events/store/memory-store.js +39 -0
  112. package/dist/events/store.d.ts +11 -0
  113. package/dist/events/store.js +2 -0
  114. package/dist/events/types.d.ts +14 -0
  115. package/dist/events/types.js +2 -0
  116. package/dist/index.d.ts +8 -0
  117. package/dist/index.js +30 -0
  118. package/dist/presentation/analysis-ui.d.ts +24 -0
  119. package/dist/presentation/analysis-ui.js +158 -0
  120. package/dist/presentation/dev/chat-ui-types.d.ts +68 -0
  121. package/dist/presentation/dev/chat-ui-types.js +5 -0
  122. package/dist/presentation/dev/chat-ui.d.ts +61 -0
  123. package/dist/presentation/dev/chat-ui.js +714 -0
  124. package/dist/presentation/dev/components/assistant-message.d.ts +19 -0
  125. package/dist/presentation/dev/components/assistant-message.js +36 -0
  126. package/dist/presentation/dev/components/header.d.ts +16 -0
  127. package/dist/presentation/dev/components/header.js +22 -0
  128. package/dist/presentation/dev/components/index.d.ts +13 -0
  129. package/dist/presentation/dev/components/index.js +13 -0
  130. package/dist/presentation/dev/components/input-panel.d.ts +22 -0
  131. package/dist/presentation/dev/components/input-panel.js +43 -0
  132. package/dist/presentation/dev/components/message-component.d.ts +16 -0
  133. package/dist/presentation/dev/components/message-component.js +51 -0
  134. package/dist/presentation/dev/components/messages-list.d.ts +24 -0
  135. package/dist/presentation/dev/components/messages-list.js +48 -0
  136. package/dist/presentation/dev/components/system-message.d.ts +16 -0
  137. package/dist/presentation/dev/components/system-message.js +26 -0
  138. package/dist/presentation/dev/components/user-message.d.ts +21 -0
  139. package/dist/presentation/dev/components/user-message.js +35 -0
  140. package/dist/presentation/dev/components/welcome-banner.d.ts +24 -0
  141. package/dist/presentation/dev/components/welcome-banner.js +146 -0
  142. package/dist/presentation/dev/goodbye-messages.d.ts +31 -0
  143. package/dist/presentation/dev/goodbye-messages.js +100 -0
  144. package/dist/presentation/dev/index.d.ts +5 -0
  145. package/dist/presentation/dev/index.js +5 -0
  146. package/dist/presentation/dev/text-wrapper.d.ts +30 -0
  147. package/dist/presentation/dev/text-wrapper.js +74 -0
  148. package/dist/presentation/dev-ui.d.ts +33 -0
  149. package/dist/presentation/dev-ui.js +246 -0
  150. package/dist/presentation/doctor-ui.d.ts +40 -0
  151. package/dist/presentation/doctor-ui.js +157 -0
  152. package/dist/presentation/init-ui.d.ts +14 -0
  153. package/dist/presentation/init-ui.js +41 -0
  154. package/dist/presentation/list-ui.d.ts +44 -0
  155. package/dist/presentation/list-ui.js +139 -0
  156. package/dist/presentation/test-ui.d.ts +49 -0
  157. package/dist/presentation/test-ui.js +358 -0
  158. package/dist/runtime/analysis/analyser.d.ts +14 -0
  159. package/dist/runtime/analysis/analyser.js +88 -0
  160. package/dist/runtime/analysis/dependencies.d.ts +10 -0
  161. package/dist/runtime/analysis/dependencies.js +140 -0
  162. package/dist/runtime/analysis/index.d.ts +10 -0
  163. package/dist/runtime/analysis/index.js +10 -0
  164. package/dist/runtime/analysis/indexer.d.ts +10 -0
  165. package/dist/runtime/analysis/indexer.js +62 -0
  166. package/dist/runtime/analysis/loader.d.ts +15 -0
  167. package/dist/runtime/analysis/loader.js +47 -0
  168. package/dist/runtime/analysis/normalizer.d.ts +14 -0
  169. package/dist/runtime/analysis/normalizer.js +184 -0
  170. package/dist/runtime/analysis/rules/__test-helpers__.d.ts +18 -0
  171. package/dist/runtime/analysis/rules/__test-helpers__.js +40 -0
  172. package/dist/runtime/analysis/rules/base.d.ts +38 -0
  173. package/dist/runtime/analysis/rules/base.js +23 -0
  174. package/dist/runtime/analysis/rules/error-codes.d.ts +64 -0
  175. package/dist/runtime/analysis/rules/error-codes.js +73 -0
  176. package/dist/runtime/analysis/rules/errors/e000-tool-not-found.d.ts +35 -0
  177. package/dist/runtime/analysis/rules/errors/e000-tool-not-found.js +32 -0
  178. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +22 -0
  179. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +30 -0
  180. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +24 -0
  181. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +52 -0
  182. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +23 -0
  183. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +73 -0
  184. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +23 -0
  185. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +47 -0
  186. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +25 -0
  187. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +73 -0
  188. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +22 -0
  189. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +57 -0
  190. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +23 -0
  191. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +56 -0
  192. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +22 -0
  193. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +84 -0
  194. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +23 -0
  195. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +89 -0
  196. package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +25 -0
  197. package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +46 -0
  198. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +24 -0
  199. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +33 -0
  200. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +39 -0
  201. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +40 -0
  202. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +37 -0
  203. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +34 -0
  204. package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +39 -0
  205. package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +36 -0
  206. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +42 -0
  207. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +46 -0
  208. package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +39 -0
  209. package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +36 -0
  210. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +42 -0
  211. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +46 -0
  212. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +44 -0
  213. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +66 -0
  214. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +43 -0
  215. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +42 -0
  216. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +44 -0
  217. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +66 -0
  218. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +57 -0
  219. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +80 -0
  220. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +43 -0
  221. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +42 -0
  222. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +57 -0
  223. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +80 -0
  224. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +38 -0
  225. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +37 -0
  226. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +38 -0
  227. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +37 -0
  228. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +65 -0
  229. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +109 -0
  230. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +65 -0
  231. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +109 -0
  232. package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.d.ts +22 -0
  233. package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.js +30 -0
  234. package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.d.ts +24 -0
  235. package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.js +33 -0
  236. package/dist/runtime/analysis/rules/errors/e102-underspecified-input.d.ts +24 -0
  237. package/dist/runtime/analysis/rules/errors/e102-underspecified-input.js +52 -0
  238. package/dist/runtime/analysis/rules/errors/e103-type-mismatch.d.ts +23 -0
  239. package/dist/runtime/analysis/rules/errors/e103-type-mismatch.js +72 -0
  240. package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.d.ts +22 -0
  241. package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.js +57 -0
  242. package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.d.ts +23 -0
  243. package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.js +47 -0
  244. package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.d.ts +23 -0
  245. package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.js +58 -0
  246. package/dist/runtime/analysis/rules/errors/e107-circular-dependency.d.ts +22 -0
  247. package/dist/runtime/analysis/rules/errors/e107-circular-dependency.js +84 -0
  248. package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.d.ts +23 -0
  249. package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.js +94 -0
  250. package/dist/runtime/analysis/rules/errors/e109-non-serializable.d.ts +25 -0
  251. package/dist/runtime/analysis/rules/errors/e109-non-serializable.js +44 -0
  252. package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.d.ts +25 -0
  253. package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.js +73 -0
  254. package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.d.ts +57 -0
  255. package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.js +71 -0
  256. package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.d.ts +43 -0
  257. package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.js +44 -0
  258. package/dist/runtime/analysis/rules/errors/e301-output-explosion.d.ts +39 -0
  259. package/dist/runtime/analysis/rules/errors/e301-output-explosion.js +36 -0
  260. package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.d.ts +38 -0
  261. package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.js +37 -0
  262. package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.d.ts +44 -0
  263. package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.js +66 -0
  264. package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.d.ts +39 -0
  265. package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.js +40 -0
  266. package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.d.ts +47 -0
  267. package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.js +46 -0
  268. package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.d.ts +65 -0
  269. package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.js +109 -0
  270. package/dist/runtime/analysis/rules/index.d.ts +18 -0
  271. package/dist/runtime/analysis/rules/index.js +94 -0
  272. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +22 -0
  273. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +39 -0
  274. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +24 -0
  275. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +40 -0
  276. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +22 -0
  277. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +84 -0
  278. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +23 -0
  279. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +96 -0
  280. package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +53 -0
  281. package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +108 -0
  282. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +22 -0
  283. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +44 -0
  284. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +23 -0
  285. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +37 -0
  286. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +22 -0
  287. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +97 -0
  288. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +23 -0
  289. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +88 -0
  290. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +22 -0
  291. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +81 -0
  292. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +40 -0
  293. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +32 -0
  294. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +39 -0
  295. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +36 -0
  296. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +38 -0
  297. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +36 -0
  298. package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.d.ts +22 -0
  299. package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.js +89 -0
  300. package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.d.ts +24 -0
  301. package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.js +40 -0
  302. package/dist/runtime/analysis/rules/warnings/w102-missing-examples.d.ts +22 -0
  303. package/dist/runtime/analysis/rules/warnings/w102-missing-examples.js +76 -0
  304. package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.d.ts +23 -0
  305. package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.js +91 -0
  306. package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +53 -0
  307. package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +108 -0
  308. package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.d.ts +22 -0
  309. package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.js +45 -0
  310. package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.d.ts +23 -0
  311. package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.js +37 -0
  312. package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.d.ts +22 -0
  313. package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.js +97 -0
  314. package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.d.ts +23 -0
  315. package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.js +94 -0
  316. package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.d.ts +22 -0
  317. package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.js +63 -0
  318. package/dist/runtime/analysis/rules/warnings/w110-weak-schema.d.ts +40 -0
  319. package/dist/runtime/analysis/rules/warnings/w110-weak-schema.js +32 -0
  320. package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.d.ts +39 -0
  321. package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.js +47 -0
  322. package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.d.ts +38 -0
  323. package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.js +36 -0
  324. package/dist/runtime/analysis/strict-mode.d.ts +21 -0
  325. package/dist/runtime/analysis/strict-mode.js +44 -0
  326. package/dist/runtime/analysis/types.d.ts +133 -0
  327. package/dist/runtime/analysis/types.js +6 -0
  328. package/dist/runtime/analysis/utils.d.ts +19 -0
  329. package/dist/runtime/analysis/utils.js +21 -0
  330. package/dist/runtime/dev/data-manager.d.ts +55 -0
  331. package/dist/runtime/dev/data-manager.js +87 -0
  332. package/dist/runtime/dev/event-mapper.d.ts +100 -0
  333. package/dist/runtime/dev/event-mapper.js +400 -0
  334. package/dist/runtime/dev/formatter.d.ts +94 -0
  335. package/dist/runtime/dev/formatter.js +236 -0
  336. package/dist/runtime/dev/index.d.ts +9 -0
  337. package/dist/runtime/dev/index.js +9 -0
  338. package/dist/runtime/dev/repl.d.ts +114 -0
  339. package/dist/runtime/dev/repl.js +310 -0
  340. package/dist/runtime/dev/session.d.ts +86 -0
  341. package/dist/runtime/dev/session.js +447 -0
  342. package/dist/runtime/dev/stack-trace.d.ts +77 -0
  343. package/dist/runtime/dev/stack-trace.js +286 -0
  344. package/dist/runtime/dev/types.d.ts +54 -0
  345. package/dist/runtime/dev/types.js +5 -0
  346. package/dist/runtime/llm/claude.d.ts +27 -0
  347. package/dist/runtime/llm/claude.js +150 -0
  348. package/dist/runtime/llm/factory.d.ts +30 -0
  349. package/dist/runtime/llm/factory.js +78 -0
  350. package/dist/runtime/llm/index.d.ts +10 -0
  351. package/dist/runtime/llm/index.js +10 -0
  352. package/dist/runtime/llm/ollama.d.ts +45 -0
  353. package/dist/runtime/llm/ollama.js +449 -0
  354. package/dist/runtime/llm/openai.d.ts +27 -0
  355. package/dist/runtime/llm/openai.js +170 -0
  356. package/dist/runtime/llm/provider.d.ts +32 -0
  357. package/dist/runtime/llm/provider.js +6 -0
  358. package/dist/runtime/llm/types.d.ts +55 -0
  359. package/dist/runtime/llm/types.js +6 -0
  360. package/dist/runtime/mcp/client/base.d.ts +40 -0
  361. package/dist/runtime/mcp/client/base.js +157 -0
  362. package/dist/runtime/mcp/client/manager.d.ts +91 -0
  363. package/dist/runtime/mcp/client/manager.js +248 -0
  364. package/dist/runtime/mcp/client/process.d.ts +31 -0
  365. package/dist/runtime/mcp/client/process.js +82 -0
  366. package/dist/runtime/mcp/connection.d.ts +63 -0
  367. package/dist/runtime/mcp/connection.js +449 -0
  368. package/dist/runtime/mcp/index.d.ts +9 -0
  369. package/dist/runtime/mcp/index.js +9 -0
  370. package/dist/runtime/mcp/list.d.ts +50 -0
  371. package/dist/runtime/mcp/list.js +65 -0
  372. package/dist/runtime/mcp/stdio-transport.d.ts +23 -0
  373. package/dist/runtime/mcp/stdio-transport.js +71 -0
  374. package/dist/runtime/mcp/types.d.ts +85 -0
  375. package/dist/runtime/mcp/types.js +6 -0
  376. package/dist/runtime/sandbox/executor.d.ts +102 -0
  377. package/dist/runtime/sandbox/executor.js +537 -0
  378. package/dist/runtime/sandbox/index.d.ts +9 -0
  379. package/dist/runtime/sandbox/index.js +9 -0
  380. package/dist/runtime/sandbox/io-monitor.d.ts +78 -0
  381. package/dist/runtime/sandbox/io-monitor.js +98 -0
  382. package/dist/runtime/sandbox/time-parser.d.ts +19 -0
  383. package/dist/runtime/sandbox/time-parser.js +67 -0
  384. package/dist/runtime/sandbox/types.d.ts +58 -0
  385. package/dist/runtime/sandbox/types.js +23 -0
  386. package/dist/runtime/test/behavior-observer.d.ts +61 -0
  387. package/dist/runtime/test/behavior-observer.js +140 -0
  388. package/dist/runtime/test/contract-loader.d.ts +41 -0
  389. package/dist/runtime/test/contract-loader.js +158 -0
  390. package/dist/runtime/test/contract-schema.d.ts +46 -0
  391. package/dist/runtime/test/contract-schema.js +107 -0
  392. package/dist/runtime/test/contract-types.d.ts +106 -0
  393. package/dist/runtime/test/contract-types.js +6 -0
  394. package/dist/runtime/test/dependency-tracker.d.ts +66 -0
  395. package/dist/runtime/test/dependency-tracker.js +80 -0
  396. package/dist/runtime/test/formatters.d.ts +18 -0
  397. package/dist/runtime/test/formatters.js +172 -0
  398. package/dist/runtime/test/index.d.ts +12 -0
  399. package/dist/runtime/test/index.js +13 -0
  400. package/dist/runtime/test/input-generator.d.ts +33 -0
  401. package/dist/runtime/test/input-generator.js +498 -0
  402. package/dist/runtime/test/mcp-root-detector.d.ts +31 -0
  403. package/dist/runtime/test/mcp-root-detector.js +105 -0
  404. package/dist/runtime/test/orchestrator.d.ts +131 -0
  405. package/dist/runtime/test/orchestrator.js +738 -0
  406. package/dist/runtime/test/output-validator.d.ts +44 -0
  407. package/dist/runtime/test/output-validator.js +262 -0
  408. package/dist/runtime/test/retry-tester.d.ts +44 -0
  409. package/dist/runtime/test/retry-tester.js +103 -0
  410. package/dist/runtime/test/runner.d.ts +28 -0
  411. package/dist/runtime/test/runner.js +55 -0
  412. package/dist/runtime/test/synthetic-input-generator.d.ts +11 -0
  413. package/dist/runtime/test/synthetic-input-generator.js +154 -0
  414. package/dist/runtime/test/test-runner.d.ts +28 -0
  415. package/dist/runtime/test/test-runner.js +55 -0
  416. package/dist/types/factories.d.ts +16 -0
  417. package/dist/types/factories.js +43 -0
  418. package/dist/types/ids.d.ts +16 -0
  419. package/dist/types/ids.js +2 -0
  420. package/dist/types/opaque.d.ts +4 -0
  421. package/dist/types/opaque.js +2 -0
  422. package/dist/utils/errors.d.ts +92 -0
  423. package/dist/utils/errors.js +97 -0
  424. package/dist/utils/gitignore.d.ts +11 -0
  425. package/dist/utils/gitignore.js +59 -0
  426. package/dist/utils/json-file-saver.d.ts +17 -0
  427. package/dist/utils/json-file-saver.js +81 -0
  428. package/dist/utils/json-formatter.d.ts +63 -0
  429. package/dist/utils/json-formatter.js +344 -0
  430. package/dist/utils/logger.d.ts +184 -0
  431. package/dist/utils/logger.js +330 -0
  432. package/dist/utils/package-manager.d.ts +30 -0
  433. package/dist/utils/package-manager.js +157 -0
  434. package/dist/utils/version-checker.d.ts +47 -0
  435. package/dist/utils/version-checker.js +167 -0
  436. package/dist/utils/version-display.d.ts +10 -0
  437. package/dist/utils/version-display.js +20 -0
  438. package/package.json +106 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Ollama (local) LLM provider implementation.
3
+ * Supports both Ollama SDK (automatic) and local command execution.
4
+ */
5
+ import type { LLMProvider } from './provider.js';
6
+ import type { LLMRequest, LLMResponse } from './types.js';
7
+ /**
8
+ * Ollama provider implementation.
9
+ * Uses Ollama SDK to communicate with local Ollama instance.
10
+ * Automatically handles service startup and model downloading if needed.
11
+ */
12
+ export declare class OllamaProvider implements LLMProvider {
13
+ private client;
14
+ private modelName;
15
+ private baseUrl;
16
+ constructor(modelName: string, baseUrl?: string);
17
+ getName(): string;
18
+ getModelName(): string;
19
+ supportsToolCalls(): boolean;
20
+ /**
21
+ * Ensure Ollama service is running, start it automatically if needed.
22
+ */
23
+ private ensureOllamaRunning;
24
+ /**
25
+ * Check if model exists, download if it doesn't.
26
+ * Uses official Ollama API: https://github.com/ollama/ollama-js
27
+ */
28
+ private ensureModelExists;
29
+ chat(request: LLMRequest): Promise<LLMResponse>;
30
+ /**
31
+ * Check if Ollama is running.
32
+ * @param baseUrl - Base URL for Ollama API
33
+ * @returns true if Ollama is accessible
34
+ */
35
+ static checkConnection(baseUrl?: string): Promise<boolean>;
36
+ /**
37
+ * Create Ollama provider from config.
38
+ * @param modelNameEnvVar - Environment variable name for model name, or direct model name
39
+ * @param projectRoot - Project root directory
40
+ * @param baseUrl - Optional base URL for Ollama (defaults to http://localhost:11434)
41
+ * @returns Ollama provider instance
42
+ */
43
+ static fromConfig(modelNameEnvVar: string, projectRoot?: string, baseUrl?: string): OllamaProvider;
44
+ }
45
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Ollama (local) LLM provider implementation.
3
+ * Supports both Ollama SDK (automatic) and local command execution.
4
+ */
5
+ import { Ollama } from 'ollama';
6
+ import * as childProcess from 'child_process';
7
+ import { v4 as uuidv4 } from 'uuid';
8
+ import { ConfigurationError } from '../../utils/errors.js';
9
+ import { logger, log } from '../../utils/logger.js';
10
+ import { checkCommandExists, checkEnvVar } from '../../config/env-checker.js';
11
+ /**
12
+ * Static process manager for Ollama service.
13
+ * Ensures only one Ollama process is spawned per application instance.
14
+ */
15
+ class OllamaProcessManager {
16
+ static ollamaProcess = null;
17
+ static isStarting = false;
18
+ /**
19
+ * Start Ollama service if not already running.
20
+ */
21
+ static async ensureRunning(baseUrl = 'http://localhost:11434') {
22
+ // Check if already running
23
+ const client = new Ollama({ host: baseUrl });
24
+ try {
25
+ await client.list();
26
+ return; // Already running
27
+ }
28
+ catch {
29
+ // Not running, continue to start it
30
+ }
31
+ // Check if Ollama is installed
32
+ if (!checkCommandExists('ollama')) {
33
+ throw new ConfigurationError(`Ollama is not installed on your system.\n` +
34
+ `\n` +
35
+ `To install Ollama:\n` +
36
+ ` 1. Visit https://ollama.ai and download for your platform\n` +
37
+ ` 2. Install Ollama\n` +
38
+ ` 3. Run this command again\n` +
39
+ `\n` +
40
+ `Note: We cannot automatically install Ollama as it requires system-level permissions.`);
41
+ }
42
+ // Prevent multiple simultaneous start attempts
43
+ if (this.isStarting) {
44
+ // Wait for the other start attempt to complete
45
+ let retries = 30; // Wait up to 30 seconds
46
+ while (this.isStarting && retries > 0) {
47
+ await new Promise(resolve => setTimeout(resolve, 1000));
48
+ try {
49
+ await client.list();
50
+ return; // Started by another attempt
51
+ }
52
+ catch {
53
+ retries--;
54
+ }
55
+ }
56
+ if (retries === 0) {
57
+ throw new ConfigurationError('Timeout waiting for Ollama service to start');
58
+ }
59
+ return;
60
+ }
61
+ this.isStarting = true;
62
+ try {
63
+ log.info('🚀 Starting Ollama service...');
64
+ // Spawn Ollama serve process
65
+ this.ollamaProcess = childProcess.spawn('ollama', ['serve'], {
66
+ stdio: ['ignore', 'pipe', 'pipe'],
67
+ detached: false, // Keep attached so we can clean it up
68
+ });
69
+ // Set up cleanup on exit
70
+ const cleanup = () => {
71
+ if (this.ollamaProcess) {
72
+ try {
73
+ this.ollamaProcess.kill();
74
+ }
75
+ catch {
76
+ // Ignore errors during cleanup
77
+ }
78
+ this.ollamaProcess = null;
79
+ }
80
+ };
81
+ process.once('exit', cleanup);
82
+ process.once('SIGINT', cleanup);
83
+ process.once('SIGTERM', cleanup);
84
+ // Capture output (but don't spam console)
85
+ this.ollamaProcess.stdout?.on('data', () => {
86
+ // Ollama serve outputs are usually not needed
87
+ });
88
+ this.ollamaProcess.stderr?.on('data', (data) => {
89
+ const message = data.toString().trim();
90
+ // Only log errors, not normal startup messages
91
+ if (message && /error|fatal|critical/i.test(message)) {
92
+ logger.warn(`Ollama: ${message}`);
93
+ }
94
+ });
95
+ // Handle process errors
96
+ this.ollamaProcess.on('error', (error) => {
97
+ logger.error('Failed to start Ollama service', error);
98
+ this.ollamaProcess = null;
99
+ this.isStarting = false;
100
+ throw new ConfigurationError(`Failed to start Ollama service: ${error.message}`);
101
+ });
102
+ // Wait for Ollama to be ready (poll with retries)
103
+ const maxRetries = 30; // 30 seconds max
104
+ const retryDelay = 1000; // 1 second between retries
105
+ for (let i = 0; i < maxRetries; i++) {
106
+ await new Promise(resolve => setTimeout(resolve, retryDelay));
107
+ try {
108
+ await client.list();
109
+ log.success('✅ Ollama service is running');
110
+ log.blank();
111
+ this.isStarting = false;
112
+ return; // Success!
113
+ }
114
+ catch {
115
+ // Not ready yet, continue waiting
116
+ if (i === maxRetries - 1) {
117
+ // Last retry failed
118
+ if (this.ollamaProcess) {
119
+ this.ollamaProcess.kill();
120
+ this.ollamaProcess = null;
121
+ }
122
+ this.isStarting = false;
123
+ throw new ConfigurationError('Ollama service failed to start within 30 seconds. ' +
124
+ 'Please check if Ollama is installed correctly.');
125
+ }
126
+ }
127
+ }
128
+ }
129
+ catch (error) {
130
+ this.isStarting = false;
131
+ if (error instanceof ConfigurationError) {
132
+ throw error;
133
+ }
134
+ throw new ConfigurationError(`Failed to start Ollama service: ${error instanceof Error ? error.message : String(error)}`);
135
+ }
136
+ }
137
+ /**
138
+ * Stop the Ollama service if we started it.
139
+ */
140
+ static stop() {
141
+ if (this.ollamaProcess) {
142
+ try {
143
+ this.ollamaProcess.kill();
144
+ }
145
+ catch {
146
+ // Ignore errors
147
+ }
148
+ this.ollamaProcess = null;
149
+ }
150
+ this.isStarting = false;
151
+ }
152
+ }
153
+ /**
154
+ * Ollama provider implementation.
155
+ * Uses Ollama SDK to communicate with local Ollama instance.
156
+ * Automatically handles service startup and model downloading if needed.
157
+ */
158
+ export class OllamaProvider {
159
+ client;
160
+ modelName;
161
+ baseUrl;
162
+ constructor(modelName, baseUrl = 'http://localhost:11434') {
163
+ if (!modelName) {
164
+ throw new ConfigurationError('Ollama model name is required');
165
+ }
166
+ this.modelName = modelName;
167
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
168
+ this.client = new Ollama({
169
+ host: this.baseUrl,
170
+ });
171
+ }
172
+ getName() {
173
+ return 'Ollama';
174
+ }
175
+ getModelName() {
176
+ return this.modelName;
177
+ }
178
+ supportsToolCalls() {
179
+ // Ollama supports function calling/tools in newer models
180
+ // Most modern models (llama3.1+, mistral, etc.) support tools
181
+ return true;
182
+ }
183
+ /**
184
+ * Ensure Ollama service is running, start it automatically if needed.
185
+ */
186
+ async ensureOllamaRunning() {
187
+ try {
188
+ // Try to connect first
189
+ await this.client.list();
190
+ return; // Already running
191
+ }
192
+ catch {
193
+ // Not running, try to start it automatically
194
+ await OllamaProcessManager.ensureRunning(this.baseUrl);
195
+ // Verify it's now running
196
+ try {
197
+ await this.client.list();
198
+ }
199
+ catch (err) {
200
+ const errorMessage = err instanceof Error ? err.message : String(err);
201
+ throw new ConfigurationError(`Failed to connect to Ollama at ${this.baseUrl} after starting service: ${errorMessage}`);
202
+ }
203
+ }
204
+ }
205
+ /**
206
+ * Check if model exists, download if it doesn't.
207
+ * Uses official Ollama API: https://github.com/ollama/ollama-js
208
+ */
209
+ async ensureModelExists() {
210
+ try {
211
+ // Check if model exists using list() API
212
+ const modelsResponse = await this.client.list();
213
+ const modelExists = modelsResponse.models?.some((m) => m.name === this.modelName || m.name.startsWith(`${this.modelName}:`)) ?? false;
214
+ if (!modelExists) {
215
+ logger.info(`Model ${this.modelName} not found. Downloading...`);
216
+ log.blank();
217
+ log.info(`📥 Downloading model: ${this.modelName}`);
218
+ log.plain('This may take a few minutes depending on your internet connection...');
219
+ log.blank();
220
+ // Pull the model using official API with streaming for progress
221
+ const stream = await this.client.pull({
222
+ model: this.modelName,
223
+ stream: true,
224
+ });
225
+ // Show download progress according to ollama-js API
226
+ // Stream chunks have: status, completed, total, etc.
227
+ let lastPercent = 0;
228
+ for await (const chunk of stream) {
229
+ // Handle progress updates
230
+ if (chunk.completed !== undefined &&
231
+ chunk.total !== undefined &&
232
+ chunk.total > 0) {
233
+ const percent = Math.round((chunk.completed / chunk.total) * 100);
234
+ if (percent !== lastPercent) {
235
+ process.stdout.write(`\r📥 Downloading: ${percent}%`);
236
+ lastPercent = percent;
237
+ }
238
+ }
239
+ // Show status messages
240
+ if (chunk.status) {
241
+ process.stdout.write(`\r📥 ${chunk.status}`);
242
+ }
243
+ }
244
+ log.blank();
245
+ log.success('✅ Model downloaded successfully!');
246
+ log.blank();
247
+ }
248
+ }
249
+ catch (err) {
250
+ const errorMessage = err instanceof Error ? err.message : String(err);
251
+ throw new ConfigurationError(`Failed to ensure model ${this.modelName} is available: ${errorMessage}`);
252
+ }
253
+ }
254
+ async chat(request) {
255
+ try {
256
+ // Ensure Ollama is running
257
+ await this.ensureOllamaRunning();
258
+ // Ensure model exists (download if needed)
259
+ await this.ensureModelExists();
260
+ // Build messages for Ollama
261
+ const messages = request.messages.map(msg => ({
262
+ role: msg.role,
263
+ content: msg.content,
264
+ }));
265
+ // Add system prompt if provided
266
+ if (request.systemPrompt) {
267
+ messages.unshift({
268
+ role: 'system',
269
+ content: request.systemPrompt,
270
+ });
271
+ }
272
+ // Convert tools to Ollama format if provided
273
+ // Ollama uses a 'tools' array with function definitions
274
+ const tools = request.tools?.map(tool => {
275
+ // Ollama expects tools in a specific format
276
+ // Format: { type: 'function', function: { name, description, parameters } }
277
+ const inputSchema = tool.inputSchema;
278
+ // Convert properties to the format Ollama expects
279
+ const properties = {};
280
+ if (inputSchema.properties) {
281
+ for (const [key, value] of Object.entries(inputSchema.properties)) {
282
+ if (value &&
283
+ typeof value === 'object' &&
284
+ ('type' in value || 'description' in value)) {
285
+ properties[key] = value;
286
+ }
287
+ else {
288
+ // Default structure if not properly formatted
289
+ const valueStr = typeof value === 'string'
290
+ ? value
291
+ : value && typeof value === 'object'
292
+ ? JSON.stringify(value)
293
+ : String(value);
294
+ properties[key] = {
295
+ type: 'string',
296
+ description: valueStr,
297
+ };
298
+ }
299
+ }
300
+ }
301
+ return {
302
+ type: 'function',
303
+ function: {
304
+ name: tool.name,
305
+ description: tool.description,
306
+ parameters: {
307
+ type: 'object',
308
+ properties,
309
+ required: inputSchema.required || [],
310
+ },
311
+ },
312
+ };
313
+ });
314
+ // Call Ollama API according to official API: https://github.com/ollama/ollama-js
315
+ const chatRequest = {
316
+ model: this.modelName,
317
+ messages,
318
+ stream: false, // We want a complete response, not a stream
319
+ options: {
320
+ temperature: request.temperature ?? 0.7,
321
+ num_predict: request.maxTokens,
322
+ },
323
+ };
324
+ // Add tools if available
325
+ if (tools && tools.length > 0) {
326
+ chatRequest.tools = tools;
327
+ }
328
+ const response = await this.client.chat(chatRequest);
329
+ // Response structure according to ollama-js API:
330
+ // { message: { role: string, content: string, tool_calls?: [...] }, done: boolean, ... }
331
+ const content = response.message?.content || '';
332
+ // Extract tool calls from response
333
+ // Ollama returns tool_calls in the message if the model supports it
334
+ const toolCalls = [];
335
+ if (response.message &&
336
+ 'tool_calls' in response.message &&
337
+ response.message.tool_calls) {
338
+ const toolCallsArray = response.message.tool_calls;
339
+ for (const toolCall of toolCallsArray) {
340
+ if (toolCall.function) {
341
+ try {
342
+ let args;
343
+ if (typeof toolCall.function.arguments === 'string') {
344
+ args = JSON.parse(toolCall.function.arguments);
345
+ }
346
+ else if (toolCall.function.arguments &&
347
+ typeof toolCall.function.arguments === 'object' &&
348
+ !Array.isArray(toolCall.function.arguments)) {
349
+ args = toolCall.function.arguments;
350
+ }
351
+ else {
352
+ args = {};
353
+ }
354
+ toolCalls.push({
355
+ id: toolCall.id || uuidv4(),
356
+ name: toolCall.function.name,
357
+ arguments: args,
358
+ });
359
+ }
360
+ catch {
361
+ // If parsing fails, use empty object
362
+ toolCalls.push({
363
+ id: toolCall.id || uuidv4(),
364
+ name: toolCall.function.name,
365
+ arguments: {},
366
+ });
367
+ }
368
+ }
369
+ }
370
+ }
371
+ const finishReason = toolCalls.length > 0 ? 'tool_calls' : response.done ? 'stop' : 'length';
372
+ // Extract usage statistics if available
373
+ const evalCount = response.eval_count;
374
+ const promptEvalCount = response.prompt_eval_count;
375
+ return {
376
+ content,
377
+ finishReason,
378
+ toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
379
+ usage: evalCount !== undefined && promptEvalCount !== undefined
380
+ ? {
381
+ promptTokens: promptEvalCount,
382
+ completionTokens: evalCount,
383
+ totalTokens: promptEvalCount + evalCount,
384
+ }
385
+ : undefined,
386
+ };
387
+ }
388
+ catch (err) {
389
+ if (err instanceof ConfigurationError) {
390
+ throw err;
391
+ }
392
+ if (err instanceof Error) {
393
+ // Check if it's a connection error - try to start Ollama automatically
394
+ if (err.message.includes('fetch failed') ||
395
+ err.message.includes('ECONNREFUSED') ||
396
+ err.message.includes('ENOTFOUND')) {
397
+ try {
398
+ // Try to start Ollama automatically
399
+ await OllamaProcessManager.ensureRunning(this.baseUrl);
400
+ // Retry the request
401
+ return this.chat(request);
402
+ }
403
+ catch (startError) {
404
+ if (startError instanceof ConfigurationError) {
405
+ throw startError;
406
+ }
407
+ throw new ConfigurationError(`Cannot connect to Ollama at ${this.baseUrl}. ` +
408
+ `Failed to start service automatically: ${startError instanceof Error
409
+ ? startError.message
410
+ : String(startError)}`);
411
+ }
412
+ }
413
+ throw new Error(`Ollama API error: ${err.message}`);
414
+ }
415
+ throw new Error('Unknown error from Ollama API');
416
+ }
417
+ }
418
+ /**
419
+ * Check if Ollama is running.
420
+ * @param baseUrl - Base URL for Ollama API
421
+ * @returns true if Ollama is accessible
422
+ */
423
+ static async checkConnection(baseUrl = 'http://localhost:11434') {
424
+ try {
425
+ const client = new Ollama({ host: baseUrl });
426
+ await client.list();
427
+ return true;
428
+ }
429
+ catch {
430
+ return false;
431
+ }
432
+ }
433
+ /**
434
+ * Create Ollama provider from config.
435
+ * @param modelNameEnvVar - Environment variable name for model name, or direct model name
436
+ * @param projectRoot - Project root directory
437
+ * @param baseUrl - Optional base URL for Ollama (defaults to http://localhost:11434)
438
+ * @returns Ollama provider instance
439
+ */
440
+ static fromConfig(modelNameEnvVar, projectRoot = process.cwd(), baseUrl) {
441
+ const modelNameCheck = checkEnvVar(modelNameEnvVar, projectRoot);
442
+ if (!modelNameCheck.isSet || !modelNameCheck.value) {
443
+ throw new ConfigurationError(modelNameCheck.errorMessage ||
444
+ `Ollama model name (${modelNameEnvVar}) is not set`);
445
+ }
446
+ return new OllamaProvider(modelNameCheck.value, baseUrl);
447
+ }
448
+ }
449
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * OpenAI LLM provider implementation.
3
+ */
4
+ import type { LLMProvider } from './provider.js';
5
+ import type { LLMRequest, LLMResponse } from './types.js';
6
+ import type { APIKey, ModelName } from '../../types/ids.js';
7
+ /**
8
+ * OpenAI provider implementation.
9
+ */
10
+ export declare class OpenAIProvider implements LLMProvider {
11
+ private client;
12
+ private modelName;
13
+ constructor(apiKey: string, modelName: string);
14
+ getName(): string;
15
+ getModelName(): string;
16
+ supportsToolCalls(): boolean;
17
+ chat(request: LLMRequest): Promise<LLMResponse>;
18
+ /**
19
+ * Create OpenAI provider from config.
20
+ * @param apiKeyEnvVar - Environment variable name for API key
21
+ * @param modelNameEnvVar - Environment variable name for model name
22
+ * @param projectRoot - Project root directory
23
+ * @returns OpenAI provider instance
24
+ */
25
+ static fromConfig(apiKeyEnvVar: APIKey | string, modelNameEnvVar: ModelName | string, projectRoot?: string): OpenAIProvider;
26
+ }
27
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1,170 @@
1
+ /**
2
+ * OpenAI LLM provider implementation.
3
+ */
4
+ import OpenAI from 'openai';
5
+ import { checkEnvVar } from '../../config/env-checker.js';
6
+ import { ConfigurationError } from '../../utils/errors.js';
7
+ /**
8
+ * OpenAI provider implementation.
9
+ */
10
+ export class OpenAIProvider {
11
+ client;
12
+ modelName;
13
+ constructor(apiKey, modelName) {
14
+ if (!apiKey) {
15
+ throw new ConfigurationError('OpenAI API key is required');
16
+ }
17
+ if (!modelName) {
18
+ throw new ConfigurationError('OpenAI model name is required');
19
+ }
20
+ this.client = new OpenAI({
21
+ apiKey,
22
+ });
23
+ this.modelName = modelName;
24
+ }
25
+ getName() {
26
+ return 'OpenAI';
27
+ }
28
+ getModelName() {
29
+ return this.modelName;
30
+ }
31
+ supportsToolCalls() {
32
+ return true;
33
+ }
34
+ async chat(request) {
35
+ try {
36
+ // Convert tools to OpenAI function format
37
+ const functions = request.tools?.map(tool => {
38
+ const schema = tool.inputSchema;
39
+ // Check if schema is empty (no properties or empty properties object)
40
+ let isEmpty = true;
41
+ let schemaObj = null;
42
+ if (schema && typeof schema === 'object' && schema !== null) {
43
+ schemaObj = schema;
44
+ isEmpty =
45
+ schemaObj.type === 'object' &&
46
+ (!schemaObj.properties ||
47
+ (typeof schemaObj.properties === 'object' &&
48
+ schemaObj.properties !== null &&
49
+ Object.keys(schemaObj.properties).length === 0));
50
+ }
51
+ // For OpenAI, omit parameters if schema is empty to avoid validation errors
52
+ const functionDef = {
53
+ name: tool.name,
54
+ description: tool.description,
55
+ };
56
+ if (!isEmpty && schemaObj) {
57
+ functionDef.parameters = schemaObj;
58
+ }
59
+ return functionDef;
60
+ });
61
+ const messages = request.messages.map(msg => ({
62
+ role: msg.role,
63
+ content: msg.content,
64
+ }));
65
+ // Add system prompt if provided
66
+ if (request.systemPrompt) {
67
+ messages.unshift({
68
+ role: 'system',
69
+ content: request.systemPrompt,
70
+ });
71
+ }
72
+ const response = await this.client.chat.completions.create({
73
+ model: this.modelName,
74
+ messages,
75
+ functions,
76
+ temperature: request.temperature ?? 0.7,
77
+ max_tokens: request.maxTokens,
78
+ });
79
+ const choice = response.choices[0];
80
+ if (!choice) {
81
+ throw new Error('No response from OpenAI');
82
+ }
83
+ const content = choice.message.content || '';
84
+ const finishReason = choice.finish_reason;
85
+ // Extract tool calls if present
86
+ const toolCalls = [];
87
+ if (choice.message.function_call) {
88
+ const funcCall = choice.message.function_call;
89
+ try {
90
+ toolCalls.push({
91
+ id: funcCall.name || '',
92
+ name: funcCall.name || '',
93
+ arguments: JSON.parse(funcCall.arguments || '{}'),
94
+ });
95
+ }
96
+ catch {
97
+ // If parsing fails, use empty object
98
+ toolCalls.push({
99
+ id: funcCall.name || '',
100
+ name: funcCall.name || '',
101
+ arguments: {},
102
+ });
103
+ }
104
+ }
105
+ // Handle multiple function calls (newer API)
106
+ if (choice.message.tool_calls) {
107
+ for (const toolCall of choice.message.tool_calls) {
108
+ if (toolCall.type === 'function') {
109
+ try {
110
+ toolCalls.push({
111
+ id: toolCall.id,
112
+ name: toolCall.function.name || '',
113
+ arguments: JSON.parse(toolCall.function.arguments || '{}'),
114
+ });
115
+ }
116
+ catch {
117
+ // If parsing fails, use empty object
118
+ toolCalls.push({
119
+ id: toolCall.id,
120
+ name: toolCall.function.name || '',
121
+ arguments: {},
122
+ });
123
+ }
124
+ }
125
+ }
126
+ }
127
+ return {
128
+ content,
129
+ finishReason,
130
+ toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
131
+ usage: response.usage
132
+ ? {
133
+ promptTokens: response.usage.prompt_tokens,
134
+ completionTokens: response.usage.completion_tokens,
135
+ totalTokens: response.usage.total_tokens,
136
+ }
137
+ : undefined,
138
+ };
139
+ }
140
+ catch (error) {
141
+ if (error instanceof Error) {
142
+ throw new Error(`OpenAI API error: ${error.message}`);
143
+ }
144
+ throw new Error('Unknown error from OpenAI API');
145
+ }
146
+ }
147
+ /**
148
+ * Create OpenAI provider from config.
149
+ * @param apiKeyEnvVar - Environment variable name for API key
150
+ * @param modelNameEnvVar - Environment variable name for model name
151
+ * @param projectRoot - Project root directory
152
+ * @returns OpenAI provider instance
153
+ */
154
+ static fromConfig(apiKeyEnvVar, modelNameEnvVar, projectRoot = process.cwd()) {
155
+ // Check API key
156
+ const apiKeyCheck = checkEnvVar(apiKeyEnvVar, projectRoot);
157
+ if (!apiKeyCheck.isSet || !apiKeyCheck.value) {
158
+ throw new ConfigurationError(apiKeyCheck.errorMessage ||
159
+ `OpenAI API key (${apiKeyEnvVar}) is not set`);
160
+ }
161
+ // Check model name
162
+ const modelNameCheck = checkEnvVar(modelNameEnvVar, projectRoot);
163
+ if (!modelNameCheck.isSet || !modelNameCheck.value) {
164
+ throw new ConfigurationError(modelNameCheck.errorMessage ||
165
+ `OpenAI model name (${modelNameEnvVar}) is not set`);
166
+ }
167
+ return new OpenAIProvider(apiKeyCheck.value, modelNameCheck.value);
168
+ }
169
+ }
170
+ //# sourceMappingURL=openai.js.map