@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,323 @@
1
+ /**
2
+ * Retry logic with exponential backoff.
3
+ */
4
+ import { getLogger } from '../logging/logger.js';
5
+ import { BellwetherError, LLMRateLimitError, isRetryable, wrapError, createTimingContext, } from './types.js';
6
+ import { RETRY_STRATEGIES, CIRCUIT_BREAKER, MATH_FACTORS } from '../constants.js';
7
+ const DEFAULT_OPTIONS = {
8
+ maxAttempts: RETRY_STRATEGIES.DEFAULT.maxAttempts,
9
+ initialDelayMs: RETRY_STRATEGIES.DEFAULT.initialDelayMs,
10
+ maxDelayMs: RETRY_STRATEGIES.DEFAULT.maxDelayMs,
11
+ backoffMultiplier: RETRY_STRATEGIES.DEFAULT.backoffMultiplier,
12
+ jitter: RETRY_STRATEGIES.DEFAULT.jitter,
13
+ };
14
+ /**
15
+ * Calculate delay with exponential backoff and optional jitter.
16
+ */
17
+ function calculateDelay(attempt, initialDelayMs, maxDelayMs, backoffMultiplier, jitter) {
18
+ // Exponential backoff: delay = initial * multiplier^(attempt - 1)
19
+ const exponentialDelay = initialDelayMs * Math.pow(backoffMultiplier, attempt - 1);
20
+ const clampedDelay = Math.min(exponentialDelay, maxDelayMs);
21
+ if (jitter) {
22
+ // Add random jitter: ±25% of the delay
23
+ const jitterRange = clampedDelay * MATH_FACTORS.JITTER_RANGE;
24
+ const jitterAmount = Math.random() * jitterRange * 2 - jitterRange;
25
+ return Math.max(0, clampedDelay + jitterAmount);
26
+ }
27
+ return clampedDelay;
28
+ }
29
+ /**
30
+ * Sleep for the specified duration.
31
+ */
32
+ function sleep(ms) {
33
+ return new Promise((resolve) => setTimeout(resolve, ms));
34
+ }
35
+ /**
36
+ * Execute a function with retry logic.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const result = await withRetry(
41
+ * async () => await llmClient.complete(prompt),
42
+ * { maxAttempts: 3, operation: 'LLM completion' }
43
+ * );
44
+ * ```
45
+ */
46
+ export async function withRetry(fn, options = {}) {
47
+ const { maxAttempts = DEFAULT_OPTIONS.maxAttempts, initialDelayMs = DEFAULT_OPTIONS.initialDelayMs, maxDelayMs = DEFAULT_OPTIONS.maxDelayMs, backoffMultiplier = DEFAULT_OPTIONS.backoffMultiplier, jitter = DEFAULT_OPTIONS.jitter, shouldRetry = isRetryable, onRetry, operation = 'operation', context, } = options;
48
+ const logger = getLogger('retry');
49
+ const startedAt = new Date();
50
+ let lastError;
51
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
52
+ try {
53
+ return await fn();
54
+ }
55
+ catch (error) {
56
+ lastError = error;
57
+ // Check if we should retry
58
+ if (attempt >= maxAttempts || !shouldRetry(error, attempt)) {
59
+ // Wrap and rethrow with context
60
+ const wrappedError = wrapError(error, {
61
+ ...context,
62
+ operation,
63
+ timing: createTimingContext(startedAt),
64
+ retry: {
65
+ attempt,
66
+ maxAttempts,
67
+ },
68
+ });
69
+ logger.warn({
70
+ operation,
71
+ attempt,
72
+ maxAttempts,
73
+ error: wrappedError.toJSON(),
74
+ message: `${operation} failed after ${attempt} attempt(s)`,
75
+ });
76
+ throw wrappedError;
77
+ }
78
+ // Calculate delay for next attempt
79
+ // Use server-provided retry-after if available (from LLMRateLimitError)
80
+ let delayMs;
81
+ if (error instanceof LLMRateLimitError && error.retryAfterMs) {
82
+ // Use server-specified delay, but respect our maxDelayMs cap
83
+ delayMs = Math.min(error.retryAfterMs, maxDelayMs);
84
+ logger.debug({
85
+ operation,
86
+ serverDelayMs: error.retryAfterMs,
87
+ actualDelayMs: delayMs,
88
+ message: `Using server-provided retry delay`,
89
+ });
90
+ }
91
+ else {
92
+ delayMs = calculateDelay(attempt, initialDelayMs, maxDelayMs, backoffMultiplier, jitter);
93
+ }
94
+ // Log retry
95
+ logger.debug({
96
+ operation,
97
+ attempt,
98
+ maxAttempts,
99
+ delayMs: Math.round(delayMs),
100
+ error: error instanceof Error ? error.message : String(error),
101
+ message: `Retrying ${operation} in ${Math.round(delayMs)}ms`,
102
+ });
103
+ // Notify callback
104
+ if (onRetry) {
105
+ onRetry(error, attempt, delayMs);
106
+ }
107
+ // Wait before retry
108
+ await sleep(delayMs);
109
+ }
110
+ }
111
+ // This should never happen, but TypeScript needs it
112
+ throw wrapError(lastError, {
113
+ ...context,
114
+ operation,
115
+ timing: createTimingContext(startedAt),
116
+ retry: { attempt: maxAttempts, maxAttempts },
117
+ });
118
+ }
119
+ /**
120
+ * Create a retry wrapper for a specific operation.
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const retryableFetch = createRetryWrapper({
125
+ * maxAttempts: 5,
126
+ * operation: 'API fetch'
127
+ * });
128
+ *
129
+ * const data = await retryableFetch(() => fetchData());
130
+ * ```
131
+ */
132
+ export function createRetryWrapper(defaultOptions) {
133
+ return (fn, overrides = {}) => {
134
+ return withRetry(fn, { ...defaultOptions, ...overrides });
135
+ };
136
+ }
137
+ /**
138
+ * Retry options specifically tuned for LLM calls.
139
+ */
140
+ export const LLM_RETRY_OPTIONS = {
141
+ maxAttempts: RETRY_STRATEGIES.LLM.maxAttempts,
142
+ initialDelayMs: RETRY_STRATEGIES.LLM.initialDelayMs, // LLM rate limits often need longer waits
143
+ maxDelayMs: RETRY_STRATEGIES.LLM.maxDelayMs,
144
+ backoffMultiplier: RETRY_STRATEGIES.LLM.backoffMultiplier,
145
+ jitter: RETRY_STRATEGIES.LLM.jitter,
146
+ shouldRetry: (error) => {
147
+ // Check for known LLM error patterns
148
+ const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
149
+ // Rate limits - always retry
150
+ if (message.includes('rate limit') || message.includes('429')) {
151
+ return true;
152
+ }
153
+ // Connection issues - retry
154
+ if (message.includes('econnreset') ||
155
+ message.includes('econnrefused') ||
156
+ message.includes('socket hang up') ||
157
+ message.includes('fetch failed')) {
158
+ return true;
159
+ }
160
+ // Timeouts - retry
161
+ if (message.includes('timeout')) {
162
+ return true;
163
+ }
164
+ // Server errors (5xx) - retry
165
+ if (message.includes('500') || message.includes('502') || message.includes('503')) {
166
+ return true;
167
+ }
168
+ // Auth errors - don't retry
169
+ if (message.includes('401') || message.includes('unauthorized') || message.includes('api key')) {
170
+ return false;
171
+ }
172
+ // Quota errors - don't retry
173
+ if (message.includes('quota') || message.includes('insufficient') || message.includes('credit')) {
174
+ return false;
175
+ }
176
+ // Default: use standard isRetryable
177
+ return isRetryable(error);
178
+ },
179
+ };
180
+ /**
181
+ * Retry options for MCP transport operations.
182
+ */
183
+ export const TRANSPORT_RETRY_OPTIONS = {
184
+ maxAttempts: RETRY_STRATEGIES.TRANSPORT.maxAttempts, // Transport failures are often persistent
185
+ initialDelayMs: RETRY_STRATEGIES.TRANSPORT.initialDelayMs,
186
+ maxDelayMs: RETRY_STRATEGIES.TRANSPORT.maxDelayMs,
187
+ backoffMultiplier: RETRY_STRATEGIES.TRANSPORT.backoffMultiplier,
188
+ jitter: RETRY_STRATEGIES.TRANSPORT.jitter,
189
+ shouldRetry: (error) => {
190
+ const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
191
+ // Timeouts might be transient
192
+ if (message.includes('timeout')) {
193
+ return true;
194
+ }
195
+ // Connection resets might recover
196
+ if (message.includes('econnreset')) {
197
+ return true;
198
+ }
199
+ // Protocol errors are permanent
200
+ if (message.includes('protocol') || message.includes('parse')) {
201
+ return false;
202
+ }
203
+ // Server exit is permanent
204
+ if (message.includes('exit') || message.includes('closed')) {
205
+ return false;
206
+ }
207
+ return isRetryable(error);
208
+ },
209
+ };
210
+ /**
211
+ * Retry options for tool calls during interviews.
212
+ */
213
+ export const TOOL_CALL_RETRY_OPTIONS = {
214
+ maxAttempts: RETRY_STRATEGIES.TOOL_CALL.maxAttempts, // Tool failures are often deterministic
215
+ initialDelayMs: RETRY_STRATEGIES.TOOL_CALL.initialDelayMs,
216
+ maxDelayMs: RETRY_STRATEGIES.TOOL_CALL.maxDelayMs,
217
+ backoffMultiplier: RETRY_STRATEGIES.TOOL_CALL.backoffMultiplier,
218
+ jitter: RETRY_STRATEGIES.TOOL_CALL.jitter,
219
+ shouldRetry: (error) => {
220
+ const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
221
+ // Timeout - might succeed on retry
222
+ if (message.includes('timeout')) {
223
+ return true;
224
+ }
225
+ // Most tool errors are deterministic - don't retry
226
+ return false;
227
+ },
228
+ };
229
+ const DEFAULT_CIRCUIT_OPTIONS = {
230
+ failureThreshold: CIRCUIT_BREAKER.FAILURE_THRESHOLD,
231
+ resetTimeMs: CIRCUIT_BREAKER.RESET_TIME_MS,
232
+ failureWindowMs: CIRCUIT_BREAKER.FAILURE_WINDOW_MS,
233
+ };
234
+ /**
235
+ * Create a circuit breaker for an operation.
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * const protectedCall = createCircuitBreaker('llm-api');
240
+ *
241
+ * try {
242
+ * const result = await protectedCall(() => llmClient.complete(prompt));
243
+ * } catch (error) {
244
+ * // Either operation error or circuit open error
245
+ * }
246
+ * ```
247
+ */
248
+ export function createCircuitBreaker(name, options = {}) {
249
+ const { failureThreshold = DEFAULT_CIRCUIT_OPTIONS.failureThreshold, resetTimeMs = DEFAULT_CIRCUIT_OPTIONS.resetTimeMs, failureWindowMs = DEFAULT_CIRCUIT_OPTIONS.failureWindowMs, } = options;
250
+ const state = {
251
+ failures: 0,
252
+ isOpen: false,
253
+ };
254
+ const logger = getLogger('circuit-breaker');
255
+ return async (fn) => {
256
+ // Check if circuit is open
257
+ if (state.isOpen) {
258
+ const now = new Date();
259
+ const timeSinceOpen = state.openedAt
260
+ ? now.getTime() - state.openedAt.getTime()
261
+ : 0;
262
+ if (timeSinceOpen < resetTimeMs) {
263
+ // Still in open state
264
+ throw new BellwetherError(`Circuit breaker '${name}' is open`, {
265
+ code: 'CIRCUIT_BREAKER_OPEN',
266
+ severity: 'high',
267
+ retryable: 'retryable',
268
+ context: {
269
+ metadata: {
270
+ name,
271
+ failures: state.failures,
272
+ openedAt: state.openedAt?.toISOString(),
273
+ timeUntilReset: resetTimeMs - timeSinceOpen,
274
+ },
275
+ },
276
+ });
277
+ }
278
+ // Half-open: try one request
279
+ logger.info({
280
+ circuitBreaker: name,
281
+ message: `Circuit breaker '${name}' attempting half-open test`,
282
+ });
283
+ }
284
+ try {
285
+ const result = await fn();
286
+ // Success: reset state
287
+ if (state.isOpen) {
288
+ logger.info({
289
+ circuitBreaker: name,
290
+ message: `Circuit breaker '${name}' closed after successful test`,
291
+ });
292
+ }
293
+ state.failures = 0;
294
+ state.isOpen = false;
295
+ state.openedAt = undefined;
296
+ return result;
297
+ }
298
+ catch (error) {
299
+ const now = new Date();
300
+ // Reset failure count if outside window
301
+ if (state.lastFailure) {
302
+ const timeSinceLastFailure = now.getTime() - state.lastFailure.getTime();
303
+ if (timeSinceLastFailure > failureWindowMs) {
304
+ state.failures = 0;
305
+ }
306
+ }
307
+ state.failures++;
308
+ state.lastFailure = now;
309
+ // Check if we should open the circuit
310
+ if (state.failures >= failureThreshold && !state.isOpen) {
311
+ state.isOpen = true;
312
+ state.openedAt = now;
313
+ logger.warn({
314
+ circuitBreaker: name,
315
+ failures: state.failures,
316
+ message: `Circuit breaker '${name}' opened after ${state.failures} failures`,
317
+ });
318
+ }
319
+ throw error;
320
+ }
321
+ };
322
+ }
323
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Comprehensive error types for Bellwether.
3
+ *
4
+ * Error hierarchy:
5
+ * - BellwetherError (base)
6
+ * - TransportError (MCP communication)
7
+ * - LLMError (LLM provider issues)
8
+ * - InterviewError (interview execution)
9
+ * - WorkflowError (workflow execution)
10
+ * - ConfigError (configuration issues)
11
+ */
12
+ /**
13
+ * Error severity levels.
14
+ */
15
+ export type ErrorSeverity = 'low' | 'medium' | 'high' | 'critical';
16
+ /**
17
+ * Whether an error is retryable.
18
+ */
19
+ export type RetryableStatus = 'retryable' | 'terminal' | 'unknown';
20
+ /**
21
+ * Error context for debugging and recovery.
22
+ */
23
+ export interface ErrorContext {
24
+ /** Operation that failed */
25
+ operation?: string;
26
+ /** Component where error occurred */
27
+ component?: string;
28
+ /** Tool name if applicable */
29
+ tool?: string;
30
+ /** Workflow ID if applicable */
31
+ workflow?: string;
32
+ /** Step index if applicable */
33
+ stepIndex?: number;
34
+ /** Request ID for tracing */
35
+ requestId?: string;
36
+ /** Timing information */
37
+ timing?: {
38
+ startedAt: Date;
39
+ failedAt: Date;
40
+ durationMs: number;
41
+ };
42
+ /** Retry information */
43
+ retry?: {
44
+ attempt: number;
45
+ maxAttempts: number;
46
+ nextDelayMs?: number;
47
+ };
48
+ /** Additional metadata */
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ /**
52
+ * Base error class for all Bellwether errors.
53
+ */
54
+ export declare class BellwetherError extends Error {
55
+ /** Error code for programmatic handling */
56
+ readonly code: string;
57
+ /** Error severity */
58
+ readonly severity: ErrorSeverity;
59
+ /** Whether this error is retryable */
60
+ readonly retryable: RetryableStatus;
61
+ /** Error context for debugging */
62
+ readonly context: ErrorContext;
63
+ /** Original error if this wraps another */
64
+ readonly cause?: Error;
65
+ constructor(message: string, options: {
66
+ code: string;
67
+ severity?: ErrorSeverity;
68
+ retryable?: RetryableStatus;
69
+ context?: ErrorContext;
70
+ cause?: Error;
71
+ });
72
+ /**
73
+ * Create a new error with additional context.
74
+ */
75
+ withContext(additionalContext: Partial<ErrorContext>): BellwetherError;
76
+ /**
77
+ * Convert to JSON for logging.
78
+ */
79
+ toJSON(): Record<string, unknown>;
80
+ }
81
+ /**
82
+ * Base class for transport-related errors.
83
+ */
84
+ export declare class TransportError extends BellwetherError {
85
+ constructor(message: string, options: {
86
+ code: string;
87
+ severity?: ErrorSeverity;
88
+ retryable?: RetryableStatus;
89
+ context?: ErrorContext;
90
+ cause?: Error;
91
+ });
92
+ }
93
+ /**
94
+ * Connection failed or was lost.
95
+ */
96
+ export declare class ConnectionError extends TransportError {
97
+ constructor(message: string, context?: ErrorContext, cause?: Error);
98
+ }
99
+ /**
100
+ * Request timed out.
101
+ */
102
+ export declare class TimeoutError extends TransportError {
103
+ /** Timeout value in milliseconds */
104
+ readonly timeoutMs: number;
105
+ constructor(message: string, timeoutMs: number, context?: ErrorContext, cause?: Error);
106
+ }
107
+ /**
108
+ * Server process exited unexpectedly.
109
+ */
110
+ export declare class ServerExitError extends TransportError {
111
+ /** Exit code if available */
112
+ readonly exitCode?: number;
113
+ /** Exit signal if available */
114
+ readonly signal?: string;
115
+ constructor(message: string, exitCode?: number, signal?: string, context?: ErrorContext);
116
+ }
117
+ /**
118
+ * Protocol error (invalid message format, etc).
119
+ */
120
+ export declare class ProtocolError extends TransportError {
121
+ constructor(message: string, context?: ErrorContext, cause?: Error);
122
+ }
123
+ /**
124
+ * Buffer overflow during message processing.
125
+ */
126
+ export declare class BufferOverflowError extends TransportError {
127
+ /** Current buffer size */
128
+ readonly bufferSize: number;
129
+ /** Maximum allowed size */
130
+ readonly maxSize: number;
131
+ constructor(bufferSize: number, maxSize: number, context?: ErrorContext);
132
+ }
133
+ /**
134
+ * Base class for LLM-related errors.
135
+ */
136
+ export declare class LLMError extends BellwetherError {
137
+ /** LLM provider name */
138
+ readonly provider: string;
139
+ /** Model name if available */
140
+ readonly model?: string;
141
+ constructor(message: string, provider: string, options: {
142
+ code: string;
143
+ model?: string;
144
+ severity?: ErrorSeverity;
145
+ retryable?: RetryableStatus;
146
+ context?: ErrorContext;
147
+ cause?: Error;
148
+ });
149
+ }
150
+ /**
151
+ * Authentication/API key error.
152
+ */
153
+ export declare class LLMAuthError extends LLMError {
154
+ constructor(provider: string, model?: string, context?: ErrorContext, cause?: Error);
155
+ }
156
+ /**
157
+ * Rate limit exceeded.
158
+ */
159
+ export declare class LLMRateLimitError extends LLMError {
160
+ /** Retry after in milliseconds if known */
161
+ readonly retryAfterMs?: number;
162
+ constructor(provider: string, retryAfterMs?: number, model?: string, context?: ErrorContext, cause?: Error);
163
+ }
164
+ /**
165
+ * Quota/credits exhausted.
166
+ */
167
+ export declare class LLMQuotaError extends LLMError {
168
+ constructor(provider: string, model?: string, context?: ErrorContext, cause?: Error);
169
+ }
170
+ /**
171
+ * Model refused to complete request (content policy, etc).
172
+ */
173
+ export declare class LLMRefusalError extends LLMError {
174
+ /** Refusal reason if available */
175
+ readonly reason?: string;
176
+ constructor(provider: string, reason?: string, model?: string, context?: ErrorContext, cause?: Error);
177
+ }
178
+ /**
179
+ * LLM response parsing failed.
180
+ */
181
+ export declare class LLMParseError extends LLMError {
182
+ /** Raw response that couldn't be parsed */
183
+ readonly rawResponse?: string;
184
+ constructor(provider: string, rawResponse?: string, model?: string, context?: ErrorContext, cause?: Error);
185
+ }
186
+ /**
187
+ * LLM connection failed.
188
+ */
189
+ export declare class LLMConnectionError extends LLMError {
190
+ constructor(provider: string, model?: string, context?: ErrorContext, cause?: Error);
191
+ }
192
+ /**
193
+ * Base class for interview-related errors.
194
+ */
195
+ export declare class InterviewError extends BellwetherError {
196
+ constructor(message: string, options: {
197
+ code: string;
198
+ severity?: ErrorSeverity;
199
+ retryable?: RetryableStatus;
200
+ context?: ErrorContext;
201
+ cause?: Error;
202
+ });
203
+ }
204
+ /**
205
+ * Tool call failed.
206
+ */
207
+ export declare class ToolCallError extends InterviewError {
208
+ /** Tool name */
209
+ readonly toolName: string;
210
+ /** Arguments passed to tool */
211
+ readonly args: Record<string, unknown>;
212
+ constructor(toolName: string, args: Record<string, unknown>, message: string, context?: ErrorContext, cause?: Error);
213
+ }
214
+ /**
215
+ * Discovery failed.
216
+ */
217
+ export declare class DiscoveryError extends InterviewError {
218
+ constructor(message: string, context?: ErrorContext, cause?: Error);
219
+ }
220
+ /**
221
+ * Question generation failed.
222
+ */
223
+ export declare class QuestionGenerationError extends InterviewError {
224
+ constructor(toolName: string, context?: ErrorContext, cause?: Error);
225
+ }
226
+ /**
227
+ * Analysis/synthesis failed.
228
+ */
229
+ export declare class AnalysisError extends InterviewError {
230
+ constructor(phase: 'response' | 'profile' | 'summary', context?: ErrorContext, cause?: Error);
231
+ }
232
+ /**
233
+ * Base class for workflow-related errors.
234
+ */
235
+ export declare class WorkflowError extends BellwetherError {
236
+ /** Workflow ID */
237
+ readonly workflowId: string;
238
+ /** Workflow name */
239
+ readonly workflowName?: string;
240
+ constructor(message: string, workflowId: string, options: {
241
+ code: string;
242
+ workflowName?: string;
243
+ severity?: ErrorSeverity;
244
+ retryable?: RetryableStatus;
245
+ context?: ErrorContext;
246
+ cause?: Error;
247
+ });
248
+ }
249
+ /**
250
+ * Workflow step failed.
251
+ */
252
+ export declare class WorkflowStepError extends WorkflowError {
253
+ /** Step index (0-based) */
254
+ readonly stepIndex: number;
255
+ /** Tool name for this step */
256
+ readonly toolName: string;
257
+ constructor(workflowId: string, stepIndex: number, toolName: string, message: string, workflowName?: string, context?: ErrorContext, cause?: Error);
258
+ }
259
+ /**
260
+ * Argument resolution failed (JSON path evaluation).
261
+ */
262
+ export declare class ArgResolutionError extends WorkflowError {
263
+ /** The path expression that failed */
264
+ readonly pathExpression: string;
265
+ /** Step index where resolution failed */
266
+ readonly stepIndex: number;
267
+ constructor(workflowId: string, stepIndex: number, pathExpression: string, message: string, workflowName?: string, context?: ErrorContext);
268
+ }
269
+ /**
270
+ * Assertion failed during workflow execution.
271
+ */
272
+ export declare class AssertionError extends WorkflowError {
273
+ /** The assertion that failed */
274
+ readonly assertion: string;
275
+ /** Actual value received */
276
+ readonly actualValue?: unknown;
277
+ constructor(workflowId: string, stepIndex: number, assertion: string, actualValue?: unknown, workflowName?: string, context?: ErrorContext);
278
+ }
279
+ /**
280
+ * Configuration-related error.
281
+ */
282
+ export declare class ConfigError extends BellwetherError {
283
+ constructor(message: string, context?: ErrorContext, cause?: Error);
284
+ }
285
+ /**
286
+ * Configuration file not found.
287
+ */
288
+ export declare class ConfigNotFoundError extends ConfigError {
289
+ /** Path that was searched */
290
+ readonly path: string;
291
+ constructor(path: string, context?: ErrorContext);
292
+ }
293
+ /**
294
+ * Configuration validation failed.
295
+ */
296
+ export declare class ConfigValidationError extends ConfigError {
297
+ /** Validation errors */
298
+ readonly validationErrors: string[];
299
+ constructor(errors: string[], context?: ErrorContext);
300
+ }
301
+ /**
302
+ * Check if an error is a BellwetherError.
303
+ */
304
+ export declare function isBellwetherError(error: unknown): error is BellwetherError;
305
+ /**
306
+ * Check if an error is retryable.
307
+ */
308
+ export declare function isRetryable(error: unknown): boolean;
309
+ /**
310
+ * Wrap an unknown error in a BellwetherError.
311
+ */
312
+ export declare function wrapError(error: unknown, context?: ErrorContext): BellwetherError;
313
+ /**
314
+ * Extract error message from any error type.
315
+ */
316
+ export declare function getErrorMessage(error: unknown): string;
317
+ /**
318
+ * Create timing context for error tracking.
319
+ */
320
+ export declare function createTimingContext(startedAt: Date): ErrorContext['timing'];
321
+ //# sourceMappingURL=types.d.ts.map