observability-toolkit 1.8.5 → 2.1.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/README.md +167 -281
- package/dist/__tests__/find-constant-dedup.test.d.ts +11 -0
- package/dist/__tests__/find-constant-dedup.test.d.ts.map +1 -0
- package/dist/__tests__/find-constant-dedup.test.js +132 -0
- package/dist/__tests__/find-constant-dedup.test.js.map +1 -0
- package/dist/backends/backend-schemas.d.ts +309 -0
- package/dist/backends/backend-schemas.d.ts.map +1 -0
- package/dist/backends/backend-schemas.js +215 -0
- package/dist/backends/backend-schemas.js.map +1 -0
- package/dist/backends/cloud.d.ts +46 -0
- package/dist/backends/cloud.d.ts.map +1 -0
- package/dist/backends/cloud.js +520 -0
- package/dist/backends/cloud.js.map +1 -0
- package/dist/backends/cloud.test.d.ts +2 -0
- package/dist/backends/cloud.test.d.ts.map +1 -0
- package/dist/backends/cloud.test.js +436 -0
- package/dist/backends/cloud.test.js.map +1 -0
- package/dist/backends/index.d.ts +672 -236
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +334 -0
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/index.test.js +606 -31
- package/dist/backends/index.test.js.map +1 -1
- package/dist/backends/local-jsonl-boolean-search.test.js +8 -7
- package/dist/backends/local-jsonl-boolean-search.test.js.map +1 -1
- package/dist/backends/local-jsonl-cache.test.js +33 -31
- package/dist/backends/local-jsonl-cache.test.js.map +1 -1
- package/dist/backends/local-jsonl-circuit-breaker.test.js +9 -7
- package/dist/backends/local-jsonl-circuit-breaker.test.js.map +1 -1
- package/dist/backends/local-jsonl-export.test.js +73 -58
- package/dist/backends/local-jsonl-export.test.js.map +1 -1
- package/dist/backends/local-jsonl-index.test.js +52 -50
- package/dist/backends/local-jsonl-index.test.js.map +1 -1
- package/dist/backends/local-jsonl-logs.test.js +47 -31
- package/dist/backends/local-jsonl-logs.test.js.map +1 -1
- package/dist/backends/local-jsonl-metrics.test.js +85 -82
- package/dist/backends/local-jsonl-metrics.test.js.map +1 -1
- package/dist/backends/local-jsonl-otlp-unwrap.test.d.ts +2 -0
- package/dist/backends/local-jsonl-otlp-unwrap.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-otlp-unwrap.test.js +602 -0
- package/dist/backends/local-jsonl-otlp-unwrap.test.js.map +1 -0
- package/dist/backends/local-jsonl-traces.test.js +161 -147
- package/dist/backends/local-jsonl-traces.test.js.map +1 -1
- package/dist/backends/local-jsonl.d.ts +64 -5
- package/dist/backends/local-jsonl.d.ts.map +1 -1
- package/dist/backends/local-jsonl.js +1821 -612
- package/dist/backends/local-jsonl.js.map +1 -1
- package/dist/backends/shared.d.ts +9 -0
- package/dist/backends/shared.d.ts.map +1 -0
- package/dist/backends/shared.js +9 -0
- package/dist/backends/shared.js.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/logs/v1/logs_service_pb.d.ts +40 -0
- package/dist/generated/opentelemetry/proto/collector/logs/v1/logs_service_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/logs/v1/logs_service_pb.js +27 -0
- package/dist/generated/opentelemetry/proto/collector/logs/v1/logs_service_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/metrics/v1/metrics_service_pb.d.ts +106 -0
- package/dist/generated/opentelemetry/proto/collector/metrics/v1/metrics_service_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/metrics/v1/metrics_service_pb.js +43 -0
- package/dist/generated/opentelemetry/proto/collector/metrics/v1/metrics_service_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb.d.ts +111 -0
- package/dist/generated/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb.js +42 -0
- package/dist/generated/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/trace/v1/trace_service_pb.d.ts +106 -0
- package/dist/generated/opentelemetry/proto/collector/trace/v1/trace_service_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/collector/trace/v1/trace_service_pb.js +43 -0
- package/dist/generated/opentelemetry/proto/collector/trace/v1/trace_service_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/common/v1/common_pb.d.ts +243 -0
- package/dist/generated/opentelemetry/proto/common/v1/common_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/common/v1/common_pb.js +49 -0
- package/dist/generated/opentelemetry/proto/common/v1/common_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/logs/v1/logs_pb.d.ts +90 -0
- package/dist/generated/opentelemetry/proto/logs/v1/logs_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/logs/v1/logs_pb.js +66 -0
- package/dist/generated/opentelemetry/proto/logs/v1/logs_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/metrics/v1/metrics_pb.d.ts +1134 -0
- package/dist/generated/opentelemetry/proto/metrics/v1/metrics_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/metrics/v1/metrics_pb.js +223 -0
- package/dist/generated/opentelemetry/proto/metrics/v1/metrics_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/profiles/v1development/profiles_pb.d.ts +678 -0
- package/dist/generated/opentelemetry/proto/profiles/v1development/profiles_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/profiles/v1development/profiles_pb.js +107 -0
- package/dist/generated/opentelemetry/proto/profiles/v1development/profiles_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/resource/v1/resource_pb.d.ts +46 -0
- package/dist/generated/opentelemetry/proto/resource/v1/resource_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/resource/v1/resource_pb.js +25 -0
- package/dist/generated/opentelemetry/proto/resource/v1/resource_pb.js.map +1 -0
- package/dist/generated/opentelemetry/proto/trace/v1/trace_pb.d.ts +569 -0
- package/dist/generated/opentelemetry/proto/trace/v1/trace_pb.d.ts.map +1 -0
- package/dist/generated/opentelemetry/proto/trace/v1/trace_pb.js +195 -0
- package/dist/generated/opentelemetry/proto/trace/v1/trace_pb.js.map +1 -0
- package/dist/lib/agent-judge/agent-as-judge.d.ts +157 -0
- package/dist/lib/agent-judge/agent-as-judge.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-as-judge.js +137 -0
- package/dist/lib/agent-judge/agent-as-judge.js.map +1 -0
- package/dist/lib/agent-judge/agent-as-judge.test.d.ts +5 -0
- package/dist/lib/agent-judge/agent-as-judge.test.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-as-judge.test.js +839 -0
- package/dist/lib/agent-judge/agent-as-judge.test.js.map +1 -0
- package/dist/lib/agent-judge/agent-eval-metrics.d.ts +293 -0
- package/dist/lib/agent-judge/agent-eval-metrics.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-eval-metrics.js +715 -0
- package/dist/lib/agent-judge/agent-eval-metrics.js.map +1 -0
- package/dist/lib/agent-judge/agent-eval-metrics.test.d.ts +5 -0
- package/dist/lib/agent-judge/agent-eval-metrics.test.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-eval-metrics.test.js +676 -0
- package/dist/lib/agent-judge/agent-eval-metrics.test.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-classes.d.ts +95 -0
- package/dist/lib/agent-judge/agent-judge-classes.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-classes.js +222 -0
- package/dist/lib/agent-judge/agent-judge-classes.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-classes.test.d.ts +6 -0
- package/dist/lib/agent-judge/agent-judge-classes.test.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-classes.test.js +271 -0
- package/dist/lib/agent-judge/agent-judge-classes.test.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-consensus.d.ts +58 -0
- package/dist/lib/agent-judge/agent-judge-consensus.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-consensus.js +149 -0
- package/dist/lib/agent-judge/agent-judge-consensus.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-consensus.test.d.ts +2 -0
- package/dist/lib/agent-judge/agent-judge-consensus.test.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-consensus.test.js +170 -0
- package/dist/lib/agent-judge/agent-judge-consensus.test.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-verification.d.ts +89 -0
- package/dist/lib/agent-judge/agent-judge-verification.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-verification.js +235 -0
- package/dist/lib/agent-judge/agent-judge-verification.js.map +1 -0
- package/dist/lib/agent-judge/agent-judge-verification.test.d.ts +5 -0
- package/dist/lib/agent-judge/agent-judge-verification.test.d.ts.map +1 -0
- package/dist/lib/agent-judge/agent-judge-verification.test.js +399 -0
- package/dist/lib/agent-judge/agent-judge-verification.test.js.map +1 -0
- package/dist/lib/audit/agent-auditor-scoring.d.ts +167 -0
- package/dist/lib/audit/agent-auditor-scoring.d.ts.map +1 -0
- package/dist/lib/audit/agent-auditor-scoring.js +338 -0
- package/dist/lib/audit/agent-auditor-scoring.js.map +1 -0
- package/dist/lib/audit/agent-auditor-scoring.test.d.ts +2 -0
- package/dist/lib/audit/agent-auditor-scoring.test.d.ts.map +1 -0
- package/dist/lib/audit/agent-auditor-scoring.test.js +576 -0
- package/dist/lib/audit/agent-auditor-scoring.test.js.map +1 -0
- package/dist/lib/audit/audit-record.d.ts +139 -0
- package/dist/lib/audit/audit-record.d.ts.map +1 -0
- package/dist/lib/audit/audit-record.js +288 -0
- package/dist/lib/audit/audit-record.js.map +1 -0
- package/dist/lib/audit/audit-record.test.d.ts +5 -0
- package/dist/lib/audit/audit-record.test.d.ts.map +1 -0
- package/dist/lib/audit/audit-record.test.js +258 -0
- package/dist/lib/audit/audit-record.test.js.map +1 -0
- package/dist/lib/audit/audit-scoring-constants.d.ts +57 -0
- package/dist/lib/audit/audit-scoring-constants.d.ts.map +1 -0
- package/dist/lib/audit/audit-scoring-constants.js +59 -0
- package/dist/lib/audit/audit-scoring-constants.js.map +1 -0
- package/dist/lib/audit/compliance-report.d.ts +125 -0
- package/dist/lib/audit/compliance-report.d.ts.map +1 -0
- package/dist/lib/audit/compliance-report.js +205 -0
- package/dist/lib/audit/compliance-report.js.map +1 -0
- package/dist/lib/audit/compliance-report.test.d.ts +5 -0
- package/dist/lib/audit/compliance-report.test.d.ts.map +1 -0
- package/dist/lib/audit/compliance-report.test.js +290 -0
- package/dist/lib/audit/compliance-report.test.js.map +1 -0
- package/dist/lib/audit/retention-guard.d.ts +41 -0
- package/dist/lib/audit/retention-guard.d.ts.map +1 -0
- package/dist/lib/audit/retention-guard.js +103 -0
- package/dist/lib/audit/retention-guard.js.map +1 -0
- package/dist/lib/audit/retention-guard.test.d.ts +5 -0
- package/dist/lib/audit/retention-guard.test.d.ts.map +1 -0
- package/dist/lib/audit/retention-guard.test.js +109 -0
- package/dist/lib/audit/retention-guard.test.js.map +1 -0
- package/dist/lib/audit/skill-auditor-scoring.d.ts +69 -0
- package/dist/lib/audit/skill-auditor-scoring.d.ts.map +1 -0
- package/dist/lib/audit/skill-auditor-scoring.js +149 -0
- package/dist/lib/audit/skill-auditor-scoring.js.map +1 -0
- package/dist/lib/audit/skill-auditor-scoring.test.d.ts +2 -0
- package/dist/lib/audit/skill-auditor-scoring.test.d.ts.map +1 -0
- package/dist/lib/audit/skill-auditor-scoring.test.js +369 -0
- package/dist/lib/audit/skill-auditor-scoring.test.js.map +1 -0
- package/dist/lib/audit/verification-events.d.ts +119 -0
- package/dist/lib/audit/verification-events.d.ts.map +1 -0
- package/dist/lib/audit/verification-events.js +175 -0
- package/dist/lib/audit/verification-events.js.map +1 -0
- package/dist/lib/audit/verification-events.test.d.ts +5 -0
- package/dist/lib/audit/verification-events.test.d.ts.map +1 -0
- package/dist/lib/audit/verification-events.test.js +197 -0
- package/dist/lib/audit/verification-events.test.js.map +1 -0
- package/dist/lib/core/constants-models.d.ts +90 -0
- package/dist/lib/core/constants-models.d.ts.map +1 -0
- package/dist/lib/core/constants-models.js +208 -0
- package/dist/lib/core/constants-models.js.map +1 -0
- package/dist/lib/core/constants-otel.d.ts +68 -0
- package/dist/lib/core/constants-otel.d.ts.map +1 -0
- package/dist/lib/core/constants-otel.js +128 -0
- package/dist/lib/core/constants-otel.js.map +1 -0
- package/dist/lib/core/constants-symlink.test.d.ts.map +1 -0
- package/dist/lib/{constants-symlink.test.js → core/constants-symlink.test.js} +25 -24
- package/dist/lib/core/constants-symlink.test.js.map +1 -0
- package/dist/lib/core/constants-telemetry.d.ts +21 -0
- package/dist/lib/core/constants-telemetry.d.ts.map +1 -0
- package/dist/lib/core/constants-telemetry.js +162 -0
- package/dist/lib/core/constants-telemetry.js.map +1 -0
- package/dist/lib/core/constants.d.ts +152 -0
- package/dist/lib/core/constants.d.ts.map +1 -0
- package/dist/lib/core/constants.js +223 -0
- package/dist/lib/core/constants.js.map +1 -0
- package/dist/lib/core/constants.test.d.ts.map +1 -0
- package/dist/lib/{constants.test.js → core/constants.test.js} +198 -82
- package/dist/lib/core/constants.test.js.map +1 -0
- package/dist/lib/core/doc-sync.test.d.ts +9 -0
- package/dist/lib/core/doc-sync.test.d.ts.map +1 -0
- package/dist/lib/core/doc-sync.test.js +159 -0
- package/dist/lib/core/doc-sync.test.js.map +1 -0
- package/dist/lib/core/edge-cases.test.d.ts.map +1 -0
- package/dist/lib/{edge-cases.test.js → core/edge-cases.test.js} +76 -73
- package/dist/lib/core/edge-cases.test.js.map +1 -0
- package/dist/lib/{file-utils.d.ts → core/file-utils.d.ts} +63 -8
- package/dist/lib/core/file-utils.d.ts.map +1 -0
- package/dist/lib/{file-utils.js → core/file-utils.js} +186 -93
- package/dist/lib/core/file-utils.js.map +1 -0
- package/dist/lib/core/file-utils.test-constants.d.ts +38 -0
- package/dist/lib/core/file-utils.test-constants.d.ts.map +1 -0
- package/dist/lib/core/file-utils.test-constants.js +40 -0
- package/dist/lib/core/file-utils.test-constants.js.map +1 -0
- package/dist/lib/core/file-utils.test.d.ts.map +1 -0
- package/dist/lib/{file-utils.test.js → core/file-utils.test.js} +240 -214
- package/dist/lib/core/file-utils.test.js.map +1 -0
- package/dist/lib/{input-validator.d.ts → core/input-validator.d.ts} +30 -20
- package/dist/lib/core/input-validator.d.ts.map +1 -0
- package/dist/lib/core/input-validator.fuzz.test.d.ts.map +1 -0
- package/dist/lib/{input-validator.fuzz.test.js → core/input-validator.fuzz.test.js} +41 -29
- package/dist/lib/core/input-validator.fuzz.test.js.map +1 -0
- package/dist/lib/{input-validator.js → core/input-validator.js} +83 -39
- package/dist/lib/core/input-validator.js.map +1 -0
- package/dist/lib/core/input-validator.test.d.ts.map +1 -0
- package/dist/lib/{input-validator.test.js → core/input-validator.test.js} +95 -45
- package/dist/lib/core/input-validator.test.js.map +1 -0
- package/dist/lib/{logger.d.ts → core/logger.d.ts} +4 -18
- package/dist/lib/core/logger.d.ts.map +1 -0
- package/dist/lib/core/logger.js +104 -0
- package/dist/lib/core/logger.js.map +1 -0
- package/dist/lib/core/logger.test.d.ts.map +1 -0
- package/dist/lib/core/logger.test.js.map +1 -0
- package/dist/lib/core/schema-types.d.ts +37 -0
- package/dist/lib/core/schema-types.d.ts.map +1 -0
- package/dist/lib/core/schema-types.js +29 -0
- package/dist/lib/core/schema-types.js.map +1 -0
- package/dist/lib/{server-utils.d.ts → core/server-utils.d.ts} +11 -1
- package/dist/lib/core/server-utils.d.ts.map +1 -0
- package/dist/lib/{server-utils.js → core/server-utils.js} +25 -5
- package/dist/lib/core/server-utils.js.map +1 -0
- package/dist/lib/core/shared-schemas.d.ts +301 -0
- package/dist/lib/core/shared-schemas.d.ts.map +1 -0
- package/dist/lib/core/shared-schemas.js +222 -0
- package/dist/lib/core/shared-schemas.js.map +1 -0
- package/dist/lib/core/shared-schemas.test.d.ts.map +1 -0
- package/dist/lib/{shared-schemas.test.js → core/shared-schemas.test.js} +48 -18
- package/dist/lib/core/shared-schemas.test.js.map +1 -0
- package/dist/lib/core/units.d.ts +67 -0
- package/dist/lib/core/units.d.ts.map +1 -0
- package/dist/lib/core/units.js +88 -0
- package/dist/lib/core/units.js.map +1 -0
- package/dist/lib/cost/cost-estimation.d.ts +264 -0
- package/dist/lib/cost/cost-estimation.d.ts.map +1 -0
- package/dist/lib/cost/cost-estimation.js +541 -0
- package/dist/lib/cost/cost-estimation.js.map +1 -0
- package/dist/lib/cost/cost-estimation.test.d.ts +5 -0
- package/dist/lib/cost/cost-estimation.test.d.ts.map +1 -0
- package/dist/lib/cost/cost-estimation.test.js +701 -0
- package/dist/lib/cost/cost-estimation.test.js.map +1 -0
- package/dist/lib/cost/pricing-cache.d.ts +59 -0
- package/dist/lib/cost/pricing-cache.d.ts.map +1 -0
- package/dist/lib/cost/pricing-cache.js +120 -0
- package/dist/lib/cost/pricing-cache.js.map +1 -0
- package/dist/lib/cost/pricing-cache.test.d.ts +5 -0
- package/dist/lib/cost/pricing-cache.test.d.ts.map +1 -0
- package/dist/lib/cost/pricing-cache.test.js +176 -0
- package/dist/lib/cost/pricing-cache.test.js.map +1 -0
- package/dist/lib/dashboard-file-utils.d.ts +35 -0
- package/dist/lib/dashboard-file-utils.d.ts.map +1 -0
- package/dist/lib/dashboard-file-utils.js +94 -0
- package/dist/lib/dashboard-file-utils.js.map +1 -0
- package/dist/lib/{error-sanitizer.d.ts → errors/error-sanitizer.d.ts} +5 -0
- package/dist/lib/errors/error-sanitizer.d.ts.map +1 -0
- package/dist/lib/{error-sanitizer.js → errors/error-sanitizer.js} +8 -6
- package/dist/lib/errors/error-sanitizer.js.map +1 -0
- package/dist/lib/errors/error-sanitizer.test.d.ts.map +1 -0
- package/dist/lib/{error-sanitizer.test.js → errors/error-sanitizer.test.js} +17 -11
- package/dist/lib/errors/error-sanitizer.test.js.map +1 -0
- package/dist/lib/{error-types.d.ts → errors/error-types.d.ts} +5 -0
- package/dist/lib/errors/error-types.d.ts.map +1 -0
- package/dist/lib/{error-types.js → errors/error-types.js} +34 -1
- package/dist/lib/errors/error-types.js.map +1 -0
- package/dist/lib/errors/error-types.test.d.ts.map +1 -0
- package/dist/lib/{error-types.test.js → errors/error-types.test.js} +51 -1
- package/dist/lib/errors/error-types.test.js.map +1 -0
- package/dist/lib/errors/query-sanitizer.d.ts.map +1 -0
- package/dist/lib/{query-sanitizer.js → errors/query-sanitizer.js} +9 -1
- package/dist/lib/errors/query-sanitizer.js.map +1 -0
- package/dist/lib/errors/query-sanitizer.test.d.ts.map +1 -0
- package/dist/lib/{query-sanitizer.test.js → errors/query-sanitizer.test.js} +9 -6
- package/dist/lib/errors/query-sanitizer.test.js.map +1 -0
- package/dist/lib/exports/confident-export.d.ts +105 -0
- package/dist/lib/exports/confident-export.d.ts.map +1 -0
- package/dist/lib/exports/confident-export.js +385 -0
- package/dist/lib/exports/confident-export.js.map +1 -0
- package/dist/lib/exports/confident-export.test.d.ts +7 -0
- package/dist/lib/exports/confident-export.test.d.ts.map +1 -0
- package/dist/lib/exports/confident-export.test.js +848 -0
- package/dist/lib/exports/confident-export.test.js.map +1 -0
- package/dist/lib/exports/datadog-export.d.ts +200 -0
- package/dist/lib/exports/datadog-export.d.ts.map +1 -0
- package/dist/lib/exports/datadog-export.js +488 -0
- package/dist/lib/exports/datadog-export.js.map +1 -0
- package/dist/lib/exports/datadog-export.test.d.ts +2 -0
- package/dist/lib/exports/datadog-export.test.d.ts.map +1 -0
- package/dist/lib/exports/datadog-export.test.js +890 -0
- package/dist/lib/exports/datadog-export.test.js.map +1 -0
- package/dist/lib/exports/export-config-schemas.d.ts +67 -0
- package/dist/lib/exports/export-config-schemas.d.ts.map +1 -0
- package/dist/lib/exports/export-config-schemas.js +120 -0
- package/dist/lib/exports/export-config-schemas.js.map +1 -0
- package/dist/lib/exports/export-config-schemas.test.d.ts +8 -0
- package/dist/lib/exports/export-config-schemas.test.d.ts.map +1 -0
- package/dist/lib/exports/export-config-schemas.test.js +503 -0
- package/dist/lib/exports/export-config-schemas.test.js.map +1 -0
- package/dist/lib/exports/export-utils.d.ts +127 -0
- package/dist/lib/exports/export-utils.d.ts.map +1 -0
- package/dist/lib/exports/export-utils.js +303 -0
- package/dist/lib/exports/export-utils.js.map +1 -0
- package/dist/lib/exports/export-utils.test.d.ts +5 -0
- package/dist/lib/exports/export-utils.test.d.ts.map +1 -0
- package/dist/lib/exports/export-utils.test.js +344 -0
- package/dist/lib/exports/export-utils.test.js.map +1 -0
- package/dist/lib/exports/langfuse-export.d.ts +129 -0
- package/dist/lib/exports/langfuse-export.d.ts.map +1 -0
- package/dist/lib/exports/langfuse-export.js +370 -0
- package/dist/lib/exports/langfuse-export.js.map +1 -0
- package/dist/lib/exports/langfuse-export.test.d.ts +7 -0
- package/dist/lib/exports/langfuse-export.test.d.ts.map +1 -0
- package/dist/lib/exports/langfuse-export.test.js +1020 -0
- package/dist/lib/exports/langfuse-export.test.js.map +1 -0
- package/dist/lib/{otlp-export.d.ts → exports/otlp-export.d.ts} +3 -2
- package/dist/lib/exports/otlp-export.d.ts.map +1 -0
- package/dist/lib/{otlp-export.js → exports/otlp-export.js} +51 -36
- package/dist/lib/exports/otlp-export.js.map +1 -0
- package/dist/lib/exports/otlp-format-converter.d.ts +70 -0
- package/dist/lib/exports/otlp-format-converter.d.ts.map +1 -0
- package/dist/lib/exports/otlp-format-converter.js +401 -0
- package/dist/lib/exports/otlp-format-converter.js.map +1 -0
- package/dist/lib/exports/otlp-proto-encode.d.ts +53 -0
- package/dist/lib/exports/otlp-proto-encode.d.ts.map +1 -0
- package/dist/lib/exports/otlp-proto-encode.js +165 -0
- package/dist/lib/exports/otlp-proto-encode.js.map +1 -0
- package/dist/lib/exports/otlp-proto-encode.test.d.ts +7 -0
- package/dist/lib/exports/otlp-proto-encode.test.d.ts.map +1 -0
- package/dist/lib/exports/otlp-proto-encode.test.js +997 -0
- package/dist/lib/exports/otlp-proto-encode.test.js.map +1 -0
- package/dist/lib/exports/phoenix-export.d.ts +119 -0
- package/dist/lib/exports/phoenix-export.d.ts.map +1 -0
- package/dist/lib/exports/phoenix-export.js +448 -0
- package/dist/lib/exports/phoenix-export.js.map +1 -0
- package/dist/lib/exports/phoenix-export.test.d.ts +11 -0
- package/dist/lib/exports/phoenix-export.test.d.ts.map +1 -0
- package/dist/lib/exports/phoenix-export.test.js +816 -0
- package/dist/lib/exports/phoenix-export.test.js.map +1 -0
- package/dist/lib/index.d.ts +16 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +31 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/judge/evaluation-hooks-schemas.d.ts +186 -0
- package/dist/lib/judge/evaluation-hooks-schemas.d.ts.map +1 -0
- package/dist/lib/judge/evaluation-hooks-schemas.js +125 -0
- package/dist/lib/judge/evaluation-hooks-schemas.js.map +1 -0
- package/dist/lib/judge/evaluation-hooks.d.ts +88 -0
- package/dist/lib/judge/evaluation-hooks.d.ts.map +1 -0
- package/dist/lib/judge/evaluation-hooks.js +658 -0
- package/dist/lib/judge/evaluation-hooks.js.map +1 -0
- package/dist/lib/judge/evaluation-hooks.test.d.ts +8 -0
- package/dist/lib/judge/evaluation-hooks.test.d.ts.map +1 -0
- package/dist/lib/judge/evaluation-hooks.test.js +934 -0
- package/dist/lib/judge/evaluation-hooks.test.js.map +1 -0
- package/dist/lib/judge/llm-as-judge.d.ts +138 -0
- package/dist/lib/judge/llm-as-judge.d.ts.map +1 -0
- package/dist/lib/judge/llm-as-judge.js +103 -0
- package/dist/lib/judge/llm-as-judge.js.map +1 -0
- package/dist/lib/judge/llm-as-judge.test.d.ts +2 -0
- package/dist/lib/judge/llm-as-judge.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-as-judge.test.js +2179 -0
- package/dist/lib/judge/llm-as-judge.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-bias.d.ts +44 -0
- package/dist/lib/judge/llm-judge-bias.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-bias.js +130 -0
- package/dist/lib/judge/llm-judge-bias.js.map +1 -0
- package/dist/lib/judge/llm-judge-bias.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-bias.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-bias.test.js +380 -0
- package/dist/lib/judge/llm-judge-bias.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-code.d.ts +99 -0
- package/dist/lib/judge/llm-judge-code.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-code.js +261 -0
- package/dist/lib/judge/llm-judge-code.js.map +1 -0
- package/dist/lib/judge/llm-judge-code.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-code.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-code.test.js +981 -0
- package/dist/lib/judge/llm-judge-code.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-config.d.ts +241 -0
- package/dist/lib/judge/llm-judge-config.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-config.js +390 -0
- package/dist/lib/judge/llm-judge-config.js.map +1 -0
- package/dist/lib/judge/llm-judge-config.test.d.ts +5 -0
- package/dist/lib/judge/llm-judge-config.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-config.test.js +392 -0
- package/dist/lib/judge/llm-judge-config.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-constants.d.ts +111 -0
- package/dist/lib/judge/llm-judge-constants.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-constants.js +150 -0
- package/dist/lib/judge/llm-judge-constants.js.map +1 -0
- package/dist/lib/judge/llm-judge-dag.d.ts +57 -0
- package/dist/lib/judge/llm-judge-dag.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-dag.js +217 -0
- package/dist/lib/judge/llm-judge-dag.js.map +1 -0
- package/dist/lib/judge/llm-judge-dag.test.d.ts +8 -0
- package/dist/lib/judge/llm-judge-dag.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-dag.test.js +973 -0
- package/dist/lib/judge/llm-judge-dag.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-domain.d.ts +42 -0
- package/dist/lib/judge/llm-judge-domain.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-domain.js +167 -0
- package/dist/lib/judge/llm-judge-domain.js.map +1 -0
- package/dist/lib/judge/llm-judge-domain.test.d.ts +6 -0
- package/dist/lib/judge/llm-judge-domain.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-domain.test.js +337 -0
- package/dist/lib/judge/llm-judge-domain.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-geval.d.ts +42 -0
- package/dist/lib/judge/llm-judge-geval.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-geval.js +213 -0
- package/dist/lib/judge/llm-judge-geval.js.map +1 -0
- package/dist/lib/judge/llm-judge-geval.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-geval.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-geval.test.js +556 -0
- package/dist/lib/judge/llm-judge-geval.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-otel.test.d.ts +9 -0
- package/dist/lib/judge/llm-judge-otel.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-otel.test.js +91 -0
- package/dist/lib/judge/llm-judge-otel.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-qag.d.ts +38 -0
- package/dist/lib/judge/llm-judge-qag.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-qag.js +205 -0
- package/dist/lib/judge/llm-judge-qag.js.map +1 -0
- package/dist/lib/judge/llm-judge-qag.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-qag.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-qag.test.js +386 -0
- package/dist/lib/judge/llm-judge-qag.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-resilience.d.ts +74 -0
- package/dist/lib/judge/llm-judge-resilience.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-resilience.js +146 -0
- package/dist/lib/judge/llm-judge-resilience.js.map +1 -0
- package/dist/lib/judge/llm-judge-resilience.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-resilience.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-resilience.test.js +353 -0
- package/dist/lib/judge/llm-judge-resilience.test.js.map +1 -0
- package/dist/lib/judge/llm-judge-security.d.ts +106 -0
- package/dist/lib/judge/llm-judge-security.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-security.js +314 -0
- package/dist/lib/judge/llm-judge-security.js.map +1 -0
- package/dist/lib/judge/llm-judge-security.test.d.ts +2 -0
- package/dist/lib/judge/llm-judge-security.test.d.ts.map +1 -0
- package/dist/lib/judge/llm-judge-security.test.js +1011 -0
- package/dist/lib/judge/llm-judge-security.test.js.map +1 -0
- package/dist/lib/observability/context-accumulator.d.ts +32 -0
- package/dist/lib/observability/context-accumulator.d.ts.map +1 -0
- package/dist/lib/observability/context-accumulator.js +87 -0
- package/dist/lib/observability/context-accumulator.js.map +1 -0
- package/dist/lib/observability/evaluation-events.d.ts +35 -0
- package/dist/lib/observability/evaluation-events.d.ts.map +1 -0
- package/dist/lib/observability/evaluation-events.js +90 -0
- package/dist/lib/observability/evaluation-events.js.map +1 -0
- package/dist/lib/observability/file-span-exporter.d.ts +17 -0
- package/dist/lib/observability/file-span-exporter.d.ts.map +1 -0
- package/dist/lib/observability/file-span-exporter.js +49 -0
- package/dist/lib/observability/file-span-exporter.js.map +1 -0
- package/dist/lib/observability/histogram-bucket-constants.d.ts +25 -0
- package/dist/lib/observability/histogram-bucket-constants.d.ts.map +1 -0
- package/dist/lib/observability/histogram-bucket-constants.js +60 -0
- package/dist/lib/observability/histogram-bucket-constants.js.map +1 -0
- package/dist/lib/observability/histogram.d.ts +112 -0
- package/dist/lib/observability/histogram.d.ts.map +1 -0
- package/dist/lib/observability/histogram.js +170 -0
- package/dist/lib/observability/histogram.js.map +1 -0
- package/dist/lib/observability/histogram.test.d.ts +5 -0
- package/dist/lib/observability/histogram.test.d.ts.map +1 -0
- package/dist/lib/observability/histogram.test.js +385 -0
- package/dist/lib/observability/histogram.test.js.map +1 -0
- package/dist/lib/observability/indexer.d.ts +114 -0
- package/dist/lib/observability/indexer.d.ts.map +1 -0
- package/dist/lib/{indexer.js → observability/indexer.js} +65 -16
- package/dist/lib/observability/indexer.js.map +1 -0
- package/dist/lib/observability/indexer.test.d.ts.map +1 -0
- package/dist/lib/{indexer.test.js → observability/indexer.test.js} +94 -77
- package/dist/lib/observability/indexer.test.js.map +1 -0
- package/dist/lib/observability/instrumentation-eval.test.d.ts +5 -0
- package/dist/lib/observability/instrumentation-eval.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation-eval.test.js +63 -0
- package/dist/lib/observability/instrumentation-eval.test.js.map +1 -0
- package/dist/lib/observability/instrumentation-init-errors.test.d.ts +13 -0
- package/dist/lib/observability/instrumentation-init-errors.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation-init-errors.test.js +194 -0
- package/dist/lib/observability/instrumentation-init-errors.test.js.map +1 -0
- package/dist/lib/observability/instrumentation-retry-timeout.test.d.ts +15 -0
- package/dist/lib/observability/instrumentation-retry-timeout.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation-retry-timeout.test.js +188 -0
- package/dist/lib/observability/instrumentation-retry-timeout.test.js.map +1 -0
- package/dist/lib/observability/instrumentation-set-otel.test.d.ts +5 -0
- package/dist/lib/observability/instrumentation-set-otel.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation-set-otel.test.js +59 -0
- package/dist/lib/observability/instrumentation-set-otel.test.js.map +1 -0
- package/dist/lib/observability/instrumentation.d.ts +158 -0
- package/dist/lib/observability/instrumentation.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation.integration.test.d.ts +2 -0
- package/dist/lib/observability/instrumentation.integration.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation.integration.test.js +590 -0
- package/dist/lib/observability/instrumentation.integration.test.js.map +1 -0
- package/dist/lib/observability/instrumentation.js +512 -0
- package/dist/lib/observability/instrumentation.js.map +1 -0
- package/dist/lib/observability/instrumentation.test.d.ts +2 -0
- package/dist/lib/observability/instrumentation.test.d.ts.map +1 -0
- package/dist/lib/observability/instrumentation.test.js +822 -0
- package/dist/lib/observability/instrumentation.test.js.map +1 -0
- package/dist/lib/observability/mcp-semconv-constants.d.ts +98 -0
- package/dist/lib/observability/mcp-semconv-constants.d.ts.map +1 -0
- package/dist/lib/observability/mcp-semconv-constants.js +102 -0
- package/dist/lib/observability/mcp-semconv-constants.js.map +1 -0
- package/dist/lib/observability/mcp-semconv.d.ts +37 -0
- package/dist/lib/observability/mcp-semconv.d.ts.map +1 -0
- package/dist/lib/observability/mcp-semconv.js +87 -0
- package/dist/lib/observability/mcp-semconv.js.map +1 -0
- package/dist/lib/observability/mcp-semconv.test.d.ts +2 -0
- package/dist/lib/observability/mcp-semconv.test.d.ts.map +1 -0
- package/dist/lib/observability/mcp-semconv.test.js +168 -0
- package/dist/lib/observability/mcp-semconv.test.js.map +1 -0
- package/dist/lib/observability/metrics.d.ts +100 -0
- package/dist/lib/observability/metrics.d.ts.map +1 -0
- package/dist/lib/observability/metrics.js +429 -0
- package/dist/lib/observability/metrics.js.map +1 -0
- package/dist/lib/observability/metrics.test.d.ts +5 -0
- package/dist/lib/observability/metrics.test.d.ts.map +1 -0
- package/dist/lib/observability/metrics.test.js +191 -0
- package/dist/lib/observability/metrics.test.js.map +1 -0
- package/dist/lib/observability/observability-test-constants.d.ts +34 -0
- package/dist/lib/observability/observability-test-constants.d.ts.map +1 -0
- package/dist/lib/observability/observability-test-constants.js +55 -0
- package/dist/lib/observability/observability-test-constants.js.map +1 -0
- package/dist/lib/observability/opentelemetry-resources.test.d.ts +2 -0
- package/dist/lib/observability/opentelemetry-resources.test.d.ts.map +1 -0
- package/dist/lib/observability/opentelemetry-resources.test.js +19 -0
- package/dist/lib/observability/opentelemetry-resources.test.js.map +1 -0
- package/dist/lib/observability/parse-stats.d.ts +119 -0
- package/dist/lib/observability/parse-stats.d.ts.map +1 -0
- package/dist/lib/observability/parse-stats.js +207 -0
- package/dist/lib/observability/parse-stats.js.map +1 -0
- package/dist/lib/observability/parse-stats.test.d.ts +5 -0
- package/dist/lib/observability/parse-stats.test.d.ts.map +1 -0
- package/dist/lib/observability/parse-stats.test.js +287 -0
- package/dist/lib/observability/parse-stats.test.js.map +1 -0
- package/dist/lib/observability/render-trace-tree.d.ts +31 -0
- package/dist/lib/observability/render-trace-tree.d.ts.map +1 -0
- package/dist/lib/observability/render-trace-tree.js +95 -0
- package/dist/lib/observability/render-trace-tree.js.map +1 -0
- package/dist/lib/observability/render-trace-tree.test.d.ts +5 -0
- package/dist/lib/observability/render-trace-tree.test.d.ts.map +1 -0
- package/dist/lib/observability/render-trace-tree.test.js +97 -0
- package/dist/lib/observability/render-trace-tree.test.js.map +1 -0
- package/dist/lib/observability/span-attributes.d.ts +27 -0
- package/dist/lib/observability/span-attributes.d.ts.map +1 -0
- package/dist/lib/observability/span-attributes.js +85 -0
- package/dist/lib/observability/span-attributes.js.map +1 -0
- package/dist/lib/observability/trace-anomaly-detector.d.ts +23 -0
- package/dist/lib/observability/trace-anomaly-detector.d.ts.map +1 -0
- package/dist/lib/observability/trace-anomaly-detector.js +211 -0
- package/dist/lib/observability/trace-anomaly-detector.js.map +1 -0
- package/dist/lib/observability/trace-anomaly-detector.test.d.ts +5 -0
- package/dist/lib/observability/trace-anomaly-detector.test.d.ts.map +1 -0
- package/dist/lib/observability/trace-anomaly-detector.test.js +224 -0
- package/dist/lib/observability/trace-anomaly-detector.test.js.map +1 -0
- package/dist/lib/observability/trace-anomaly-schemas.d.ts +189 -0
- package/dist/lib/observability/trace-anomaly-schemas.d.ts.map +1 -0
- package/dist/lib/observability/trace-anomaly-schemas.js +167 -0
- package/dist/lib/observability/trace-anomaly-schemas.js.map +1 -0
- package/dist/lib/privacy/content-redaction.d.ts +141 -0
- package/dist/lib/privacy/content-redaction.d.ts.map +1 -0
- package/dist/lib/privacy/content-redaction.js +210 -0
- package/dist/lib/privacy/content-redaction.js.map +1 -0
- package/dist/lib/privacy/content-redaction.test.d.ts +2 -0
- package/dist/lib/privacy/content-redaction.test.d.ts.map +1 -0
- package/dist/lib/privacy/content-redaction.test.js +302 -0
- package/dist/lib/privacy/content-redaction.test.js.map +1 -0
- package/dist/lib/quality/bucket-utils.d.ts +17 -0
- package/dist/lib/quality/bucket-utils.d.ts.map +1 -0
- package/dist/lib/quality/bucket-utils.js +31 -0
- package/dist/lib/quality/bucket-utils.js.map +1 -0
- package/dist/lib/quality/bucket-utils.test.d.ts +2 -0
- package/dist/lib/quality/bucket-utils.test.d.ts.map +1 -0
- package/dist/lib/quality/bucket-utils.test.js +42 -0
- package/dist/lib/quality/bucket-utils.test.js.map +1 -0
- package/dist/lib/quality/qfe-backtest-detail.test.d.ts +5 -0
- package/dist/lib/quality/qfe-backtest-detail.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-backtest-detail.test.js +179 -0
- package/dist/lib/quality/qfe-backtest-detail.test.js.map +1 -0
- package/dist/lib/quality/qfe-calibration-paths.test.d.ts +5 -0
- package/dist/lib/quality/qfe-calibration-paths.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-calibration-paths.test.js +203 -0
- package/dist/lib/quality/qfe-calibration-paths.test.js.map +1 -0
- package/dist/lib/quality/qfe-correlation-helpers.test.d.ts +6 -0
- package/dist/lib/quality/qfe-correlation-helpers.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-correlation-helpers.test.js +143 -0
- package/dist/lib/quality/qfe-correlation-helpers.test.js.map +1 -0
- package/dist/lib/quality/qfe-cqi-paths.test.d.ts +6 -0
- package/dist/lib/quality/qfe-cqi-paths.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-cqi-paths.test.js +231 -0
- package/dist/lib/quality/qfe-cqi-paths.test.js.map +1 -0
- package/dist/lib/quality/qfe-critic-internals.test.d.ts +6 -0
- package/dist/lib/quality/qfe-critic-internals.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-critic-internals.test.js +191 -0
- package/dist/lib/quality/qfe-critic-internals.test.js.map +1 -0
- package/dist/lib/quality/qfe-derived-paths.test.d.ts +2 -0
- package/dist/lib/quality/qfe-derived-paths.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-derived-paths.test.js +372 -0
- package/dist/lib/quality/qfe-derived-paths.test.js.map +1 -0
- package/dist/lib/quality/qfe-dynamics-paths.test.d.ts +8 -0
- package/dist/lib/quality/qfe-dynamics-paths.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-dynamics-paths.test.js +223 -0
- package/dist/lib/quality/qfe-dynamics-paths.test.js.map +1 -0
- package/dist/lib/quality/qfe-granger-internals.test.d.ts +6 -0
- package/dist/lib/quality/qfe-granger-internals.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-granger-internals.test.js +158 -0
- package/dist/lib/quality/qfe-granger-internals.test.js.map +1 -0
- package/dist/lib/quality/qfe-label-normalize.test.d.ts +7 -0
- package/dist/lib/quality/qfe-label-normalize.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-label-normalize.test.js +332 -0
- package/dist/lib/quality/qfe-label-normalize.test.js.map +1 -0
- package/dist/lib/quality/qfe-ordinal-edge.test.d.ts +6 -0
- package/dist/lib/quality/qfe-ordinal-edge.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-ordinal-edge.test.js +98 -0
- package/dist/lib/quality/qfe-ordinal-edge.test.js.map +1 -0
- package/dist/lib/quality/qfe-roles-detail.test.d.ts +5 -0
- package/dist/lib/quality/qfe-roles-detail.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-roles-detail.test.js +115 -0
- package/dist/lib/quality/qfe-roles-detail.test.js.map +1 -0
- package/dist/lib/quality/qfe-rolling-detail.test.d.ts +7 -0
- package/dist/lib/quality/qfe-rolling-detail.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-rolling-detail.test.js +249 -0
- package/dist/lib/quality/qfe-rolling-detail.test.js.map +1 -0
- package/dist/lib/quality/qfe-stats-internals.test.d.ts +7 -0
- package/dist/lib/quality/qfe-stats-internals.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-stats-internals.test.js +143 -0
- package/dist/lib/quality/qfe-stats-internals.test.js.map +1 -0
- package/dist/lib/quality/qfe-streaming.test.d.ts +5 -0
- package/dist/lib/quality/qfe-streaming.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-streaming.test.js +239 -0
- package/dist/lib/quality/qfe-streaming.test.js.map +1 -0
- package/dist/lib/quality/qfe-sweep-detail.test.d.ts +6 -0
- package/dist/lib/quality/qfe-sweep-detail.test.d.ts.map +1 -0
- package/dist/lib/quality/qfe-sweep-detail.test.js +291 -0
- package/dist/lib/quality/qfe-sweep-detail.test.js.map +1 -0
- package/dist/lib/quality/quality-alerts.d.ts +23 -0
- package/dist/lib/quality/quality-alerts.d.ts.map +1 -0
- package/dist/lib/quality/quality-alerts.js +89 -0
- package/dist/lib/quality/quality-alerts.js.map +1 -0
- package/dist/lib/quality/quality-alerts.test.d.ts +2 -0
- package/dist/lib/quality/quality-alerts.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-alerts.test.js +86 -0
- package/dist/lib/quality/quality-alerts.test.js.map +1 -0
- package/dist/lib/quality/quality-constants.d.ts +294 -0
- package/dist/lib/quality/quality-constants.d.ts.map +1 -0
- package/dist/lib/quality/quality-constants.js +335 -0
- package/dist/lib/quality/quality-constants.js.map +1 -0
- package/dist/lib/quality/quality-feature-engineering.d.ts +1071 -0
- package/dist/lib/quality/quality-feature-engineering.d.ts.map +1 -0
- package/dist/lib/quality/quality-feature-engineering.js +2076 -0
- package/dist/lib/quality/quality-feature-engineering.js.map +1 -0
- package/dist/lib/quality/quality-feature-engineering.test.d.ts +5 -0
- package/dist/lib/quality/quality-feature-engineering.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-feature-engineering.test.js +2908 -0
- package/dist/lib/quality/quality-feature-engineering.test.js.map +1 -0
- package/dist/lib/quality/quality-metrics.d.ts +943 -0
- package/dist/lib/quality/quality-metrics.d.ts.map +1 -0
- package/dist/lib/quality/quality-metrics.js +1151 -0
- package/dist/lib/quality/quality-metrics.js.map +1 -0
- package/dist/lib/quality/quality-metrics.test.d.ts +5 -0
- package/dist/lib/quality/quality-metrics.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-metrics.test.js +2766 -0
- package/dist/lib/quality/quality-metrics.test.js.map +1 -0
- package/dist/lib/quality/quality-multi-agent.d.ts +106 -0
- package/dist/lib/quality/quality-multi-agent.d.ts.map +1 -0
- package/dist/lib/quality/quality-multi-agent.js +124 -0
- package/dist/lib/quality/quality-multi-agent.js.map +1 -0
- package/dist/lib/quality/quality-multi-agent.test.d.ts +6 -0
- package/dist/lib/quality/quality-multi-agent.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-multi-agent.test.js +163 -0
- package/dist/lib/quality/quality-multi-agent.test.js.map +1 -0
- package/dist/lib/quality/quality-sla.d.ts +35 -0
- package/dist/lib/quality/quality-sla.d.ts.map +1 -0
- package/dist/lib/quality/quality-sla.js +62 -0
- package/dist/lib/quality/quality-sla.js.map +1 -0
- package/dist/lib/quality/quality-sla.test.d.ts +5 -0
- package/dist/lib/quality/quality-sla.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-sla.test.js +144 -0
- package/dist/lib/quality/quality-sla.test.js.map +1 -0
- package/dist/lib/quality/quality-test-constants.d.ts +23 -0
- package/dist/lib/quality/quality-test-constants.d.ts.map +1 -0
- package/dist/lib/quality/quality-test-constants.js +25 -0
- package/dist/lib/quality/quality-test-constants.js.map +1 -0
- package/dist/lib/quality/quality-trends.d.ts +101 -0
- package/dist/lib/quality/quality-trends.d.ts.map +1 -0
- package/dist/lib/quality/quality-trends.js +299 -0
- package/dist/lib/quality/quality-trends.js.map +1 -0
- package/dist/lib/quality/quality-trends.test.d.ts +6 -0
- package/dist/lib/quality/quality-trends.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-trends.test.js +377 -0
- package/dist/lib/quality/quality-trends.test.js.map +1 -0
- package/dist/lib/quality/quality-views.d.ts +966 -0
- package/dist/lib/quality/quality-views.d.ts.map +1 -0
- package/dist/lib/quality/quality-views.js +367 -0
- package/dist/lib/quality/quality-views.js.map +1 -0
- package/dist/lib/quality/quality-views.test.d.ts +6 -0
- package/dist/lib/quality/quality-views.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-views.test.js +262 -0
- package/dist/lib/quality/quality-views.test.js.map +1 -0
- package/dist/lib/quality/quality-visualization.d.ts +112 -0
- package/dist/lib/quality/quality-visualization.d.ts.map +1 -0
- package/dist/lib/quality/quality-visualization.js +136 -0
- package/dist/lib/quality/quality-visualization.js.map +1 -0
- package/dist/lib/quality/quality-visualization.test.d.ts +5 -0
- package/dist/lib/quality/quality-visualization.test.d.ts.map +1 -0
- package/dist/lib/quality/quality-visualization.test.js +189 -0
- package/dist/lib/quality/quality-visualization.test.js.map +1 -0
- package/dist/lib/resilience/cache.d.ts +56 -0
- package/dist/lib/resilience/cache.d.ts.map +1 -0
- package/dist/lib/resilience/cache.js +96 -0
- package/dist/lib/resilience/cache.js.map +1 -0
- package/dist/lib/resilience/cache.test.d.ts.map +1 -0
- package/dist/lib/{cache.test.js → resilience/cache.test.js} +21 -20
- package/dist/lib/resilience/cache.test.js.map +1 -0
- package/dist/lib/resilience/circuit-breaker.d.ts +147 -0
- package/dist/lib/resilience/circuit-breaker.d.ts.map +1 -0
- package/dist/lib/resilience/circuit-breaker.js +251 -0
- package/dist/lib/resilience/circuit-breaker.js.map +1 -0
- package/dist/lib/resilience/circuit-breaker.test.d.ts.map +1 -0
- package/dist/lib/{circuit-breaker.test.js → resilience/circuit-breaker.test.js} +29 -26
- package/dist/lib/resilience/circuit-breaker.test.js.map +1 -0
- package/dist/lib/{toon-encoder.d.ts → resilience/toon-encoder.d.ts} +6 -1
- package/dist/lib/resilience/toon-encoder.d.ts.map +1 -0
- package/dist/lib/{toon-encoder.js → resilience/toon-encoder.js} +7 -2
- package/dist/lib/resilience/toon-encoder.js.map +1 -0
- package/dist/lib/resilience/toon-encoder.test.d.ts.map +1 -0
- package/dist/lib/{toon-encoder.test.js → resilience/toon-encoder.test.js} +7 -6
- package/dist/lib/resilience/toon-encoder.test.js.map +1 -0
- package/dist/lib/testing/mock-llm-builder.d.ts +139 -0
- package/dist/lib/testing/mock-llm-builder.d.ts.map +1 -0
- package/dist/lib/testing/mock-llm-builder.js +254 -0
- package/dist/lib/testing/mock-llm-builder.js.map +1 -0
- package/dist/lib/testing/mock-llm-builder.test.d.ts +5 -0
- package/dist/lib/testing/mock-llm-builder.test.d.ts.map +1 -0
- package/dist/lib/testing/mock-llm-builder.test.js +304 -0
- package/dist/lib/testing/mock-llm-builder.test.js.map +1 -0
- package/dist/lib/validation/api-schemas.d.ts +705 -0
- package/dist/lib/validation/api-schemas.d.ts.map +1 -0
- package/dist/lib/validation/api-schemas.js +351 -0
- package/dist/lib/validation/api-schemas.js.map +1 -0
- package/dist/lib/validation/api-schemas.test.d.ts +5 -0
- package/dist/lib/validation/api-schemas.test.d.ts.map +1 -0
- package/dist/lib/validation/api-schemas.test.js +427 -0
- package/dist/lib/validation/api-schemas.test.js.map +1 -0
- package/dist/lib/validation/dashboard-schemas.d.ts +203 -0
- package/dist/lib/validation/dashboard-schemas.d.ts.map +1 -0
- package/dist/lib/validation/dashboard-schemas.js +186 -0
- package/dist/lib/validation/dashboard-schemas.js.map +1 -0
- package/dist/lib/validation/dashboard-schemas.test.d.ts +5 -0
- package/dist/lib/validation/dashboard-schemas.test.d.ts.map +1 -0
- package/dist/lib/validation/dashboard-schemas.test.js +353 -0
- package/dist/lib/validation/dashboard-schemas.test.js.map +1 -0
- package/dist/server.d.ts +7 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +172 -102
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +102 -95
- package/dist/server.test.js.map +1 -1
- package/dist/test-helpers/assertions.d.ts +6 -0
- package/dist/test-helpers/assertions.d.ts.map +1 -0
- package/dist/test-helpers/assertions.js +11 -0
- package/dist/test-helpers/assertions.js.map +1 -0
- package/dist/test-helpers/env-utils.d.ts +0 -64
- package/dist/test-helpers/env-utils.d.ts.map +1 -1
- package/dist/test-helpers/env-utils.js +0 -100
- package/dist/test-helpers/env-utils.js.map +1 -1
- package/dist/test-helpers/fuzz-generators.d.ts.map +1 -1
- package/dist/test-helpers/fuzz-generators.js +62 -22
- package/dist/test-helpers/fuzz-generators.js.map +1 -1
- package/dist/test-helpers/index.d.ts +3 -2
- package/dist/test-helpers/index.d.ts.map +1 -1
- package/dist/test-helpers/index.js +4 -2
- package/dist/test-helpers/index.js.map +1 -1
- package/dist/test-helpers/memfs-utils.test.js +81 -76
- package/dist/test-helpers/memfs-utils.test.js.map +1 -1
- package/dist/test-helpers/mock-backends.d.ts +19 -17
- package/dist/test-helpers/mock-backends.d.ts.map +1 -1
- package/dist/test-helpers/mock-backends.js +16 -4
- package/dist/test-helpers/mock-backends.js.map +1 -1
- package/dist/test-helpers/mock-backends.test.js +43 -112
- package/dist/test-helpers/mock-backends.test.js.map +1 -1
- package/dist/test-helpers/race-condition-helpers.d.ts.map +1 -1
- package/dist/test-helpers/race-condition-helpers.js +3 -2
- package/dist/test-helpers/race-condition-helpers.js.map +1 -1
- package/dist/test-helpers/schema-validators.d.ts +2 -2
- package/dist/test-helpers/schema-validators.d.ts.map +1 -1
- package/dist/test-helpers/schema-validators.js +35 -31
- package/dist/test-helpers/schema-validators.js.map +1 -1
- package/dist/test-helpers/test-constants.d.ts +74 -0
- package/dist/test-helpers/test-constants.d.ts.map +1 -0
- package/dist/test-helpers/test-constants.js +78 -0
- package/dist/test-helpers/test-constants.js.map +1 -0
- package/dist/test-helpers/test-data-builders.d.ts +25 -7
- package/dist/test-helpers/test-data-builders.d.ts.map +1 -1
- package/dist/test-helpers/test-data-builders.js +32 -9
- package/dist/test-helpers/test-data-builders.js.map +1 -1
- package/dist/test-helpers/test-data-builders.test.js +116 -107
- package/dist/test-helpers/test-data-builders.test.js.map +1 -1
- package/dist/test-helpers/tool-validators.d.ts +1 -1
- package/dist/test-helpers/tool-validators.d.ts.map +1 -1
- package/dist/test-helpers/tool-validators.js +10 -10
- package/dist/test-helpers/tool-validators.js.map +1 -1
- package/dist/tools/audit-trail.d.ts +170 -0
- package/dist/tools/audit-trail.d.ts.map +1 -0
- package/dist/tools/audit-trail.js +109 -0
- package/dist/tools/audit-trail.js.map +1 -0
- package/dist/tools/audit-trail.test.d.ts +5 -0
- package/dist/tools/audit-trail.test.d.ts.map +1 -0
- package/dist/tools/audit-trail.test.js +122 -0
- package/dist/tools/audit-trail.test.js.map +1 -0
- package/dist/tools/context-stats.d.ts +6 -20
- package/dist/tools/context-stats.d.ts.map +1 -1
- package/dist/tools/context-stats.js +106 -90
- package/dist/tools/context-stats.js.map +1 -1
- package/dist/tools/context-stats.test.js +109 -60
- package/dist/tools/context-stats.test.js.map +1 -1
- package/dist/tools/detect-trace-anomalies.d.ts +123 -0
- package/dist/tools/detect-trace-anomalies.d.ts.map +1 -0
- package/dist/tools/detect-trace-anomalies.js +66 -0
- package/dist/tools/detect-trace-anomalies.js.map +1 -0
- package/dist/tools/estimate-cost.d.ts +77 -0
- package/dist/tools/estimate-cost.d.ts.map +1 -0
- package/dist/tools/estimate-cost.js +104 -0
- package/dist/tools/estimate-cost.js.map +1 -0
- package/dist/tools/estimate-cost.test.d.ts +5 -0
- package/dist/tools/estimate-cost.test.d.ts.map +1 -0
- package/dist/tools/estimate-cost.test.js +343 -0
- package/dist/tools/estimate-cost.test.js.map +1 -0
- package/dist/tools/export-base.d.ts +77 -0
- package/dist/tools/export-base.d.ts.map +1 -0
- package/dist/tools/export-base.js +150 -0
- package/dist/tools/export-base.js.map +1 -0
- package/dist/tools/export-base.test.d.ts +18 -0
- package/dist/tools/export-base.test.d.ts.map +1 -0
- package/dist/tools/export-base.test.js +220 -0
- package/dist/tools/export-base.test.js.map +1 -0
- package/dist/tools/export-confident.d.ts +149 -0
- package/dist/tools/export-confident.d.ts.map +1 -0
- package/dist/tools/export-confident.js +36 -0
- package/dist/tools/export-confident.js.map +1 -0
- package/dist/tools/export-confident.test.d.ts +7 -0
- package/dist/tools/export-confident.test.d.ts.map +1 -0
- package/dist/tools/export-confident.test.js +336 -0
- package/dist/tools/export-confident.test.js.map +1 -0
- package/dist/tools/export-datadog.d.ts +121 -0
- package/dist/tools/export-datadog.d.ts.map +1 -0
- package/dist/tools/export-datadog.js +158 -0
- package/dist/tools/export-datadog.js.map +1 -0
- package/dist/tools/export-datadog.test.d.ts +8 -0
- package/dist/tools/export-datadog.test.d.ts.map +1 -0
- package/dist/tools/export-datadog.test.js +376 -0
- package/dist/tools/export-datadog.test.js.map +1 -0
- package/dist/tools/export-jaeger.d.ts +100 -0
- package/dist/tools/export-jaeger.d.ts.map +1 -0
- package/dist/tools/export-jaeger.js +154 -0
- package/dist/tools/export-jaeger.js.map +1 -0
- package/dist/tools/export-jaeger.test.d.ts +2 -0
- package/dist/tools/export-jaeger.test.d.ts.map +1 -0
- package/dist/tools/export-jaeger.test.js +113 -0
- package/dist/tools/export-jaeger.test.js.map +1 -0
- package/dist/tools/export-langfuse.d.ts +135 -0
- package/dist/tools/export-langfuse.d.ts.map +1 -0
- package/dist/tools/export-langfuse.js +33 -0
- package/dist/tools/export-langfuse.js.map +1 -0
- package/dist/tools/export-langfuse.test.d.ts +7 -0
- package/dist/tools/export-langfuse.test.d.ts.map +1 -0
- package/dist/tools/export-langfuse.test.js +292 -0
- package/dist/tools/export-langfuse.test.js.map +1 -0
- package/dist/tools/export-phoenix.d.ts +170 -0
- package/dist/tools/export-phoenix.d.ts.map +1 -0
- package/dist/tools/export-phoenix.js +47 -0
- package/dist/tools/export-phoenix.js.map +1 -0
- package/dist/tools/export-phoenix.test.d.ts +7 -0
- package/dist/tools/export-phoenix.test.d.ts.map +1 -0
- package/dist/tools/export-phoenix.test.js +317 -0
- package/dist/tools/export-phoenix.test.js.map +1 -0
- package/dist/tools/get-trace-url.d.ts +2 -10
- package/dist/tools/get-trace-url.d.ts.map +1 -1
- package/dist/tools/get-trace-url.js +5 -8
- package/dist/tools/get-trace-url.js.map +1 -1
- package/dist/tools/get-trace-url.test.js +81 -399
- package/dist/tools/get-trace-url.test.js.map +1 -1
- package/dist/tools/hallucination-detection.d.ts +203 -0
- package/dist/tools/hallucination-detection.d.ts.map +1 -0
- package/dist/tools/hallucination-detection.js +189 -0
- package/dist/tools/hallucination-detection.js.map +1 -0
- package/dist/tools/hallucination-detection.test.d.ts +5 -0
- package/dist/tools/hallucination-detection.test.d.ts.map +1 -0
- package/dist/tools/hallucination-detection.test.js +529 -0
- package/dist/tools/hallucination-detection.test.js.map +1 -0
- package/dist/tools/health-check.d.ts +35 -16
- package/dist/tools/health-check.d.ts.map +1 -1
- package/dist/tools/health-check.js +101 -85
- package/dist/tools/health-check.js.map +1 -1
- package/dist/tools/health-check.test.js +72 -165
- package/dist/tools/health-check.test.js.map +1 -1
- package/dist/tools/index.d.ts +19 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +19 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ingest-constants.d.ts +8 -0
- package/dist/tools/ingest-constants.d.ts.map +1 -0
- package/dist/tools/ingest-constants.js +8 -0
- package/dist/tools/ingest-constants.js.map +1 -0
- package/dist/tools/ingest-spans.d.ts +45 -0
- package/dist/tools/ingest-spans.d.ts.map +1 -0
- package/dist/tools/ingest-spans.js +129 -0
- package/dist/tools/ingest-spans.js.map +1 -0
- package/dist/tools/ingest-spans.test.d.ts +5 -0
- package/dist/tools/ingest-spans.test.d.ts.map +1 -0
- package/dist/tools/ingest-spans.test.js +250 -0
- package/dist/tools/ingest-spans.test.js.map +1 -0
- package/dist/tools/ingest-traces.d.ts +76 -0
- package/dist/tools/ingest-traces.d.ts.map +1 -0
- package/dist/tools/ingest-traces.js +164 -0
- package/dist/tools/ingest-traces.js.map +1 -0
- package/dist/tools/ingest-traces.test.d.ts +5 -0
- package/dist/tools/ingest-traces.test.d.ts.map +1 -0
- package/dist/tools/ingest-traces.test.js +483 -0
- package/dist/tools/ingest-traces.test.js.map +1 -0
- package/dist/tools/inject-evaluations.d.ts +254 -0
- package/dist/tools/inject-evaluations.d.ts.map +1 -0
- package/dist/tools/inject-evaluations.js +133 -0
- package/dist/tools/inject-evaluations.js.map +1 -0
- package/dist/tools/inject-evaluations.test.d.ts +5 -0
- package/dist/tools/inject-evaluations.test.d.ts.map +1 -0
- package/dist/tools/inject-evaluations.test.js +371 -0
- package/dist/tools/inject-evaluations.test.js.map +1 -0
- package/dist/tools/manage-datasets.d.ts +850 -0
- package/dist/tools/manage-datasets.d.ts.map +1 -0
- package/dist/tools/manage-datasets.js +139 -0
- package/dist/tools/manage-datasets.js.map +1 -0
- package/dist/tools/manage-datasets.test.d.ts +5 -0
- package/dist/tools/manage-datasets.test.d.ts.map +1 -0
- package/dist/tools/manage-datasets.test.js +430 -0
- package/dist/tools/manage-datasets.test.js.map +1 -0
- package/dist/tools/multi-agent-coordination.d.ts +178 -0
- package/dist/tools/multi-agent-coordination.d.ts.map +1 -0
- package/dist/tools/multi-agent-coordination.js +270 -0
- package/dist/tools/multi-agent-coordination.js.map +1 -0
- package/dist/tools/multi-agent-coordination.test.d.ts +5 -0
- package/dist/tools/multi-agent-coordination.test.d.ts.map +1 -0
- package/dist/tools/multi-agent-coordination.test.js +530 -0
- package/dist/tools/multi-agent-coordination.test.js.map +1 -0
- package/dist/tools/query-evaluations.d.ts +154 -91
- package/dist/tools/query-evaluations.d.ts.map +1 -1
- package/dist/tools/query-evaluations.js +206 -169
- package/dist/tools/query-evaluations.js.map +1 -1
- package/dist/tools/query-evaluations.test.js +386 -391
- package/dist/tools/query-evaluations.test.js.map +1 -1
- package/dist/tools/query-llm-events.d.ts +100 -75
- package/dist/tools/query-llm-events.d.ts.map +1 -1
- package/dist/tools/query-llm-events.js +106 -80
- package/dist/tools/query-llm-events.js.map +1 -1
- package/dist/tools/query-llm-events.test.js +183 -346
- package/dist/tools/query-llm-events.test.js.map +1 -1
- package/dist/tools/query-logs.d.ts +45 -58
- package/dist/tools/query-logs.d.ts.map +1 -1
- package/dist/tools/query-logs.js +54 -101
- package/dist/tools/query-logs.js.map +1 -1
- package/dist/tools/query-logs.test.js +118 -314
- package/dist/tools/query-logs.test.js.map +1 -1
- package/dist/tools/query-metric-histograms.d.ts +112 -0
- package/dist/tools/query-metric-histograms.d.ts.map +1 -0
- package/dist/tools/query-metric-histograms.js +69 -0
- package/dist/tools/query-metric-histograms.js.map +1 -0
- package/dist/tools/query-metric-histograms.test.d.ts +5 -0
- package/dist/tools/query-metric-histograms.test.d.ts.map +1 -0
- package/dist/tools/query-metric-histograms.test.js +209 -0
- package/dist/tools/query-metric-histograms.test.js.map +1 -0
- package/dist/tools/query-metrics.d.ts +159 -60
- package/dist/tools/query-metrics.d.ts.map +1 -1
- package/dist/tools/query-metrics.js +133 -111
- package/dist/tools/query-metrics.js.map +1 -1
- package/dist/tools/query-metrics.test.js +314 -389
- package/dist/tools/query-metrics.test.js.map +1 -1
- package/dist/tools/query-regressions.d.ts +76 -0
- package/dist/tools/query-regressions.d.ts.map +1 -0
- package/dist/tools/query-regressions.js +122 -0
- package/dist/tools/query-regressions.js.map +1 -0
- package/dist/tools/query-regressions.test.d.ts +8 -0
- package/dist/tools/query-regressions.test.d.ts.map +1 -0
- package/dist/tools/query-regressions.test.js +129 -0
- package/dist/tools/query-regressions.test.js.map +1 -0
- package/dist/tools/query-traces.d.ts +103 -71
- package/dist/tools/query-traces.d.ts.map +1 -1
- package/dist/tools/query-traces.js +75 -106
- package/dist/tools/query-traces.js.map +1 -1
- package/dist/tools/query-traces.test.js +140 -846
- package/dist/tools/query-traces.test.js.map +1 -1
- package/dist/tools/query-verifications.d.ts +123 -0
- package/dist/tools/query-verifications.d.ts.map +1 -0
- package/dist/tools/query-verifications.js +102 -0
- package/dist/tools/query-verifications.js.map +1 -0
- package/dist/tools/query-verifications.test.d.ts +5 -0
- package/dist/tools/query-verifications.test.d.ts.map +1 -0
- package/dist/tools/query-verifications.test.js +163 -0
- package/dist/tools/query-verifications.test.js.map +1 -0
- package/dist/tools/routing-telemetry.d.ts +168 -0
- package/dist/tools/routing-telemetry.d.ts.map +1 -0
- package/dist/tools/routing-telemetry.js +267 -0
- package/dist/tools/routing-telemetry.js.map +1 -0
- package/dist/tools/routing-telemetry.test.d.ts +5 -0
- package/dist/tools/routing-telemetry.test.d.ts.map +1 -0
- package/dist/tools/routing-telemetry.test.js +747 -0
- package/dist/tools/routing-telemetry.test.js.map +1 -0
- package/dist/tools/setup-claudeignore.d.ts +4 -32
- package/dist/tools/setup-claudeignore.d.ts.map +1 -1
- package/dist/tools/setup-claudeignore.js +18 -22
- package/dist/tools/setup-claudeignore.js.map +1 -1
- package/dist/tools/setup-claudeignore.test.js +50 -49
- package/dist/tools/setup-claudeignore.test.js.map +1 -1
- package/dist/tools/token-budget.d.ts +170 -0
- package/dist/tools/token-budget.d.ts.map +1 -0
- package/dist/tools/token-budget.js +219 -0
- package/dist/tools/token-budget.js.map +1 -0
- package/dist/tools/token-budget.test.d.ts +5 -0
- package/dist/tools/token-budget.test.d.ts.map +1 -0
- package/dist/tools/token-budget.test.js +293 -0
- package/dist/tools/token-budget.test.js.map +1 -0
- package/package.json +76 -6
- package/dist/backends/local-jsonl.test.d.ts +0 -2
- package/dist/backends/local-jsonl.test.d.ts.map +0 -1
- package/dist/backends/local-jsonl.test.js +0 -4651
- package/dist/backends/local-jsonl.test.js.map +0 -1
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts +0 -6
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts.map +0 -1
- package/dist/backends/signoz-api-circuit-breaker.test.js +0 -548
- package/dist/backends/signoz-api-circuit-breaker.test.js.map +0 -1
- package/dist/backends/signoz-api-rate-limiter.test.d.ts +0 -6
- package/dist/backends/signoz-api-rate-limiter.test.d.ts.map +0 -1
- package/dist/backends/signoz-api-rate-limiter.test.js +0 -389
- package/dist/backends/signoz-api-rate-limiter.test.js.map +0 -1
- package/dist/backends/signoz-api-ssrf.test.d.ts +0 -6
- package/dist/backends/signoz-api-ssrf.test.d.ts.map +0 -1
- package/dist/backends/signoz-api-ssrf.test.js +0 -216
- package/dist/backends/signoz-api-ssrf.test.js.map +0 -1
- package/dist/backends/signoz-api-test-helpers.d.ts +0 -80
- package/dist/backends/signoz-api-test-helpers.d.ts.map +0 -1
- package/dist/backends/signoz-api-test-helpers.js +0 -79
- package/dist/backends/signoz-api-test-helpers.js.map +0 -1
- package/dist/backends/signoz-api.d.ts +0 -95
- package/dist/backends/signoz-api.d.ts.map +0 -1
- package/dist/backends/signoz-api.integration.test.d.ts +0 -8
- package/dist/backends/signoz-api.integration.test.d.ts.map +0 -1
- package/dist/backends/signoz-api.integration.test.js +0 -137
- package/dist/backends/signoz-api.integration.test.js.map +0 -1
- package/dist/backends/signoz-api.js +0 -1016
- package/dist/backends/signoz-api.js.map +0 -1
- package/dist/backends/signoz-api.test.d.ts +0 -11
- package/dist/backends/signoz-api.test.d.ts.map +0 -1
- package/dist/backends/signoz-api.test.js +0 -831
- package/dist/backends/signoz-api.test.js.map +0 -1
- package/dist/lib/cache.d.ts +0 -77
- package/dist/lib/cache.d.ts.map +0 -1
- package/dist/lib/cache.js +0 -119
- package/dist/lib/cache.js.map +0 -1
- package/dist/lib/cache.test.d.ts.map +0 -1
- package/dist/lib/cache.test.js.map +0 -1
- package/dist/lib/circuit-breaker.d.ts +0 -83
- package/dist/lib/circuit-breaker.d.ts.map +0 -1
- package/dist/lib/circuit-breaker.js +0 -125
- package/dist/lib/circuit-breaker.js.map +0 -1
- package/dist/lib/circuit-breaker.test.d.ts.map +0 -1
- package/dist/lib/circuit-breaker.test.js.map +0 -1
- package/dist/lib/constants-symlink.test.d.ts.map +0 -1
- package/dist/lib/constants-symlink.test.js.map +0 -1
- package/dist/lib/constants.d.ts +0 -108
- package/dist/lib/constants.d.ts.map +0 -1
- package/dist/lib/constants.js +0 -350
- package/dist/lib/constants.js.map +0 -1
- package/dist/lib/constants.test.d.ts.map +0 -1
- package/dist/lib/constants.test.js.map +0 -1
- package/dist/lib/edge-cases.test.d.ts.map +0 -1
- package/dist/lib/edge-cases.test.js.map +0 -1
- package/dist/lib/error-sanitizer.d.ts.map +0 -1
- package/dist/lib/error-sanitizer.js.map +0 -1
- package/dist/lib/error-sanitizer.test.d.ts.map +0 -1
- package/dist/lib/error-sanitizer.test.js.map +0 -1
- package/dist/lib/error-types.d.ts.map +0 -1
- package/dist/lib/error-types.js.map +0 -1
- package/dist/lib/error-types.test.d.ts.map +0 -1
- package/dist/lib/error-types.test.js.map +0 -1
- package/dist/lib/file-utils.d.ts.map +0 -1
- package/dist/lib/file-utils.js.map +0 -1
- package/dist/lib/file-utils.test.d.ts.map +0 -1
- package/dist/lib/file-utils.test.js.map +0 -1
- package/dist/lib/indexer.d.ts +0 -96
- package/dist/lib/indexer.d.ts.map +0 -1
- package/dist/lib/indexer.js.map +0 -1
- package/dist/lib/indexer.test.d.ts.map +0 -1
- package/dist/lib/indexer.test.js.map +0 -1
- package/dist/lib/input-validator.d.ts.map +0 -1
- package/dist/lib/input-validator.fuzz.test.d.ts.map +0 -1
- package/dist/lib/input-validator.fuzz.test.js.map +0 -1
- package/dist/lib/input-validator.js.map +0 -1
- package/dist/lib/input-validator.test.d.ts.map +0 -1
- package/dist/lib/input-validator.test.js.map +0 -1
- package/dist/lib/logger.d.ts.map +0 -1
- package/dist/lib/logger.js +0 -81
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/logger.test.d.ts.map +0 -1
- package/dist/lib/logger.test.js.map +0 -1
- package/dist/lib/otlp-export.d.ts.map +0 -1
- package/dist/lib/otlp-export.js.map +0 -1
- package/dist/lib/query-sanitizer.d.ts.map +0 -1
- package/dist/lib/query-sanitizer.js.map +0 -1
- package/dist/lib/query-sanitizer.test.d.ts.map +0 -1
- package/dist/lib/query-sanitizer.test.js.map +0 -1
- package/dist/lib/server-utils.d.ts.map +0 -1
- package/dist/lib/server-utils.js.map +0 -1
- package/dist/lib/shared-schemas.d.ts +0 -81
- package/dist/lib/shared-schemas.d.ts.map +0 -1
- package/dist/lib/shared-schemas.js +0 -80
- package/dist/lib/shared-schemas.js.map +0 -1
- package/dist/lib/shared-schemas.test.d.ts.map +0 -1
- package/dist/lib/shared-schemas.test.js.map +0 -1
- package/dist/lib/toon-encoder.d.ts.map +0 -1
- package/dist/lib/toon-encoder.js.map +0 -1
- package/dist/lib/toon-encoder.test.d.ts.map +0 -1
- package/dist/lib/toon-encoder.test.js.map +0 -1
- package/dist/tools/signoz.integration.test.d.ts +0 -8
- package/dist/tools/signoz.integration.test.d.ts.map +0 -1
- package/dist/tools/signoz.integration.test.js +0 -141
- package/dist/tools/signoz.integration.test.js.map +0 -1
- /package/dist/lib/{constants-symlink.test.d.ts → core/constants-symlink.test.d.ts} +0 -0
- /package/dist/lib/{constants.test.d.ts → core/constants.test.d.ts} +0 -0
- /package/dist/lib/{edge-cases.test.d.ts → core/edge-cases.test.d.ts} +0 -0
- /package/dist/lib/{file-utils.test.d.ts → core/file-utils.test.d.ts} +0 -0
- /package/dist/lib/{input-validator.fuzz.test.d.ts → core/input-validator.fuzz.test.d.ts} +0 -0
- /package/dist/lib/{input-validator.test.d.ts → core/input-validator.test.d.ts} +0 -0
- /package/dist/lib/{logger.test.d.ts → core/logger.test.d.ts} +0 -0
- /package/dist/lib/{logger.test.js → core/logger.test.js} +0 -0
- /package/dist/lib/{shared-schemas.test.d.ts → core/shared-schemas.test.d.ts} +0 -0
- /package/dist/lib/{error-sanitizer.test.d.ts → errors/error-sanitizer.test.d.ts} +0 -0
- /package/dist/lib/{error-types.test.d.ts → errors/error-types.test.d.ts} +0 -0
- /package/dist/lib/{query-sanitizer.d.ts → errors/query-sanitizer.d.ts} +0 -0
- /package/dist/lib/{query-sanitizer.test.d.ts → errors/query-sanitizer.test.d.ts} +0 -0
- /package/dist/lib/{indexer.test.d.ts → observability/indexer.test.d.ts} +0 -0
- /package/dist/lib/{cache.test.d.ts → resilience/cache.test.d.ts} +0 -0
- /package/dist/lib/{circuit-breaker.test.d.ts → resilience/circuit-breaker.test.d.ts} +0 -0
- /package/dist/lib/{toon-encoder.test.d.ts → resilience/toon-encoder.test.d.ts} +0 -0
|
@@ -0,0 +1,747 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for routing-telemetry tool (R8)
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it } from 'vitest';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { ROUTING_ATTRIBUTES } from '../backends/index.js';
|
|
7
|
+
import { createTraceBackend } from '../test-helpers/mock-backends.js';
|
|
8
|
+
import { routingTelemetry, routingTelemetrySchema, ROUTING_TELEMETRY_DEFAULT_LIMIT } from './routing-telemetry.js';
|
|
9
|
+
import { ONE_MILLION, ROUND_4DP_FACTOR } from '../lib/core/units.js';
|
|
10
|
+
import { MODEL_PRICING } from '../lib/core/constants-models.js';
|
|
11
|
+
import { SHORT_ID_LENGTH } from '../lib/core/constants.js';
|
|
12
|
+
import { RANDOM_STRING_RADIX, RANDOM_SUFFIX_START } from '../test-helpers/test-constants.js';
|
|
13
|
+
// ---------- test constants ----------
|
|
14
|
+
const ID_SLICE_START = RANDOM_SUFFIX_START;
|
|
15
|
+
const ID_SLICE_END = SHORT_ID_LENGTH;
|
|
16
|
+
const SPAN_DURATION_MS = 100;
|
|
17
|
+
const CLASSIFICATION_TIME_MS = 42;
|
|
18
|
+
// model fixtures
|
|
19
|
+
const MODEL_AUTO = 'auto';
|
|
20
|
+
const MODEL_GPT4O = 'gpt-4o';
|
|
21
|
+
const MODEL_GPT4O_MINI = 'gpt-4o-mini';
|
|
22
|
+
const MODEL_CLAUDE_OPUS = 'claude-opus-4-6';
|
|
23
|
+
const MODEL_CLAUDE_HAIKU = 'claude-haiku-4-5-20251001';
|
|
24
|
+
// token fixtures
|
|
25
|
+
const INPUT_TOKENS_SMALL = 1_000;
|
|
26
|
+
const OUTPUT_TOKENS_SMALL = 200;
|
|
27
|
+
const INPUT_TOKENS_LARGE = 5_000;
|
|
28
|
+
const OUTPUT_TOKENS_LARGE = 1_000;
|
|
29
|
+
// routing attribute fixtures
|
|
30
|
+
const STRATEGY_COST = 'cost_optimized';
|
|
31
|
+
const STRATEGY_PERF = 'performance';
|
|
32
|
+
// expected counts
|
|
33
|
+
const EXPECTED_ONE = 1;
|
|
34
|
+
const EXPECTED_TWO = 2;
|
|
35
|
+
const EXPECTED_THREE = 3;
|
|
36
|
+
// expected fallback rate (1 out of 2 = 0.5)
|
|
37
|
+
const EXPECTED_FALLBACK_RATE_HALF = 0.5;
|
|
38
|
+
const EXPECTED_FULL_FALLBACK_RATE = 1;
|
|
39
|
+
// ---------- helpers ----------
|
|
40
|
+
function makeSpan(overrides) {
|
|
41
|
+
const duration = overrides.durationMs ?? SPAN_DURATION_MS;
|
|
42
|
+
return {
|
|
43
|
+
traceId: overrides.traceId ?? 'trace-1',
|
|
44
|
+
spanId: `span-${Math.random().toString(RANDOM_STRING_RADIX).slice(ID_SLICE_START, ID_SLICE_END)}`,
|
|
45
|
+
name: 'chat',
|
|
46
|
+
startTimeUnixNano: Date.now() * ONE_MILLION,
|
|
47
|
+
endTimeUnixNano: (Date.now() + duration) * ONE_MILLION,
|
|
48
|
+
durationMs: duration,
|
|
49
|
+
attributes: {
|
|
50
|
+
'gen_ai.request.model': overrides.requestModel,
|
|
51
|
+
...(overrides.responseModel !== undefined && {
|
|
52
|
+
'gen_ai.response.model': overrides.responseModel,
|
|
53
|
+
}),
|
|
54
|
+
...(overrides.inputTokens !== undefined && {
|
|
55
|
+
'gen_ai.usage.input_tokens': overrides.inputTokens,
|
|
56
|
+
}),
|
|
57
|
+
...(overrides.outputTokens !== undefined && {
|
|
58
|
+
'gen_ai.usage.output_tokens': overrides.outputTokens,
|
|
59
|
+
}),
|
|
60
|
+
...(overrides.strategy !== undefined && {
|
|
61
|
+
'routing.strategy': overrides.strategy,
|
|
62
|
+
}),
|
|
63
|
+
...(overrides.fallbackTriggered !== undefined && {
|
|
64
|
+
'routing.fallback_triggered': overrides.fallbackTriggered,
|
|
65
|
+
}),
|
|
66
|
+
...(overrides.classificationTimeMs !== undefined && {
|
|
67
|
+
'routing.classification.time_ms': overrides.classificationTimeMs,
|
|
68
|
+
}),
|
|
69
|
+
...(overrides.finishReasons !== undefined && {
|
|
70
|
+
'gen_ai.response.finish_reasons': overrides.finishReasons,
|
|
71
|
+
}),
|
|
72
|
+
...(overrides.provider !== undefined && {
|
|
73
|
+
'gen_ai.provider.name': overrides.provider,
|
|
74
|
+
}),
|
|
75
|
+
...(overrides.system !== undefined && {
|
|
76
|
+
'gen_ai.system': overrides.system,
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function makeBackend(spans) {
|
|
82
|
+
const store = { local: spans };
|
|
83
|
+
return createTraceBackend(store, 'local');
|
|
84
|
+
}
|
|
85
|
+
function isNoData(r) {
|
|
86
|
+
return r.kind === 'no-data';
|
|
87
|
+
}
|
|
88
|
+
function isResult(r) {
|
|
89
|
+
return r.kind === 'result';
|
|
90
|
+
}
|
|
91
|
+
// ---------- schema ----------
|
|
92
|
+
void describe('routingTelemetrySchema', () => {
|
|
93
|
+
void it('should accept empty input with defaults', () => {
|
|
94
|
+
const result = routingTelemetrySchema.parse({});
|
|
95
|
+
assert.strictEqual(result.backend, 'cloud');
|
|
96
|
+
assert.strictEqual(result.groupBy, 'model_pair');
|
|
97
|
+
assert.strictEqual(result.limit, ROUTING_TELEMETRY_DEFAULT_LIMIT);
|
|
98
|
+
});
|
|
99
|
+
void it('should accept groupBy strategy', () => {
|
|
100
|
+
const result = routingTelemetrySchema.parse({ groupBy: 'strategy' });
|
|
101
|
+
assert.strictEqual(result.groupBy, 'strategy');
|
|
102
|
+
});
|
|
103
|
+
void it('should reject invalid groupBy value', () => {
|
|
104
|
+
assert.throws(() => routingTelemetrySchema.parse({ groupBy: 'invalid' }));
|
|
105
|
+
});
|
|
106
|
+
void it('should accept optional model filter', () => {
|
|
107
|
+
const result = routingTelemetrySchema.parse({ model: MODEL_GPT4O });
|
|
108
|
+
assert.strictEqual(result.model, MODEL_GPT4O);
|
|
109
|
+
});
|
|
110
|
+
void it('should accept startDate and endDate filters', () => {
|
|
111
|
+
const result = routingTelemetrySchema.parse({
|
|
112
|
+
startDate: '2026-01-01',
|
|
113
|
+
endDate: '2026-03-01',
|
|
114
|
+
});
|
|
115
|
+
assert.strictEqual(result.startDate, '2026-01-01');
|
|
116
|
+
assert.strictEqual(result.endDate, '2026-03-01');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
// ---------- handler ----------
|
|
120
|
+
void describe('routingTelemetry', () => {
|
|
121
|
+
void it('should return no-routing message when all spans have matching request/response models', async () => {
|
|
122
|
+
const backend = makeBackend([
|
|
123
|
+
makeSpan({ requestModel: MODEL_GPT4O, responseModel: MODEL_GPT4O }),
|
|
124
|
+
makeSpan({ requestModel: MODEL_CLAUDE_OPUS, responseModel: MODEL_CLAUDE_OPUS }),
|
|
125
|
+
]);
|
|
126
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
127
|
+
assert.ok(isNoData(result), 'should return a no-data result indicating no routing');
|
|
128
|
+
assert.ok(result.message.toLowerCase().includes('no routing') || result.message.toLowerCase().includes('routing decisions'), `unexpected message: ${result.message}`);
|
|
129
|
+
});
|
|
130
|
+
void it('should return no-routing message when backend has no spans', async () => {
|
|
131
|
+
const backend = makeBackend([]);
|
|
132
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
133
|
+
assert.ok(isNoData(result), 'should return a no-data result for empty backend');
|
|
134
|
+
});
|
|
135
|
+
void it('should detect routing decisions where request model differs from response model', async () => {
|
|
136
|
+
const backend = makeBackend([
|
|
137
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
138
|
+
]);
|
|
139
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
140
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
141
|
+
assert.strictEqual(result.summary.routedSpans, EXPECTED_ONE);
|
|
142
|
+
});
|
|
143
|
+
void it('should include routing pair in results', async () => {
|
|
144
|
+
const backend = makeBackend([
|
|
145
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
146
|
+
]);
|
|
147
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
148
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
149
|
+
const group = result.groups[0];
|
|
150
|
+
assert.ok(group, 'should have at least one group');
|
|
151
|
+
assert.ok(('requestedModel' in group && group.requestedModel === MODEL_AUTO) || ('pair' in group && group.pair.includes(MODEL_AUTO)) || JSON.stringify(group).includes(MODEL_AUTO), 'routing pair should reference the requested model');
|
|
152
|
+
assert.ok(('actualModel' in group && group.actualModel === MODEL_GPT4O) || ('pair' in group && group.pair.includes(MODEL_GPT4O)) || JSON.stringify(group).includes(MODEL_GPT4O), 'routing pair should reference the actual model');
|
|
153
|
+
});
|
|
154
|
+
void it('should skip spans missing response model', async () => {
|
|
155
|
+
const backend = makeBackend([
|
|
156
|
+
makeSpan({ requestModel: MODEL_AUTO }),
|
|
157
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
158
|
+
]);
|
|
159
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
160
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
161
|
+
assert.strictEqual(result.summary.routedSpans, EXPECTED_ONE);
|
|
162
|
+
});
|
|
163
|
+
void it('should compute model distribution counting actual models selected', async () => {
|
|
164
|
+
const backend = makeBackend([
|
|
165
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
166
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
167
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O_MINI }),
|
|
168
|
+
]);
|
|
169
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
170
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
171
|
+
assert.ok(result.modelDistribution, 'should include model distribution');
|
|
172
|
+
const gpt4oCount = result.modelDistribution[MODEL_GPT4O];
|
|
173
|
+
assert.ok(gpt4oCount !== undefined, 'gpt-4o should appear in distribution');
|
|
174
|
+
assert.strictEqual(gpt4oCount, EXPECTED_TWO);
|
|
175
|
+
});
|
|
176
|
+
void it('should compute fallback rate from routing.fallback_triggered spans', async () => {
|
|
177
|
+
const backend = makeBackend([
|
|
178
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, fallbackTriggered: true }),
|
|
179
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, fallbackTriggered: false }),
|
|
180
|
+
]);
|
|
181
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
182
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
183
|
+
assert.strictEqual(result.summary.fallbackRate, EXPECTED_FALLBACK_RATE_HALF);
|
|
184
|
+
});
|
|
185
|
+
void it('should compute P50 and P99 routing latency when classification time is present', async () => {
|
|
186
|
+
const spans = Array.from({ length: 10 }, (_, i) => makeSpan({
|
|
187
|
+
requestModel: MODEL_AUTO,
|
|
188
|
+
responseModel: MODEL_GPT4O,
|
|
189
|
+
classificationTimeMs: (i + 1) * 10,
|
|
190
|
+
}));
|
|
191
|
+
const backend = makeBackend(spans);
|
|
192
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
193
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
194
|
+
assert.ok(result.routingLatency, 'should include routing latency stats');
|
|
195
|
+
// HdrHistogram: input [10,20,...,100]
|
|
196
|
+
// p50: 50% of 10 = 5th value = 50
|
|
197
|
+
// p99: 99% of 10 → 10th value = 100
|
|
198
|
+
const EXPECTED_P50 = 50;
|
|
199
|
+
const EXPECTED_P99 = 100;
|
|
200
|
+
assert.strictEqual(result.routingLatency.p50, EXPECTED_P50, 'p50 should be 50');
|
|
201
|
+
assert.strictEqual(result.routingLatency.p99, EXPECTED_P99, `p99 should be 100, got ${result.routingLatency.p99}`);
|
|
202
|
+
assert.ok(result.routingLatency.p99 >= result.routingLatency.p50, 'p99 should be >= p50');
|
|
203
|
+
});
|
|
204
|
+
void it('should fallback to span durationMs when no spans have classification.time_ms (R8-F6)', async () => {
|
|
205
|
+
const backend = makeBackend([
|
|
206
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
207
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
208
|
+
]);
|
|
209
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
210
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
211
|
+
assert.ok(result.routingLatency, 'should have routing latency from span duration fallback');
|
|
212
|
+
assert.strictEqual(result.routingLatency.p50, SPAN_DURATION_MS, 'p50 should equal span durationMs');
|
|
213
|
+
assert.strictEqual(result.routingLatency.p99, SPAN_DURATION_MS, 'p99 should equal span durationMs');
|
|
214
|
+
assert.strictEqual(result.routingLatency.source, 'span_duration', 'source should indicate span_duration fallback');
|
|
215
|
+
});
|
|
216
|
+
void it('should compute routing latency from varied span durations (R8-F6-L2)', async () => {
|
|
217
|
+
// 10 spans with durationMs = 10,20,...,100 — no classificationTimeMs → fallback path
|
|
218
|
+
const spans = Array.from({ length: 10 }, (_, i) => makeSpan({
|
|
219
|
+
requestModel: MODEL_AUTO,
|
|
220
|
+
responseModel: MODEL_GPT4O,
|
|
221
|
+
durationMs: (i + 1) * 10,
|
|
222
|
+
}));
|
|
223
|
+
const backend = makeBackend(spans);
|
|
224
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
225
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
226
|
+
assert.ok(result.routingLatency, 'should have routing latency from span duration fallback');
|
|
227
|
+
assert.strictEqual(result.routingLatency.source, 'span_duration', 'source should indicate span_duration fallback');
|
|
228
|
+
// HdrHistogram: input [10,20,...,100]
|
|
229
|
+
// p50: 50% of 10 = 5th value = 50
|
|
230
|
+
const EXPECTED_P50 = 50;
|
|
231
|
+
assert.strictEqual(result.routingLatency.p50, EXPECTED_P50, 'p50 should be 50');
|
|
232
|
+
// p99: 99% of 10 → 10th value = 100
|
|
233
|
+
const EXPECTED_P99 = 100;
|
|
234
|
+
assert.strictEqual(result.routingLatency.p99, EXPECTED_P99, `p99 should be 100, got ${result.routingLatency.p99}`);
|
|
235
|
+
});
|
|
236
|
+
void it('should prefer classification.time_ms over durationMs when both present (R8-F6)', async () => {
|
|
237
|
+
const backend = makeBackend([
|
|
238
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, classificationTimeMs: CLASSIFICATION_TIME_MS }),
|
|
239
|
+
]);
|
|
240
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
241
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
242
|
+
assert.ok(result.routingLatency, 'should have routing latency');
|
|
243
|
+
assert.strictEqual(result.routingLatency.p50, CLASSIFICATION_TIME_MS, 'should use classification time, not durationMs');
|
|
244
|
+
assert.strictEqual(result.routingLatency.source, 'classification_time', 'source should indicate classification_time');
|
|
245
|
+
});
|
|
246
|
+
void it('should group by model pair when groupBy is model_pair', async () => {
|
|
247
|
+
const backend = makeBackend([
|
|
248
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
249
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
250
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O_MINI }),
|
|
251
|
+
]);
|
|
252
|
+
const result = await routingTelemetry({ backend: 'local', groupBy: 'model_pair' }, { localBackend: backend });
|
|
253
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
254
|
+
assert.strictEqual(result.groups.length, EXPECTED_TWO);
|
|
255
|
+
const gpt4oGroup = result.groups.find((g) => ('actualModel' in g && g.actualModel === MODEL_GPT4O) || ('pair' in g && g.pair.includes(MODEL_GPT4O)));
|
|
256
|
+
assert.ok(gpt4oGroup, 'gpt-4o group should exist');
|
|
257
|
+
assert.strictEqual(gpt4oGroup.count, EXPECTED_TWO);
|
|
258
|
+
});
|
|
259
|
+
void it('should group by strategy when groupBy is strategy', async () => {
|
|
260
|
+
const backend = makeBackend([
|
|
261
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, strategy: STRATEGY_COST }),
|
|
262
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O_MINI, strategy: STRATEGY_COST }),
|
|
263
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_OPUS, strategy: STRATEGY_PERF }),
|
|
264
|
+
]);
|
|
265
|
+
const result = await routingTelemetry({ backend: 'local', groupBy: 'strategy' }, { localBackend: backend });
|
|
266
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
267
|
+
assert.strictEqual(result.groups.length, EXPECTED_TWO);
|
|
268
|
+
const costGroup = result.groups.find((g) => 'strategy' in g && g.strategy === STRATEGY_COST);
|
|
269
|
+
assert.ok(costGroup, 'cost_optimized group should exist');
|
|
270
|
+
assert.strictEqual(costGroup.count, EXPECTED_TWO);
|
|
271
|
+
});
|
|
272
|
+
void it('should include per-strategy fallbackCount and fallbackRate (R8-F7)', async () => {
|
|
273
|
+
const backend = makeBackend([
|
|
274
|
+
// cost_optimized: 1/2 fallback → rate 0.5
|
|
275
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, strategy: STRATEGY_COST, fallbackTriggered: true }),
|
|
276
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O_MINI, strategy: STRATEGY_COST, fallbackTriggered: false }),
|
|
277
|
+
// performance: 0/1 fallback → rate 0
|
|
278
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_OPUS, strategy: STRATEGY_PERF, fallbackTriggered: false }),
|
|
279
|
+
]);
|
|
280
|
+
const result = await routingTelemetry({ backend: 'local', groupBy: 'strategy' }, { localBackend: backend });
|
|
281
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
282
|
+
assert.strictEqual(result.groups.length, EXPECTED_TWO);
|
|
283
|
+
const costGroup = result.groups.find((g) => 'strategy' in g && g.strategy === STRATEGY_COST);
|
|
284
|
+
assert.ok(costGroup && 'fallbackCount' in costGroup, 'cost group should have fallbackCount');
|
|
285
|
+
assert.strictEqual(costGroup.fallbackCount, EXPECTED_ONE, 'cost group should have 1 fallback');
|
|
286
|
+
assert.strictEqual(costGroup.fallbackRate, EXPECTED_FALLBACK_RATE_HALF, 'cost group fallback rate should be 0.5');
|
|
287
|
+
const perfGroup = result.groups.find((g) => 'strategy' in g && g.strategy === STRATEGY_PERF);
|
|
288
|
+
assert.ok(perfGroup && 'fallbackRate' in perfGroup, 'perf group should have fallbackRate');
|
|
289
|
+
assert.strictEqual(perfGroup.fallbackCount, 0, 'perf group should have 0 fallbacks');
|
|
290
|
+
assert.strictEqual(perfGroup.fallbackRate, 0, 'perf group fallback rate should be 0');
|
|
291
|
+
});
|
|
292
|
+
void it('should include providerDistribution and per-group provider from gen_ai.provider.name (R8-F4)', async () => {
|
|
293
|
+
const backend = makeBackend([
|
|
294
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, provider: 'openai' }),
|
|
295
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O_MINI, provider: 'openai' }),
|
|
296
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_OPUS, provider: 'anthropic' }),
|
|
297
|
+
]);
|
|
298
|
+
const result = await routingTelemetry({ backend: 'local', groupBy: 'model_pair' }, { localBackend: backend });
|
|
299
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
300
|
+
assert.ok(result.providerDistribution, 'should include providerDistribution');
|
|
301
|
+
assert.strictEqual(result.providerDistribution['openai'], EXPECTED_TWO, 'openai should have 2 spans');
|
|
302
|
+
assert.strictEqual(result.providerDistribution['anthropic'], EXPECTED_ONE, 'anthropic should have 1 span');
|
|
303
|
+
// Model pair groups should carry provider
|
|
304
|
+
const opusGroup = result.groups.find((g) => 'actualModel' in g && g.actualModel === MODEL_CLAUDE_OPUS);
|
|
305
|
+
assert.ok(opusGroup && 'provider' in opusGroup, 'opus group should have provider');
|
|
306
|
+
assert.strictEqual(opusGroup.provider, 'anthropic');
|
|
307
|
+
});
|
|
308
|
+
void it('should fallback to gen_ai.system when gen_ai.provider.name is absent (R8-F4)', async () => {
|
|
309
|
+
const backend = makeBackend([
|
|
310
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, system: 'openai' }),
|
|
311
|
+
]);
|
|
312
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
313
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
314
|
+
assert.strictEqual(result.providerDistribution['openai'], EXPECTED_ONE, 'should resolve provider from gen_ai.system');
|
|
315
|
+
});
|
|
316
|
+
void it('should use (unknown) provider when neither gen_ai.provider.name nor gen_ai.system present (R8-F4)', async () => {
|
|
317
|
+
const backend = makeBackend([
|
|
318
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
319
|
+
]);
|
|
320
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
321
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
322
|
+
assert.strictEqual(result.providerDistribution['(unknown)'], EXPECTED_ONE, 'should count as (unknown)');
|
|
323
|
+
// Model pair group should have null provider
|
|
324
|
+
const group = result.groups[0];
|
|
325
|
+
assert.ok(group && 'provider' in group, 'group should have provider field');
|
|
326
|
+
assert.strictEqual(group.provider, null, 'provider should be null when absent');
|
|
327
|
+
});
|
|
328
|
+
void it('should filter by model name matching either request or response model', async () => {
|
|
329
|
+
const backend = makeBackend([
|
|
330
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
331
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_HAIKU }),
|
|
332
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
333
|
+
]);
|
|
334
|
+
const result = await routingTelemetry({ backend: 'local', model: MODEL_GPT4O }, { localBackend: backend });
|
|
335
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
336
|
+
assert.strictEqual(result.summary.routedSpans, EXPECTED_TWO);
|
|
337
|
+
});
|
|
338
|
+
void it('should compute cost savings comparing actual vs hypothetical expensive-model cost', async () => {
|
|
339
|
+
const backend = makeBackend([
|
|
340
|
+
makeSpan({
|
|
341
|
+
requestModel: MODEL_AUTO,
|
|
342
|
+
responseModel: MODEL_GPT4O_MINI,
|
|
343
|
+
inputTokens: INPUT_TOKENS_LARGE,
|
|
344
|
+
outputTokens: OUTPUT_TOKENS_LARGE,
|
|
345
|
+
}),
|
|
346
|
+
makeSpan({
|
|
347
|
+
requestModel: MODEL_AUTO,
|
|
348
|
+
responseModel: MODEL_GPT4O,
|
|
349
|
+
inputTokens: INPUT_TOKENS_SMALL,
|
|
350
|
+
outputTokens: OUTPUT_TOKENS_SMALL,
|
|
351
|
+
}),
|
|
352
|
+
]);
|
|
353
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
354
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
355
|
+
assert.ok(typeof result.costSavings === 'number', 'cost savings should be a number');
|
|
356
|
+
assert.ok(result.costSavings >= 0, 'cost savings should be non-negative');
|
|
357
|
+
});
|
|
358
|
+
void it('should include total routed span count in summary', async () => {
|
|
359
|
+
const backend = makeBackend([
|
|
360
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
361
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
362
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_HAIKU }),
|
|
363
|
+
]);
|
|
364
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
365
|
+
assert.ok(isResult(result), 'should return a full result');
|
|
366
|
+
assert.strictEqual(result.summary.routedSpans, EXPECTED_THREE);
|
|
367
|
+
});
|
|
368
|
+
void it('should include tool name obs_routing_telemetry in routingTelemetryTool export', async () => {
|
|
369
|
+
const { routingTelemetryTool } = await import('./routing-telemetry.js');
|
|
370
|
+
assert.strictEqual(routingTelemetryTool.name, 'obs_routing_telemetry');
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
// ---------- regression tests (review findings) ----------
|
|
374
|
+
void describe('H1/F1 — phantom pricing baseline', () => {
|
|
375
|
+
void it('should use single most expensive model by total cost, not mixed input/output', async () => {
|
|
376
|
+
// Model A: high input ($10), low output ($5) → total $15
|
|
377
|
+
// Model B: low input ($2), high output ($12) → total $14
|
|
378
|
+
// Phantom bug would pick input=$10 + output=$12 = $22 (wrong)
|
|
379
|
+
// Fix picks Model A (total $15) → hypothetical uses {input: 10, output: 5}
|
|
380
|
+
MODEL_PRICING['phantom-model-a'] = { input: 10, output: 5, provider: 'test' };
|
|
381
|
+
MODEL_PRICING['phantom-model-b'] = { input: 2, output: 12, provider: 'test' };
|
|
382
|
+
const spans = [
|
|
383
|
+
makeSpan({
|
|
384
|
+
requestModel: MODEL_AUTO,
|
|
385
|
+
responseModel: 'phantom-model-a',
|
|
386
|
+
inputTokens: 1_000_000,
|
|
387
|
+
outputTokens: 1_000_000,
|
|
388
|
+
}),
|
|
389
|
+
makeSpan({
|
|
390
|
+
requestModel: MODEL_AUTO,
|
|
391
|
+
responseModel: 'phantom-model-b',
|
|
392
|
+
inputTokens: 1_000_000,
|
|
393
|
+
outputTokens: 1_000_000,
|
|
394
|
+
}),
|
|
395
|
+
];
|
|
396
|
+
const backend = makeBackend(spans);
|
|
397
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
398
|
+
assert.ok(isResult(result));
|
|
399
|
+
// Actual: model-a (10+5=15) + model-b (2+12=14) = 29
|
|
400
|
+
// Hypothetical (model-a pair): 2 * (10+5) = 30
|
|
401
|
+
// Savings = 30 - 29 = 1
|
|
402
|
+
assert.strictEqual(result.costSavings, 1);
|
|
403
|
+
delete MODEL_PRICING['phantom-model-a'];
|
|
404
|
+
delete MODEL_PRICING['phantom-model-b'];
|
|
405
|
+
});
|
|
406
|
+
void it('should round costSavings to 4 decimal places (F5)', async () => {
|
|
407
|
+
MODEL_PRICING['round-cheap'] = { input: 0.001, output: 0.001, provider: 'test' };
|
|
408
|
+
MODEL_PRICING['round-pricey'] = { input: 0.003, output: 0.003, provider: 'test' };
|
|
409
|
+
const spans = [
|
|
410
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: 'round-cheap', inputTokens: 333, outputTokens: 333 }),
|
|
411
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: 'round-pricey', inputTokens: 333, outputTokens: 333 }),
|
|
412
|
+
];
|
|
413
|
+
const backend = makeBackend(spans);
|
|
414
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
415
|
+
assert.ok(isResult(result));
|
|
416
|
+
// costSavings * ROUND_4DP_FACTOR should be integer (no more than 4dp)
|
|
417
|
+
assert.strictEqual(result.costSavings * ROUND_4DP_FACTOR, Math.round(result.costSavings * ROUND_4DP_FACTOR));
|
|
418
|
+
delete MODEL_PRICING['round-cheap'];
|
|
419
|
+
delete MODEL_PRICING['round-pricey'];
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
void describe('M2/M3 — numeric coercion for OTLP string attributes', () => {
|
|
423
|
+
void it('should handle string token counts from OTLP JSON (M2)', async () => {
|
|
424
|
+
const spans = [
|
|
425
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
426
|
+
];
|
|
427
|
+
// Simulate OTLP string values by overwriting attributes
|
|
428
|
+
const span0 = spans[0];
|
|
429
|
+
assert(span0 !== undefined && span0.attributes !== undefined, 'span0 and its attributes must exist');
|
|
430
|
+
span0.attributes['gen_ai.usage.input_tokens'] = '1000';
|
|
431
|
+
span0.attributes['gen_ai.usage.output_tokens'] = '500';
|
|
432
|
+
const backend = makeBackend(spans);
|
|
433
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
434
|
+
assert.ok(isResult(result));
|
|
435
|
+
assert.ok(Number.isFinite(result.costSavings), 'costSavings should not be NaN');
|
|
436
|
+
assert.ok(result.costSavings >= 0, 'costSavings should be non-negative');
|
|
437
|
+
});
|
|
438
|
+
void it('should handle string classificationTimeMs (M3)', async () => {
|
|
439
|
+
const spans = [
|
|
440
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
441
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
442
|
+
];
|
|
443
|
+
const m3span0 = spans[0];
|
|
444
|
+
const m3span1 = spans[1];
|
|
445
|
+
assert(m3span0?.attributes !== undefined && m3span1?.attributes !== undefined, 'spans and attributes must exist');
|
|
446
|
+
m3span0.attributes['routing.classification.time_ms'] = '42.5';
|
|
447
|
+
m3span1.attributes['routing.classification.time_ms'] = '100';
|
|
448
|
+
const backend = makeBackend(spans);
|
|
449
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
450
|
+
assert.ok(isResult(result));
|
|
451
|
+
assert.ok(result.routingLatency, 'should have routing latency');
|
|
452
|
+
assert.ok(result.routingLatency.p50 > 0, 'p50 should be positive');
|
|
453
|
+
assert.ok(result.routingLatency.p99 > 0, 'p99 should be positive');
|
|
454
|
+
});
|
|
455
|
+
void it('should treat non-numeric token values as 0', async () => {
|
|
456
|
+
const spans = [
|
|
457
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
458
|
+
];
|
|
459
|
+
const m4span0 = spans[0];
|
|
460
|
+
assert(m4span0?.attributes !== undefined, 'span0 and its attributes must exist');
|
|
461
|
+
m4span0.attributes['gen_ai.usage.input_tokens'] = 'not-a-number';
|
|
462
|
+
m4span0.attributes['gen_ai.usage.output_tokens'] = undefined;
|
|
463
|
+
const backend = makeBackend(spans);
|
|
464
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
465
|
+
assert.ok(isResult(result));
|
|
466
|
+
assert.ok(Number.isFinite(result.costSavings), 'should not produce NaN');
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
void describe('F3 — ROUTING_ATTRIBUTES exported constants', () => {
|
|
470
|
+
void it('should export routing attribute keys from backends/index', () => {
|
|
471
|
+
assert.strictEqual(ROUTING_ATTRIBUTES.STRATEGY, 'routing.strategy');
|
|
472
|
+
assert.strictEqual(ROUTING_ATTRIBUTES.FALLBACK_TRIGGERED, 'routing.fallback_triggered');
|
|
473
|
+
assert.strictEqual(ROUTING_ATTRIBUTES.CLASSIFICATION_TIME_MS, 'routing.classification.time_ms');
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
void describe('F8 — unknown models in MODEL_PRICING', () => {
|
|
477
|
+
void it('should produce costSavings=0 when all models are unknown (no pricing data)', async () => {
|
|
478
|
+
const backend = makeBackend([
|
|
479
|
+
makeSpan({
|
|
480
|
+
requestModel: 'unknown-model-x',
|
|
481
|
+
responseModel: 'unknown-model-y',
|
|
482
|
+
inputTokens: INPUT_TOKENS_LARGE,
|
|
483
|
+
outputTokens: OUTPUT_TOKENS_LARGE,
|
|
484
|
+
}),
|
|
485
|
+
]);
|
|
486
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
487
|
+
assert.ok(isResult(result));
|
|
488
|
+
assert.strictEqual(result.costSavings, 0, 'unknown models should produce zero cost savings');
|
|
489
|
+
});
|
|
490
|
+
void it('should inflate savings when only some models are unknown (actualCost=0 for unknown)', async () => {
|
|
491
|
+
const backend = makeBackend([
|
|
492
|
+
makeSpan({
|
|
493
|
+
requestModel: MODEL_AUTO,
|
|
494
|
+
responseModel: 'unknown-model-z',
|
|
495
|
+
inputTokens: INPUT_TOKENS_LARGE,
|
|
496
|
+
outputTokens: OUTPUT_TOKENS_LARGE,
|
|
497
|
+
}),
|
|
498
|
+
makeSpan({
|
|
499
|
+
requestModel: MODEL_AUTO,
|
|
500
|
+
responseModel: MODEL_GPT4O,
|
|
501
|
+
inputTokens: INPUT_TOKENS_SMALL,
|
|
502
|
+
outputTokens: OUTPUT_TOKENS_SMALL,
|
|
503
|
+
}),
|
|
504
|
+
]);
|
|
505
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
506
|
+
assert.ok(isResult(result));
|
|
507
|
+
// Unknown model contributes 0 to actualCost but hypothetical uses gpt-4o pricing → savings inflated
|
|
508
|
+
assert.ok(result.costSavings > 0, 'savings inflated when unknown model produces zero actual cost');
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
void describe('F10 — finish_reasons fallback signal', () => {
|
|
512
|
+
void it('should detect fallback from content_filter finish reason', async () => {
|
|
513
|
+
const backend = makeBackend([
|
|
514
|
+
makeSpan({
|
|
515
|
+
requestModel: MODEL_AUTO,
|
|
516
|
+
responseModel: MODEL_GPT4O,
|
|
517
|
+
finishReasons: ['content_filter'],
|
|
518
|
+
}),
|
|
519
|
+
makeSpan({
|
|
520
|
+
requestModel: MODEL_AUTO,
|
|
521
|
+
responseModel: MODEL_GPT4O,
|
|
522
|
+
finishReasons: ['stop'],
|
|
523
|
+
}),
|
|
524
|
+
]);
|
|
525
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
526
|
+
assert.ok(isResult(result));
|
|
527
|
+
assert.strictEqual(result.summary.fallbackRate, EXPECTED_FALLBACK_RATE_HALF, 'content_filter should count as fallback');
|
|
528
|
+
});
|
|
529
|
+
void it('should detect fallback from length finish reason', async () => {
|
|
530
|
+
const backend = makeBackend([
|
|
531
|
+
makeSpan({
|
|
532
|
+
requestModel: MODEL_AUTO,
|
|
533
|
+
responseModel: MODEL_GPT4O,
|
|
534
|
+
finishReasons: ['length'],
|
|
535
|
+
}),
|
|
536
|
+
]);
|
|
537
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
538
|
+
assert.ok(isResult(result));
|
|
539
|
+
assert.strictEqual(result.summary.fallbackRate, EXPECTED_FULL_FALLBACK_RATE, 'length should count as fallback');
|
|
540
|
+
});
|
|
541
|
+
void it('should not double-count when both fallbackTriggered and finish_reasons indicate fallback', async () => {
|
|
542
|
+
const backend = makeBackend([
|
|
543
|
+
makeSpan({
|
|
544
|
+
requestModel: MODEL_AUTO,
|
|
545
|
+
responseModel: MODEL_GPT4O,
|
|
546
|
+
fallbackTriggered: true,
|
|
547
|
+
finishReasons: ['content_filter'],
|
|
548
|
+
}),
|
|
549
|
+
]);
|
|
550
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
551
|
+
assert.ok(isResult(result));
|
|
552
|
+
assert.strictEqual(result.summary.fallbackRate, EXPECTED_FULL_FALLBACK_RATE, 'should count as single fallback');
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
void describe('F12 — totalSpansScanned field', () => {
|
|
556
|
+
void it('should include totalSpansScanned in no-data result', async () => {
|
|
557
|
+
const TOTAL_SPANS = 3;
|
|
558
|
+
const backend = makeBackend([
|
|
559
|
+
makeSpan({ requestModel: MODEL_GPT4O, responseModel: MODEL_GPT4O }),
|
|
560
|
+
makeSpan({ requestModel: MODEL_GPT4O, responseModel: MODEL_GPT4O }),
|
|
561
|
+
makeSpan({ requestModel: MODEL_GPT4O, responseModel: MODEL_GPT4O }),
|
|
562
|
+
]);
|
|
563
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
564
|
+
assert.ok(isNoData(result));
|
|
565
|
+
assert.strictEqual(result.totalSpansScanned, TOTAL_SPANS);
|
|
566
|
+
});
|
|
567
|
+
void it('should include totalSpansScanned in result', async () => {
|
|
568
|
+
const TOTAL_SPANS = 3;
|
|
569
|
+
const backend = makeBackend([
|
|
570
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O }),
|
|
571
|
+
makeSpan({ requestModel: MODEL_GPT4O, responseModel: MODEL_GPT4O }),
|
|
572
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_HAIKU }),
|
|
573
|
+
]);
|
|
574
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
575
|
+
assert.ok(isResult(result));
|
|
576
|
+
assert.strictEqual(result.totalSpansScanned, TOTAL_SPANS);
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
// ============================================================================
|
|
580
|
+
// Stress Tests (ST-R8)
|
|
581
|
+
// ============================================================================
|
|
582
|
+
// MAX_QUERY_LIMIT = 1000; use max to stress the routing at full capacity
|
|
583
|
+
const ST_R8_SPAN_COUNT = 1_000;
|
|
584
|
+
const ST_R8_UNIQUE_MODELS = 8;
|
|
585
|
+
const ST_R8_REQUEST_MODELS = ['auto', 'router', 'gpt-4-turbo', 'claude-3'];
|
|
586
|
+
const ST_R8_RESPONSE_MODELS = [
|
|
587
|
+
MODEL_GPT4O,
|
|
588
|
+
MODEL_GPT4O_MINI,
|
|
589
|
+
MODEL_CLAUDE_OPUS,
|
|
590
|
+
MODEL_CLAUDE_HAIKU,
|
|
591
|
+
'claude-3-5-sonnet-20241022',
|
|
592
|
+
'gpt-4-turbo',
|
|
593
|
+
'claude-3-haiku-20240307',
|
|
594
|
+
'claude-3-opus-20240229',
|
|
595
|
+
];
|
|
596
|
+
function makeStressSpan(i) {
|
|
597
|
+
const requestModel = ST_R8_REQUEST_MODELS[i % ST_R8_REQUEST_MODELS.length];
|
|
598
|
+
const responseModel = ST_R8_RESPONSE_MODELS[i % ST_R8_UNIQUE_MODELS];
|
|
599
|
+
return makeSpan({
|
|
600
|
+
requestModel,
|
|
601
|
+
responseModel,
|
|
602
|
+
inputTokens: 500 + (i % 2000),
|
|
603
|
+
outputTokens: 100 + (i % 500),
|
|
604
|
+
strategy: i % 3 === 0 ? STRATEGY_COST : (i % 3 === 1 ? STRATEGY_PERF : undefined),
|
|
605
|
+
fallbackTriggered: i % 7 === 0,
|
|
606
|
+
classificationTimeMs: i % 5 === 0 ? 10 + (i % 50) : undefined,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
void describe('routingTelemetry stress (ST-R8)', () => {
|
|
610
|
+
void it('high-volume (1K spans at max limit): produces a result and all numeric fields are finite', async () => {
|
|
611
|
+
const spans = Array.from({ length: ST_R8_SPAN_COUNT }, (_, i) => makeStressSpan(i));
|
|
612
|
+
const backend = makeBackend(spans);
|
|
613
|
+
const result = await routingTelemetry({ backend: 'local', limit: ST_R8_SPAN_COUNT }, { localBackend: backend });
|
|
614
|
+
assert.ok(isResult(result), `expected result, got no-data for ${ST_R8_SPAN_COUNT} spans`);
|
|
615
|
+
if (!isResult(result))
|
|
616
|
+
return;
|
|
617
|
+
assert.ok(isFinite(result.costSavings), `costSavings should be finite, got ${result.costSavings}`);
|
|
618
|
+
assert.ok(result.costSavings >= 0, `costSavings should be non-negative, got ${result.costSavings}`);
|
|
619
|
+
assert.ok(isFinite(result.summary.fallbackRate), `fallbackRate should be finite`);
|
|
620
|
+
assert.ok(result.summary.fallbackRate >= 0 && result.summary.fallbackRate <= 1, `fallbackRate ${result.summary.fallbackRate} out of [0,1]`);
|
|
621
|
+
});
|
|
622
|
+
void it('high-volume: modelDistribution has exactly the expected unique models', async () => {
|
|
623
|
+
const spans = Array.from({ length: ST_R8_SPAN_COUNT }, (_, i) => makeStressSpan(i));
|
|
624
|
+
const backend = makeBackend(spans);
|
|
625
|
+
const result = await routingTelemetry({ backend: 'local', limit: ST_R8_SPAN_COUNT }, { localBackend: backend });
|
|
626
|
+
assert.ok(isResult(result));
|
|
627
|
+
if (!isResult(result))
|
|
628
|
+
return;
|
|
629
|
+
// All 8 response models should appear (ST_R8_SPAN_COUNT / ST_R8_UNIQUE_MODELS = 125 each)
|
|
630
|
+
assert.strictEqual(Object.keys(result.modelDistribution).length, ST_R8_UNIQUE_MODELS, `expected ${ST_R8_UNIQUE_MODELS} unique models in distribution`);
|
|
631
|
+
});
|
|
632
|
+
void it('unknown model in pricing table: costSavings is 0 and does not throw', async () => {
|
|
633
|
+
const spans = [
|
|
634
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: 'unknown-future-model-xyz', inputTokens: 1000, outputTokens: 200 }),
|
|
635
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: 'another-unknown-model', inputTokens: 1000, outputTokens: 200 }),
|
|
636
|
+
];
|
|
637
|
+
const backend = makeBackend(spans);
|
|
638
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
639
|
+
assert.ok(isResult(result), 'should return result (not no-data) for unknown-model spans');
|
|
640
|
+
if (!isResult(result))
|
|
641
|
+
return;
|
|
642
|
+
// Unknown models have no pricing → computeCost returns 0 → savings = max(0, 0-0) = 0
|
|
643
|
+
assert.strictEqual(result.costSavings, 0, 'cost savings should be 0 when models have no pricing entry');
|
|
644
|
+
});
|
|
645
|
+
void it('string-typed OTLP attributes: token counts parsed from strings work correctly', async () => {
|
|
646
|
+
// OTLP attributes may arrive as strings rather than numbers in some SDK versions
|
|
647
|
+
const spanWithStringAttrs = {
|
|
648
|
+
traceId: 'trace-str',
|
|
649
|
+
spanId: 'span-str',
|
|
650
|
+
name: 'chat',
|
|
651
|
+
startTimeUnixNano: Date.now() * 1_000_000,
|
|
652
|
+
endTimeUnixNano: (Date.now() + 100) * 1_000_000,
|
|
653
|
+
durationMs: 100,
|
|
654
|
+
attributes: {
|
|
655
|
+
'gen_ai.request.model': MODEL_AUTO,
|
|
656
|
+
'gen_ai.response.model': MODEL_GPT4O,
|
|
657
|
+
'gen_ai.usage.input_tokens': '1000', // string-typed
|
|
658
|
+
'gen_ai.usage.output_tokens': '200', // string-typed
|
|
659
|
+
'routing.fallback_triggered': 'true', // string-typed bool
|
|
660
|
+
},
|
|
661
|
+
};
|
|
662
|
+
const backend = makeBackend([spanWithStringAttrs]);
|
|
663
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
664
|
+
assert.ok(isResult(result), 'should handle string-typed OTLP attributes');
|
|
665
|
+
if (!isResult(result))
|
|
666
|
+
return;
|
|
667
|
+
// String 'true' for fallback_triggered should be parsed as true
|
|
668
|
+
assert.strictEqual(result.summary.fallbackRate, 1, 'string "true" fallback_triggered should count as fallback');
|
|
669
|
+
// Token costs should be computed correctly from string-parsed numbers
|
|
670
|
+
assert.ok(result.costSavings >= 0, 'costSavings should be non-negative with string tokens');
|
|
671
|
+
});
|
|
672
|
+
void it('identical values produce p50 = p99 (no NaN or divide-by-zero)', async () => {
|
|
673
|
+
// All spans have the same classificationTimeMs — identical values case
|
|
674
|
+
const SPAN_COUNT = 100;
|
|
675
|
+
const spans = Array.from({ length: SPAN_COUNT }, () => makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, classificationTimeMs: CLASSIFICATION_TIME_MS }));
|
|
676
|
+
const backend = makeBackend(spans);
|
|
677
|
+
const result = await routingTelemetry({ backend: 'local', limit: SPAN_COUNT }, { localBackend: backend });
|
|
678
|
+
assert.ok(isResult(result));
|
|
679
|
+
if (!isResult(result))
|
|
680
|
+
return;
|
|
681
|
+
assert.ok(result.routingLatency !== undefined, 'routingLatency should be defined');
|
|
682
|
+
if (!result.routingLatency)
|
|
683
|
+
return;
|
|
684
|
+
assert.strictEqual(result.routingLatency.p50, CLASSIFICATION_TIME_MS, `p50 should be ${CLASSIFICATION_TIME_MS} for identical values`);
|
|
685
|
+
assert.strictEqual(result.routingLatency.p99, CLASSIFICATION_TIME_MS, `p99 should be ${CLASSIFICATION_TIME_MS} for identical values`);
|
|
686
|
+
assert.ok(isFinite(result.routingLatency.p50), 'p50 should be finite');
|
|
687
|
+
assert.ok(isFinite(result.routingLatency.p99), 'p99 should be finite');
|
|
688
|
+
});
|
|
689
|
+
void it('single-span array returns the span value for p50 and p99', async () => {
|
|
690
|
+
const SINGLE_MS = 77;
|
|
691
|
+
const backend = makeBackend([
|
|
692
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, classificationTimeMs: SINGLE_MS }),
|
|
693
|
+
]);
|
|
694
|
+
const result = await routingTelemetry({ backend: 'local' }, { localBackend: backend });
|
|
695
|
+
assert.ok(isResult(result));
|
|
696
|
+
if (!isResult(result))
|
|
697
|
+
return;
|
|
698
|
+
assert.ok(result.routingLatency !== undefined);
|
|
699
|
+
assert.strictEqual(result.routingLatency?.p50, SINGLE_MS, `p50 should equal the single value (${SINGLE_MS})`);
|
|
700
|
+
assert.strictEqual(result.routingLatency?.p99, SINGLE_MS, `p99 should equal the single value (${SINGLE_MS})`);
|
|
701
|
+
});
|
|
702
|
+
void it('cost savings accuracy: cheaper model saves the expected amount vs expensive baseline', async () => {
|
|
703
|
+
const PRICING_GPT4O = MODEL_PRICING[MODEL_GPT4O];
|
|
704
|
+
const PRICING_HAIKU = MODEL_PRICING[MODEL_CLAUDE_HAIKU];
|
|
705
|
+
if (!PRICING_GPT4O || !PRICING_HAIKU) {
|
|
706
|
+
// Skip if either model is not in pricing table
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const INPUT_TOKENS = 10_000;
|
|
710
|
+
const OUTPUT_TOKENS = 2_000;
|
|
711
|
+
const CHEAP_SPAN_COUNT = 100;
|
|
712
|
+
// Most spans route 'auto' → haiku (cheap); one span routes 'auto' → gpt-4o (expensive baseline).
|
|
713
|
+
// Cost savings are computed vs the most expensive response model per request model.
|
|
714
|
+
// Both are routed (auto ≠ haiku, auto ≠ gpt-4o), so both are included in routedSpans.
|
|
715
|
+
const spans = [
|
|
716
|
+
...Array.from({ length: CHEAP_SPAN_COUNT }, () => makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_CLAUDE_HAIKU, inputTokens: INPUT_TOKENS, outputTokens: OUTPUT_TOKENS })),
|
|
717
|
+
makeSpan({ requestModel: MODEL_AUTO, responseModel: MODEL_GPT4O, inputTokens: INPUT_TOKENS, outputTokens: OUTPUT_TOKENS }),
|
|
718
|
+
];
|
|
719
|
+
const backend = makeBackend(spans);
|
|
720
|
+
const result = await routingTelemetry({ backend: 'local', limit: CHEAP_SPAN_COUNT + 1 }, { localBackend: backend });
|
|
721
|
+
assert.ok(isResult(result));
|
|
722
|
+
if (!isResult(result))
|
|
723
|
+
return;
|
|
724
|
+
// With haiku cheaper than gpt-4o, savings should be positive
|
|
725
|
+
assert.ok(result.costSavings > 0, `cost savings should be positive when routing to cheaper model, got ${result.costSavings}`);
|
|
726
|
+
});
|
|
727
|
+
void it('high cardinality: 20 unique (request, response) model pairs produce non-empty groups', async () => {
|
|
728
|
+
const UNIQUE_PAIRS = 20;
|
|
729
|
+
const spans = Array.from({ length: UNIQUE_PAIRS * 50 }, (_, i) => {
|
|
730
|
+
const pairIdx = Math.floor(i / 50);
|
|
731
|
+
return makeSpan({
|
|
732
|
+
requestModel: `request-model-${pairIdx}`,
|
|
733
|
+
responseModel: `response-model-${pairIdx}`,
|
|
734
|
+
inputTokens: 1000,
|
|
735
|
+
outputTokens: 200,
|
|
736
|
+
});
|
|
737
|
+
});
|
|
738
|
+
const backend = makeBackend(spans);
|
|
739
|
+
const result = await routingTelemetry({ backend: 'local', limit: UNIQUE_PAIRS * 50, groupBy: 'model_pair' }, { localBackend: backend });
|
|
740
|
+
assert.ok(isResult(result));
|
|
741
|
+
if (!isResult(result))
|
|
742
|
+
return;
|
|
743
|
+
assert.ok(result.groups.length > 0, 'groups should be non-empty for high cardinality inputs');
|
|
744
|
+
assert.ok(isFinite(result.costSavings), 'costSavings should be finite for high cardinality');
|
|
745
|
+
});
|
|
746
|
+
});
|
|
747
|
+
//# sourceMappingURL=routing-telemetry.test.js.map
|