@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.
- package/CHANGELOG.md +291 -0
- package/LICENSE +21 -0
- package/README.md +739 -0
- package/dist/auth/credentials.d.ts +64 -0
- package/dist/auth/credentials.js +218 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/keychain.d.ts +64 -0
- package/dist/auth/keychain.js +268 -0
- package/dist/baseline/ab-testing.d.ts +80 -0
- package/dist/baseline/ab-testing.js +236 -0
- package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
- package/dist/baseline/ai-compatibility-scorer.js +606 -0
- package/dist/baseline/calibration.d.ts +77 -0
- package/dist/baseline/calibration.js +136 -0
- package/dist/baseline/category-matching.d.ts +85 -0
- package/dist/baseline/category-matching.js +289 -0
- package/dist/baseline/change-impact-analyzer.d.ts +98 -0
- package/dist/baseline/change-impact-analyzer.js +592 -0
- package/dist/baseline/comparator.d.ts +64 -0
- package/dist/baseline/comparator.js +916 -0
- package/dist/baseline/confidence.d.ts +55 -0
- package/dist/baseline/confidence.js +122 -0
- package/dist/baseline/converter.d.ts +61 -0
- package/dist/baseline/converter.js +585 -0
- package/dist/baseline/dependency-analyzer.d.ts +89 -0
- package/dist/baseline/dependency-analyzer.js +567 -0
- package/dist/baseline/deprecation-tracker.d.ts +133 -0
- package/dist/baseline/deprecation-tracker.js +322 -0
- package/dist/baseline/diff.d.ts +55 -0
- package/dist/baseline/diff.js +1584 -0
- package/dist/baseline/documentation-scorer.d.ts +205 -0
- package/dist/baseline/documentation-scorer.js +466 -0
- package/dist/baseline/embeddings.d.ts +118 -0
- package/dist/baseline/embeddings.js +251 -0
- package/dist/baseline/error-analyzer.d.ts +198 -0
- package/dist/baseline/error-analyzer.js +721 -0
- package/dist/baseline/evaluation/evaluator.d.ts +42 -0
- package/dist/baseline/evaluation/evaluator.js +323 -0
- package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
- package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
- package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
- package/dist/baseline/evaluation/golden-dataset.js +717 -0
- package/dist/baseline/evaluation/index.d.ts +15 -0
- package/dist/baseline/evaluation/index.js +15 -0
- package/dist/baseline/evaluation/types.d.ts +186 -0
- package/dist/baseline/evaluation/types.js +8 -0
- package/dist/baseline/external-dependency-detector.d.ts +181 -0
- package/dist/baseline/external-dependency-detector.js +524 -0
- package/dist/baseline/golden-output.d.ts +162 -0
- package/dist/baseline/golden-output.js +636 -0
- package/dist/baseline/health-scorer.d.ts +174 -0
- package/dist/baseline/health-scorer.js +451 -0
- package/dist/baseline/incremental-checker.d.ts +97 -0
- package/dist/baseline/incremental-checker.js +174 -0
- package/dist/baseline/index.d.ts +31 -0
- package/dist/baseline/index.js +42 -0
- package/dist/baseline/migration-generator.d.ts +137 -0
- package/dist/baseline/migration-generator.js +554 -0
- package/dist/baseline/migrations.d.ts +60 -0
- package/dist/baseline/migrations.js +197 -0
- package/dist/baseline/performance-tracker.d.ts +214 -0
- package/dist/baseline/performance-tracker.js +577 -0
- package/dist/baseline/pr-comment-generator.d.ts +117 -0
- package/dist/baseline/pr-comment-generator.js +546 -0
- package/dist/baseline/response-fingerprint.d.ts +127 -0
- package/dist/baseline/response-fingerprint.js +728 -0
- package/dist/baseline/response-schema-tracker.d.ts +129 -0
- package/dist/baseline/response-schema-tracker.js +420 -0
- package/dist/baseline/risk-scorer.d.ts +54 -0
- package/dist/baseline/risk-scorer.js +434 -0
- package/dist/baseline/saver.d.ts +89 -0
- package/dist/baseline/saver.js +554 -0
- package/dist/baseline/scenario-generator.d.ts +151 -0
- package/dist/baseline/scenario-generator.js +905 -0
- package/dist/baseline/schema-compare.d.ts +86 -0
- package/dist/baseline/schema-compare.js +557 -0
- package/dist/baseline/schema-evolution.d.ts +189 -0
- package/dist/baseline/schema-evolution.js +467 -0
- package/dist/baseline/semantic.d.ts +203 -0
- package/dist/baseline/semantic.js +908 -0
- package/dist/baseline/synonyms.d.ts +60 -0
- package/dist/baseline/synonyms.js +386 -0
- package/dist/baseline/telemetry.d.ts +165 -0
- package/dist/baseline/telemetry.js +294 -0
- package/dist/baseline/test-pruner.d.ts +120 -0
- package/dist/baseline/test-pruner.js +387 -0
- package/dist/baseline/types.d.ts +449 -0
- package/dist/baseline/types.js +5 -0
- package/dist/baseline/version.d.ts +138 -0
- package/dist/baseline/version.js +206 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/response-cache.d.ts +151 -0
- package/dist/cache/response-cache.js +287 -0
- package/dist/ci/index.d.ts +60 -0
- package/dist/ci/index.js +342 -0
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.js +352 -0
- package/dist/cli/commands/badge.d.ts +3 -0
- package/dist/cli/commands/badge.js +74 -0
- package/dist/cli/commands/baseline-accept.d.ts +15 -0
- package/dist/cli/commands/baseline-accept.js +178 -0
- package/dist/cli/commands/baseline-migrate.d.ts +12 -0
- package/dist/cli/commands/baseline-migrate.js +164 -0
- package/dist/cli/commands/baseline.d.ts +14 -0
- package/dist/cli/commands/baseline.js +449 -0
- package/dist/cli/commands/beta.d.ts +10 -0
- package/dist/cli/commands/beta.js +231 -0
- package/dist/cli/commands/check.d.ts +11 -0
- package/dist/cli/commands/check.js +820 -0
- package/dist/cli/commands/cloud/badge.d.ts +3 -0
- package/dist/cli/commands/cloud/badge.js +74 -0
- package/dist/cli/commands/cloud/diff.d.ts +6 -0
- package/dist/cli/commands/cloud/diff.js +79 -0
- package/dist/cli/commands/cloud/history.d.ts +6 -0
- package/dist/cli/commands/cloud/history.js +102 -0
- package/dist/cli/commands/cloud/link.d.ts +9 -0
- package/dist/cli/commands/cloud/link.js +119 -0
- package/dist/cli/commands/cloud/login.d.ts +7 -0
- package/dist/cli/commands/cloud/login.js +499 -0
- package/dist/cli/commands/cloud/projects.d.ts +6 -0
- package/dist/cli/commands/cloud/projects.js +44 -0
- package/dist/cli/commands/cloud/shared.d.ts +7 -0
- package/dist/cli/commands/cloud/shared.js +42 -0
- package/dist/cli/commands/cloud/teams.d.ts +8 -0
- package/dist/cli/commands/cloud/teams.js +169 -0
- package/dist/cli/commands/cloud/upload.d.ts +8 -0
- package/dist/cli/commands/cloud/upload.js +181 -0
- package/dist/cli/commands/contract.d.ts +11 -0
- package/dist/cli/commands/contract.js +280 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.js +82 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.js +187 -0
- package/dist/cli/commands/explore.d.ts +11 -0
- package/dist/cli/commands/explore.js +437 -0
- package/dist/cli/commands/feedback.d.ts +9 -0
- package/dist/cli/commands/feedback.js +174 -0
- package/dist/cli/commands/golden.d.ts +12 -0
- package/dist/cli/commands/golden.js +407 -0
- package/dist/cli/commands/history.d.ts +10 -0
- package/dist/cli/commands/history.js +202 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +219 -0
- package/dist/cli/commands/interview.d.ts +3 -0
- package/dist/cli/commands/interview.js +903 -0
- package/dist/cli/commands/link.d.ts +10 -0
- package/dist/cli/commands/link.js +169 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +499 -0
- package/dist/cli/commands/preset.d.ts +33 -0
- package/dist/cli/commands/preset.js +297 -0
- package/dist/cli/commands/profile.d.ts +33 -0
- package/dist/cli/commands/profile.js +286 -0
- package/dist/cli/commands/registry.d.ts +11 -0
- package/dist/cli/commands/registry.js +146 -0
- package/dist/cli/commands/shared.d.ts +79 -0
- package/dist/cli/commands/shared.js +196 -0
- package/dist/cli/commands/teams.d.ts +8 -0
- package/dist/cli/commands/teams.js +169 -0
- package/dist/cli/commands/test.d.ts +9 -0
- package/dist/cli/commands/test.js +500 -0
- package/dist/cli/commands/upload.d.ts +8 -0
- package/dist/cli/commands/upload.js +223 -0
- package/dist/cli/commands/validate-config.d.ts +6 -0
- package/dist/cli/commands/validate-config.js +35 -0
- package/dist/cli/commands/verify.d.ts +11 -0
- package/dist/cli/commands/verify.js +283 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.js +253 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +178 -0
- package/dist/cli/interactive.d.ts +47 -0
- package/dist/cli/interactive.js +216 -0
- package/dist/cli/output/terminal-reporter.d.ts +19 -0
- package/dist/cli/output/terminal-reporter.js +104 -0
- package/dist/cli/output.d.ts +226 -0
- package/dist/cli/output.js +438 -0
- package/dist/cli/utils/env.d.ts +5 -0
- package/dist/cli/utils/env.js +14 -0
- package/dist/cli/utils/progress.d.ts +59 -0
- package/dist/cli/utils/progress.js +206 -0
- package/dist/cli/utils/server-context.d.ts +10 -0
- package/dist/cli/utils/server-context.js +36 -0
- package/dist/cloud/auth.d.ts +144 -0
- package/dist/cloud/auth.js +374 -0
- package/dist/cloud/client.d.ts +24 -0
- package/dist/cloud/client.js +65 -0
- package/dist/cloud/http-client.d.ts +38 -0
- package/dist/cloud/http-client.js +215 -0
- package/dist/cloud/index.d.ts +23 -0
- package/dist/cloud/index.js +25 -0
- package/dist/cloud/mock-client.d.ts +107 -0
- package/dist/cloud/mock-client.js +545 -0
- package/dist/cloud/types.d.ts +515 -0
- package/dist/cloud/types.js +15 -0
- package/dist/config/defaults.d.ts +160 -0
- package/dist/config/defaults.js +169 -0
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.js +122 -0
- package/dist/config/template.d.ts +42 -0
- package/dist/config/template.js +647 -0
- package/dist/config/validator.d.ts +2112 -0
- package/dist/config/validator.js +658 -0
- package/dist/constants/cloud.d.ts +107 -0
- package/dist/constants/cloud.js +110 -0
- package/dist/constants/core.d.ts +521 -0
- package/dist/constants/core.js +556 -0
- package/dist/constants/testing.d.ts +1283 -0
- package/dist/constants/testing.js +1568 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/contract/index.js +5 -0
- package/dist/contract/validator.d.ts +177 -0
- package/dist/contract/validator.js +574 -0
- package/dist/cost/index.d.ts +6 -0
- package/dist/cost/index.js +5 -0
- package/dist/cost/tracker.d.ts +134 -0
- package/dist/cost/tracker.js +313 -0
- package/dist/discovery/discovery.d.ts +16 -0
- package/dist/discovery/discovery.js +173 -0
- package/dist/discovery/types.d.ts +51 -0
- package/dist/discovery/types.js +2 -0
- package/dist/docs/agents.d.ts +3 -0
- package/dist/docs/agents.js +995 -0
- package/dist/docs/contract.d.ts +51 -0
- package/dist/docs/contract.js +1681 -0
- package/dist/docs/generator.d.ts +4 -0
- package/dist/docs/generator.js +4 -0
- package/dist/docs/html-reporter.d.ts +9 -0
- package/dist/docs/html-reporter.js +757 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +11 -0
- package/dist/docs/junit-reporter.d.ts +18 -0
- package/dist/docs/junit-reporter.js +210 -0
- package/dist/docs/report.d.ts +14 -0
- package/dist/docs/report.js +44 -0
- package/dist/docs/sarif-reporter.d.ts +19 -0
- package/dist/docs/sarif-reporter.js +335 -0
- package/dist/docs/shared.d.ts +35 -0
- package/dist/docs/shared.js +162 -0
- package/dist/docs/templates.d.ts +12 -0
- package/dist/docs/templates.js +76 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/retry.d.ts +92 -0
- package/dist/errors/retry.js +323 -0
- package/dist/errors/types.d.ts +321 -0
- package/dist/errors/types.js +584 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/interview/dependency-resolver.d.ts +11 -0
- package/dist/interview/dependency-resolver.js +32 -0
- package/dist/interview/interviewer.d.ts +232 -0
- package/dist/interview/interviewer.js +1939 -0
- package/dist/interview/mock-response-generator.d.ts +7 -0
- package/dist/interview/mock-response-generator.js +102 -0
- package/dist/interview/orchestrator.d.ts +237 -0
- package/dist/interview/orchestrator.js +1296 -0
- package/dist/interview/rate-limiter.d.ts +15 -0
- package/dist/interview/rate-limiter.js +55 -0
- package/dist/interview/response-validator.d.ts +10 -0
- package/dist/interview/response-validator.js +132 -0
- package/dist/interview/schema-inferrer.d.ts +8 -0
- package/dist/interview/schema-inferrer.js +71 -0
- package/dist/interview/schema-test-generator.d.ts +71 -0
- package/dist/interview/schema-test-generator.js +834 -0
- package/dist/interview/smart-value-generator.d.ts +155 -0
- package/dist/interview/smart-value-generator.js +554 -0
- package/dist/interview/stateful-test-runner.d.ts +19 -0
- package/dist/interview/stateful-test-runner.js +106 -0
- package/dist/interview/types.d.ts +561 -0
- package/dist/interview/types.js +2 -0
- package/dist/llm/anthropic.d.ts +41 -0
- package/dist/llm/anthropic.js +355 -0
- package/dist/llm/client.d.ts +123 -0
- package/dist/llm/client.js +42 -0
- package/dist/llm/factory.d.ts +38 -0
- package/dist/llm/factory.js +145 -0
- package/dist/llm/fallback.d.ts +140 -0
- package/dist/llm/fallback.js +379 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.js +15 -0
- package/dist/llm/ollama.d.ts +37 -0
- package/dist/llm/ollama.js +330 -0
- package/dist/llm/openai.d.ts +25 -0
- package/dist/llm/openai.js +320 -0
- package/dist/llm/token-budget.d.ts +161 -0
- package/dist/llm/token-budget.js +395 -0
- package/dist/logging/logger.d.ts +70 -0
- package/dist/logging/logger.js +130 -0
- package/dist/metrics/collector.d.ts +106 -0
- package/dist/metrics/collector.js +547 -0
- package/dist/metrics/index.d.ts +7 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/prometheus.d.ts +20 -0
- package/dist/metrics/prometheus.js +241 -0
- package/dist/metrics/types.d.ts +209 -0
- package/dist/metrics/types.js +5 -0
- package/dist/persona/builtins.d.ts +54 -0
- package/dist/persona/builtins.js +219 -0
- package/dist/persona/index.d.ts +8 -0
- package/dist/persona/index.js +8 -0
- package/dist/persona/loader.d.ts +30 -0
- package/dist/persona/loader.js +190 -0
- package/dist/persona/types.d.ts +144 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/validation.d.ts +94 -0
- package/dist/persona/validation.js +332 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/templates.d.ts +180 -0
- package/dist/prompts/templates.js +431 -0
- package/dist/registry/client.d.ts +49 -0
- package/dist/registry/client.js +191 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/types.d.ts +140 -0
- package/dist/registry/types.js +6 -0
- package/dist/scenarios/evaluator.d.ts +43 -0
- package/dist/scenarios/evaluator.js +206 -0
- package/dist/scenarios/index.d.ts +10 -0
- package/dist/scenarios/index.js +9 -0
- package/dist/scenarios/loader.d.ts +20 -0
- package/dist/scenarios/loader.js +285 -0
- package/dist/scenarios/types.d.ts +153 -0
- package/dist/scenarios/types.js +8 -0
- package/dist/security/index.d.ts +17 -0
- package/dist/security/index.js +18 -0
- package/dist/security/payloads.d.ts +61 -0
- package/dist/security/payloads.js +268 -0
- package/dist/security/security-tester.d.ts +42 -0
- package/dist/security/security-tester.js +582 -0
- package/dist/security/types.d.ts +166 -0
- package/dist/security/types.js +8 -0
- package/dist/transport/base-transport.d.ts +59 -0
- package/dist/transport/base-transport.js +38 -0
- package/dist/transport/http-transport.d.ts +67 -0
- package/dist/transport/http-transport.js +238 -0
- package/dist/transport/mcp-client.d.ts +141 -0
- package/dist/transport/mcp-client.js +496 -0
- package/dist/transport/sse-transport.d.ts +88 -0
- package/dist/transport/sse-transport.js +316 -0
- package/dist/transport/stdio-transport.d.ts +43 -0
- package/dist/transport/stdio-transport.js +238 -0
- package/dist/transport/types.d.ts +125 -0
- package/dist/transport/types.js +16 -0
- package/dist/utils/concurrency.d.ts +123 -0
- package/dist/utils/concurrency.js +213 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +37 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jsonpath.d.ts +87 -0
- package/dist/utils/jsonpath.js +326 -0
- package/dist/utils/markdown.d.ts +113 -0
- package/dist/utils/markdown.js +265 -0
- package/dist/utils/network.d.ts +14 -0
- package/dist/utils/network.js +17 -0
- package/dist/utils/sanitize.d.ts +92 -0
- package/dist/utils/sanitize.js +191 -0
- package/dist/utils/semantic.d.ts +194 -0
- package/dist/utils/semantic.js +1051 -0
- package/dist/utils/smart-truncate.d.ts +94 -0
- package/dist/utils/smart-truncate.js +361 -0
- package/dist/utils/timeout.d.ts +153 -0
- package/dist/utils/timeout.js +205 -0
- package/dist/utils/yaml-parser.d.ts +58 -0
- package/dist/utils/yaml-parser.js +86 -0
- package/dist/validation/index.d.ts +32 -0
- package/dist/validation/index.js +32 -0
- package/dist/validation/semantic-test-generator.d.ts +50 -0
- package/dist/validation/semantic-test-generator.js +176 -0
- package/dist/validation/semantic-types.d.ts +66 -0
- package/dist/validation/semantic-types.js +94 -0
- package/dist/validation/semantic-validator.d.ts +38 -0
- package/dist/validation/semantic-validator.js +340 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.js +5 -0
- package/dist/verification/types.d.ts +133 -0
- package/dist/verification/types.js +5 -0
- package/dist/verification/verifier.d.ts +30 -0
- package/dist/verification/verifier.js +309 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +48 -0
- package/dist/workflow/auto-generator.d.ts +27 -0
- package/dist/workflow/auto-generator.js +513 -0
- package/dist/workflow/discovery.d.ts +40 -0
- package/dist/workflow/discovery.js +195 -0
- package/dist/workflow/executor.d.ts +82 -0
- package/dist/workflow/executor.js +611 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/loader.d.ts +24 -0
- package/dist/workflow/loader.js +194 -0
- package/dist/workflow/state-tracker.d.ts +98 -0
- package/dist/workflow/state-tracker.js +424 -0
- package/dist/workflow/types.d.ts +337 -0
- package/dist/workflow/types.js +5 -0
- package/package.json +94 -0
- 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
|