observability-toolkit 1.8.4 → 2.0.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 +126 -5
- package/dist/backends/index.d.ts +163 -0
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +57 -0
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/index.test.js +55 -1
- package/dist/backends/index.test.js.map +1 -1
- package/dist/backends/local-jsonl-boolean-search.test.js +8 -8
- package/dist/backends/local-jsonl-boolean-search.test.js.map +1 -1
- package/dist/backends/local-jsonl-cache.test.d.ts +2 -0
- package/dist/backends/local-jsonl-cache.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-cache.test.js +295 -0
- package/dist/backends/local-jsonl-cache.test.js.map +1 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.d.ts +2 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.js +180 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.js.map +1 -0
- package/dist/backends/local-jsonl-export.test.d.ts +2 -0
- package/dist/backends/local-jsonl-export.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-export.test.js +704 -0
- package/dist/backends/local-jsonl-export.test.js.map +1 -0
- package/dist/backends/local-jsonl-index.test.d.ts +2 -0
- package/dist/backends/local-jsonl-index.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-index.test.js +554 -0
- package/dist/backends/local-jsonl-index.test.js.map +1 -0
- package/dist/backends/local-jsonl-logs.test.js +52 -43
- package/dist/backends/local-jsonl-logs.test.js.map +1 -1
- package/dist/backends/local-jsonl-metrics.test.d.ts +2 -0
- package/dist/backends/local-jsonl-metrics.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-metrics.test.js +876 -0
- package/dist/backends/local-jsonl-metrics.test.js.map +1 -0
- package/dist/backends/local-jsonl-traces.test.js +89 -83
- package/dist/backends/local-jsonl-traces.test.js.map +1 -1
- package/dist/backends/local-jsonl.d.ts +39 -0
- package/dist/backends/local-jsonl.d.ts.map +1 -1
- package/dist/backends/local-jsonl.js +975 -492
- package/dist/backends/local-jsonl.js.map +1 -1
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts +6 -0
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-circuit-breaker.test.js +548 -0
- package/dist/backends/signoz-api-circuit-breaker.test.js.map +1 -0
- package/dist/backends/signoz-api-rate-limiter.test.d.ts +6 -0
- package/dist/backends/signoz-api-rate-limiter.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-rate-limiter.test.js +390 -0
- package/dist/backends/signoz-api-rate-limiter.test.js.map +1 -0
- package/dist/backends/signoz-api-ssrf.test.d.ts +6 -0
- package/dist/backends/signoz-api-ssrf.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-ssrf.test.js +216 -0
- package/dist/backends/signoz-api-ssrf.test.js.map +1 -0
- package/dist/backends/signoz-api-test-helpers.d.ts +80 -0
- package/dist/backends/signoz-api-test-helpers.d.ts.map +1 -0
- package/dist/backends/signoz-api-test-helpers.js +79 -0
- package/dist/backends/signoz-api-test-helpers.js.map +1 -0
- package/dist/backends/signoz-api.d.ts +31 -1
- package/dist/backends/signoz-api.d.ts.map +1 -1
- package/dist/backends/signoz-api.js +717 -539
- package/dist/backends/signoz-api.js.map +1 -1
- package/dist/backends/signoz-api.test.d.ts +9 -0
- package/dist/backends/signoz-api.test.d.ts.map +1 -1
- package/dist/backends/signoz-api.test.js +20 -1032
- package/dist/backends/signoz-api.test.js.map +1 -1
- package/dist/lib/agent-as-judge.d.ts +388 -0
- package/dist/lib/agent-as-judge.d.ts.map +1 -0
- package/dist/lib/agent-as-judge.js +740 -0
- package/dist/lib/agent-as-judge.js.map +1 -0
- package/dist/lib/agent-as-judge.test.d.ts +5 -0
- package/dist/lib/agent-as-judge.test.d.ts.map +1 -0
- package/dist/lib/agent-as-judge.test.js +816 -0
- package/dist/lib/agent-as-judge.test.js.map +1 -0
- package/dist/lib/cache.d.ts +61 -2
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +54 -3
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/circuit-breaker.d.ts +101 -0
- package/dist/lib/circuit-breaker.d.ts.map +1 -0
- package/dist/lib/circuit-breaker.js +158 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/circuit-breaker.test.d.ts +2 -0
- package/dist/lib/circuit-breaker.test.d.ts.map +1 -0
- package/dist/lib/circuit-breaker.test.js +263 -0
- package/dist/lib/circuit-breaker.test.js.map +1 -0
- package/dist/lib/confident-export.d.ts +101 -0
- package/dist/lib/confident-export.d.ts.map +1 -0
- package/dist/lib/confident-export.js +393 -0
- package/dist/lib/confident-export.js.map +1 -0
- package/dist/lib/confident-export.test.d.ts +7 -0
- package/dist/lib/confident-export.test.d.ts.map +1 -0
- package/dist/lib/confident-export.test.js +835 -0
- package/dist/lib/confident-export.test.js.map +1 -0
- package/dist/lib/constants-symlink.test.d.ts +12 -0
- package/dist/lib/constants-symlink.test.d.ts.map +1 -0
- package/dist/lib/constants-symlink.test.js +357 -0
- package/dist/lib/constants-symlink.test.js.map +1 -0
- package/dist/lib/constants.d.ts +75 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +104 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/datadog-export.d.ts +156 -0
- package/dist/lib/datadog-export.d.ts.map +1 -0
- package/dist/lib/datadog-export.js +464 -0
- package/dist/lib/datadog-export.js.map +1 -0
- package/dist/lib/datadog-export.test.d.ts +14 -0
- package/dist/lib/datadog-export.test.d.ts.map +1 -0
- package/dist/lib/datadog-export.test.js +890 -0
- package/dist/lib/datadog-export.test.js.map +1 -0
- package/dist/lib/edge-cases.test.js +17 -17
- package/dist/lib/edge-cases.test.js.map +1 -1
- package/dist/lib/error-sanitizer.d.ts.map +1 -1
- package/dist/lib/error-sanitizer.js +29 -3
- package/dist/lib/error-sanitizer.js.map +1 -1
- package/dist/lib/error-sanitizer.test.js +159 -0
- package/dist/lib/error-sanitizer.test.js.map +1 -1
- package/dist/lib/error-types.d.ts +54 -0
- package/dist/lib/error-types.d.ts.map +1 -0
- package/dist/lib/error-types.js +154 -0
- package/dist/lib/error-types.js.map +1 -0
- package/dist/lib/error-types.test.d.ts +2 -0
- package/dist/lib/error-types.test.d.ts.map +1 -0
- package/dist/lib/error-types.test.js +196 -0
- package/dist/lib/error-types.test.js.map +1 -0
- package/dist/lib/evaluation-hooks.d.ts +49 -0
- package/dist/lib/evaluation-hooks.d.ts.map +1 -0
- package/dist/lib/evaluation-hooks.js +488 -0
- package/dist/lib/evaluation-hooks.js.map +1 -0
- package/dist/lib/evaluation-hooks.test.d.ts +8 -0
- package/dist/lib/evaluation-hooks.test.d.ts.map +1 -0
- package/dist/lib/evaluation-hooks.test.js +624 -0
- package/dist/lib/evaluation-hooks.test.js.map +1 -0
- package/dist/lib/export-utils.d.ts +99 -0
- package/dist/lib/export-utils.d.ts.map +1 -0
- package/dist/lib/export-utils.js +238 -0
- package/dist/lib/export-utils.js.map +1 -0
- package/dist/lib/export-utils.test.d.ts +5 -0
- package/dist/lib/export-utils.test.d.ts.map +1 -0
- package/dist/lib/export-utils.test.js +193 -0
- package/dist/lib/export-utils.test.js.map +1 -0
- package/dist/lib/file-utils.d.ts +17 -2
- package/dist/lib/file-utils.d.ts.map +1 -1
- package/dist/lib/file-utils.js +24 -5
- package/dist/lib/file-utils.js.map +1 -1
- package/dist/lib/file-utils.test.js +30 -0
- package/dist/lib/file-utils.test.js.map +1 -1
- package/dist/lib/histogram.d.ts +119 -0
- package/dist/lib/histogram.d.ts.map +1 -0
- package/dist/lib/histogram.js +202 -0
- package/dist/lib/histogram.js.map +1 -0
- package/dist/lib/histogram.test.d.ts +5 -0
- package/dist/lib/histogram.test.d.ts.map +1 -0
- package/dist/lib/histogram.test.js +381 -0
- package/dist/lib/histogram.test.js.map +1 -0
- package/dist/lib/indexer.test.js +27 -27
- package/dist/lib/indexer.test.js.map +1 -1
- package/dist/lib/input-validator.d.ts +12 -0
- package/dist/lib/input-validator.d.ts.map +1 -1
- package/dist/lib/input-validator.fuzz.test.d.ts +12 -0
- package/dist/lib/input-validator.fuzz.test.d.ts.map +1 -0
- package/dist/lib/input-validator.fuzz.test.js +290 -0
- package/dist/lib/input-validator.fuzz.test.js.map +1 -0
- package/dist/lib/input-validator.js +57 -3
- package/dist/lib/input-validator.js.map +1 -1
- package/dist/lib/input-validator.test.js +129 -1
- package/dist/lib/input-validator.test.js.map +1 -1
- package/dist/lib/instrumentation.d.ts +153 -0
- package/dist/lib/instrumentation.d.ts.map +1 -0
- package/dist/lib/instrumentation.integration.test.d.ts +2 -0
- package/dist/lib/instrumentation.integration.test.d.ts.map +1 -0
- package/dist/lib/instrumentation.integration.test.js +589 -0
- package/dist/lib/instrumentation.integration.test.js.map +1 -0
- package/dist/lib/instrumentation.js +520 -0
- package/dist/lib/instrumentation.js.map +1 -0
- package/dist/lib/instrumentation.test.d.ts +2 -0
- package/dist/lib/instrumentation.test.d.ts.map +1 -0
- package/dist/lib/instrumentation.test.js +821 -0
- package/dist/lib/instrumentation.test.js.map +1 -0
- package/dist/lib/langfuse-export.d.ts +125 -0
- package/dist/lib/langfuse-export.d.ts.map +1 -0
- package/dist/lib/langfuse-export.js +367 -0
- package/dist/lib/langfuse-export.js.map +1 -0
- package/dist/lib/langfuse-export.test.d.ts +7 -0
- package/dist/lib/langfuse-export.test.d.ts.map +1 -0
- package/dist/lib/langfuse-export.test.js +1007 -0
- package/dist/lib/langfuse-export.test.js.map +1 -0
- package/dist/lib/llm-as-judge.d.ts +657 -0
- package/dist/lib/llm-as-judge.d.ts.map +1 -0
- package/dist/lib/llm-as-judge.js +1397 -0
- package/dist/lib/llm-as-judge.js.map +1 -0
- package/dist/lib/llm-as-judge.test.d.ts +2 -0
- package/dist/lib/llm-as-judge.test.d.ts.map +1 -0
- package/dist/lib/llm-as-judge.test.js +2409 -0
- package/dist/lib/llm-as-judge.test.js.map +1 -0
- package/dist/lib/logger.d.ts +46 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +81 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/logger.test.d.ts +2 -0
- package/dist/lib/logger.test.d.ts.map +1 -0
- package/dist/lib/logger.test.js +122 -0
- package/dist/lib/logger.test.js.map +1 -0
- package/dist/lib/metrics.d.ts +62 -0
- package/dist/lib/metrics.d.ts.map +1 -0
- package/dist/lib/metrics.js +166 -0
- package/dist/lib/metrics.js.map +1 -0
- package/dist/lib/metrics.test.d.ts +5 -0
- package/dist/lib/metrics.test.d.ts.map +1 -0
- package/dist/lib/metrics.test.js +189 -0
- package/dist/lib/metrics.test.js.map +1 -0
- package/dist/lib/parse-stats.d.ts +119 -0
- package/dist/lib/parse-stats.d.ts.map +1 -0
- package/dist/lib/parse-stats.js +206 -0
- package/dist/lib/parse-stats.js.map +1 -0
- package/dist/lib/parse-stats.test.d.ts +5 -0
- package/dist/lib/parse-stats.test.d.ts.map +1 -0
- package/dist/lib/parse-stats.test.js +283 -0
- package/dist/lib/parse-stats.test.js.map +1 -0
- package/dist/lib/phoenix-export.d.ts +109 -0
- package/dist/lib/phoenix-export.d.ts.map +1 -0
- package/dist/lib/phoenix-export.js +429 -0
- package/dist/lib/phoenix-export.js.map +1 -0
- package/dist/lib/phoenix-export.test.d.ts +11 -0
- package/dist/lib/phoenix-export.test.d.ts.map +1 -0
- package/dist/lib/phoenix-export.test.js +725 -0
- package/dist/lib/phoenix-export.test.js.map +1 -0
- package/dist/lib/server-utils.d.ts +14 -1
- package/dist/lib/server-utils.d.ts.map +1 -1
- package/dist/lib/server-utils.js +43 -3
- package/dist/lib/server-utils.js.map +1 -1
- package/dist/lib/shared-schemas.d.ts +28 -0
- package/dist/lib/shared-schemas.d.ts.map +1 -1
- package/dist/lib/shared-schemas.js +33 -4
- package/dist/lib/shared-schemas.js.map +1 -1
- package/dist/lib/toon-encoder.d.ts +7 -2
- package/dist/lib/toon-encoder.d.ts.map +1 -1
- package/dist/lib/toon-encoder.js +21 -6
- package/dist/lib/toon-encoder.js.map +1 -1
- package/dist/lib/toon-encoder.test.d.ts +5 -0
- package/dist/lib/toon-encoder.test.d.ts.map +1 -0
- package/dist/lib/toon-encoder.test.js +85 -0
- package/dist/lib/toon-encoder.test.js.map +1 -0
- package/dist/lib/verification-events.d.ts +100 -0
- package/dist/lib/verification-events.d.ts.map +1 -0
- package/dist/lib/verification-events.js +162 -0
- package/dist/lib/verification-events.js.map +1 -0
- package/dist/lib/verification-events.test.d.ts +5 -0
- package/dist/lib/verification-events.test.d.ts.map +1 -0
- package/dist/lib/verification-events.test.js +193 -0
- package/dist/lib/verification-events.test.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +79 -21
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +30 -0
- package/dist/server.test.js.map +1 -1
- package/dist/test-helpers/env-utils.d.ts +22 -0
- package/dist/test-helpers/env-utils.d.ts.map +1 -1
- package/dist/test-helpers/env-utils.js +38 -0
- package/dist/test-helpers/env-utils.js.map +1 -1
- package/dist/test-helpers/fuzz-generators.d.ts +58 -0
- package/dist/test-helpers/fuzz-generators.d.ts.map +1 -0
- package/dist/test-helpers/fuzz-generators.js +216 -0
- package/dist/test-helpers/fuzz-generators.js.map +1 -0
- package/dist/test-helpers/index.d.ts +1 -0
- package/dist/test-helpers/index.d.ts.map +1 -1
- package/dist/test-helpers/index.js +2 -0
- package/dist/test-helpers/index.js.map +1 -1
- package/dist/test-helpers/memfs-utils.d.ts +181 -0
- package/dist/test-helpers/memfs-utils.d.ts.map +1 -0
- package/dist/test-helpers/memfs-utils.js +292 -0
- package/dist/test-helpers/memfs-utils.js.map +1 -0
- package/dist/test-helpers/memfs-utils.test.d.ts +5 -0
- package/dist/test-helpers/memfs-utils.test.d.ts.map +1 -0
- package/dist/test-helpers/memfs-utils.test.js +338 -0
- package/dist/test-helpers/memfs-utils.test.js.map +1 -0
- package/dist/test-helpers/race-condition-helpers.d.ts +85 -0
- package/dist/test-helpers/race-condition-helpers.d.ts.map +1 -0
- package/dist/test-helpers/race-condition-helpers.js +279 -0
- package/dist/test-helpers/race-condition-helpers.js.map +1 -0
- package/dist/test-helpers/test-data-builders.d.ts +40 -3
- package/dist/test-helpers/test-data-builders.d.ts.map +1 -1
- package/dist/test-helpers/test-data-builders.js +54 -5
- package/dist/test-helpers/test-data-builders.js.map +1 -1
- package/dist/test-helpers/tool-validators.d.ts.map +1 -1
- package/dist/test-helpers/tool-validators.js +16 -1
- package/dist/test-helpers/tool-validators.js.map +1 -1
- package/dist/tools/context-stats.d.ts.map +1 -1
- package/dist/tools/context-stats.js +6 -8
- package/dist/tools/context-stats.js.map +1 -1
- package/dist/tools/export-confident.d.ts +145 -0
- package/dist/tools/export-confident.d.ts.map +1 -0
- package/dist/tools/export-confident.js +134 -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 +332 -0
- package/dist/tools/export-confident.test.js.map +1 -0
- package/dist/tools/export-datadog.d.ts +160 -0
- package/dist/tools/export-datadog.d.ts.map +1 -0
- package/dist/tools/export-datadog.js +160 -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 +419 -0
- package/dist/tools/export-datadog.test.js.map +1 -0
- package/dist/tools/export-langfuse.d.ts +137 -0
- package/dist/tools/export-langfuse.d.ts.map +1 -0
- package/dist/tools/export-langfuse.js +131 -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 +303 -0
- package/dist/tools/export-langfuse.test.js.map +1 -0
- package/dist/tools/export-phoenix.d.ts +145 -0
- package/dist/tools/export-phoenix.d.ts.map +1 -0
- package/dist/tools/export-phoenix.js +135 -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 +316 -0
- package/dist/tools/export-phoenix.test.js.map +1 -0
- package/dist/tools/health-check.d.ts +26 -0
- package/dist/tools/health-check.d.ts.map +1 -1
- package/dist/tools/health-check.js +36 -7
- package/dist/tools/health-check.js.map +1 -1
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inject-evaluations.d.ts +1315 -0
- package/dist/tools/inject-evaluations.d.ts.map +1 -0
- package/dist/tools/inject-evaluations.js +121 -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 +359 -0
- package/dist/tools/inject-evaluations.test.js.map +1 -0
- package/dist/tools/query-evaluations.d.ts +25 -4
- package/dist/tools/query-evaluations.d.ts.map +1 -1
- package/dist/tools/query-evaluations.js +26 -2
- package/dist/tools/query-evaluations.js.map +1 -1
- package/dist/tools/query-evaluations.test.js +53 -46
- package/dist/tools/query-evaluations.test.js.map +1 -1
- package/dist/tools/query-llm-events.js +2 -2
- package/dist/tools/query-llm-events.js.map +1 -1
- package/dist/tools/query-llm-events.test.js +6 -3
- package/dist/tools/query-llm-events.test.js.map +1 -1
- package/dist/tools/query-logs.d.ts +8 -8
- package/dist/tools/query-logs.js +3 -3
- package/dist/tools/query-logs.js.map +1 -1
- package/dist/tools/query-metrics.d.ts +4 -4
- package/dist/tools/query-metrics.js +2 -2
- package/dist/tools/query-metrics.js.map +1 -1
- package/dist/tools/query-traces.d.ts +8 -8
- package/dist/tools/query-verifications.d.ts +111 -0
- package/dist/tools/query-verifications.d.ts.map +1 -0
- package/dist/tools/query-verifications.js +101 -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 +156 -0
- package/dist/tools/query-verifications.test.js.map +1 -0
- package/dist/types/evaluation-hooks.d.ts +176 -0
- package/dist/types/evaluation-hooks.d.ts.map +1 -0
- package/dist/types/evaluation-hooks.js +49 -0
- package/dist/types/evaluation-hooks.js.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export evaluations to Langfuse via OTLP HTTP
|
|
3
|
+
*
|
|
4
|
+
* MCP tool for exporting gen_ai.evaluation.result events to Langfuse
|
|
5
|
+
* for unified tracing and evaluation analysis.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { type LangfuseConfig } from '../lib/langfuse-export.js';
|
|
9
|
+
import type { TelemetryBackend } from '../backends/index.js';
|
|
10
|
+
export declare const exportLangfuseSchema: z.ZodObject<{
|
|
11
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
12
|
+
batchSize: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
15
|
+
publicKey: z.ZodOptional<z.ZodString>;
|
|
16
|
+
secretKey: z.ZodOptional<z.ZodString>;
|
|
17
|
+
startDate: z.ZodOptional<z.ZodString>;
|
|
18
|
+
endDate: z.ZodOptional<z.ZodString>;
|
|
19
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
20
|
+
traceId: z.ZodOptional<z.ZodString>;
|
|
21
|
+
evaluationName: z.ZodOptional<z.ZodString>;
|
|
22
|
+
scoreMin: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
scoreMax: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
scoreLabel: z.ZodOptional<z.ZodString>;
|
|
25
|
+
evaluatorType: z.ZodOptional<z.ZodEnum<["llm", "human", "rule", "classifier"]>>;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
limit: number;
|
|
28
|
+
dryRun: boolean;
|
|
29
|
+
traceId?: string | undefined;
|
|
30
|
+
sessionId?: string | undefined;
|
|
31
|
+
evaluationName?: string | undefined;
|
|
32
|
+
scoreLabel?: string | undefined;
|
|
33
|
+
scoreMin?: number | undefined;
|
|
34
|
+
scoreMax?: number | undefined;
|
|
35
|
+
evaluatorType?: "llm" | "human" | "rule" | "classifier" | undefined;
|
|
36
|
+
endpoint?: string | undefined;
|
|
37
|
+
endDate?: string | undefined;
|
|
38
|
+
startDate?: string | undefined;
|
|
39
|
+
publicKey?: string | undefined;
|
|
40
|
+
secretKey?: string | undefined;
|
|
41
|
+
batchSize?: number | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
limit?: number | undefined;
|
|
44
|
+
traceId?: string | undefined;
|
|
45
|
+
sessionId?: string | undefined;
|
|
46
|
+
evaluationName?: string | undefined;
|
|
47
|
+
scoreLabel?: string | undefined;
|
|
48
|
+
scoreMin?: number | undefined;
|
|
49
|
+
scoreMax?: number | undefined;
|
|
50
|
+
evaluatorType?: "llm" | "human" | "rule" | "classifier" | undefined;
|
|
51
|
+
endpoint?: string | undefined;
|
|
52
|
+
endDate?: string | undefined;
|
|
53
|
+
startDate?: string | undefined;
|
|
54
|
+
dryRun?: boolean | undefined;
|
|
55
|
+
publicKey?: string | undefined;
|
|
56
|
+
secretKey?: string | undefined;
|
|
57
|
+
batchSize?: number | undefined;
|
|
58
|
+
}>;
|
|
59
|
+
export type ExportLangfuseInput = z.input<typeof exportLangfuseSchema>;
|
|
60
|
+
/** Response from export operation */
|
|
61
|
+
export interface ExportLangfuseResponse {
|
|
62
|
+
success: boolean;
|
|
63
|
+
dryRun: boolean;
|
|
64
|
+
evaluationsFound: number;
|
|
65
|
+
evaluationsExported: number;
|
|
66
|
+
batches: number;
|
|
67
|
+
failed: number;
|
|
68
|
+
durationMs: number;
|
|
69
|
+
errors?: string[];
|
|
70
|
+
preview?: Array<{
|
|
71
|
+
traceId?: string;
|
|
72
|
+
evaluationName: string;
|
|
73
|
+
scoreValue?: number;
|
|
74
|
+
scoreLabel?: string;
|
|
75
|
+
}>;
|
|
76
|
+
}
|
|
77
|
+
export interface ExportLangfuseOptions {
|
|
78
|
+
localBackend?: TelemetryBackend;
|
|
79
|
+
configOverrides?: Partial<LangfuseConfig>;
|
|
80
|
+
skipExport?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export declare function exportLangfuse(rawInput: ExportLangfuseInput, options?: ExportLangfuseOptions): Promise<ExportLangfuseResponse>;
|
|
83
|
+
export declare const exportLangfuseTool: {
|
|
84
|
+
name: string;
|
|
85
|
+
description: string;
|
|
86
|
+
inputSchema: z.ZodObject<{
|
|
87
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
88
|
+
batchSize: z.ZodOptional<z.ZodNumber>;
|
|
89
|
+
dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
90
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
91
|
+
publicKey: z.ZodOptional<z.ZodString>;
|
|
92
|
+
secretKey: z.ZodOptional<z.ZodString>;
|
|
93
|
+
startDate: z.ZodOptional<z.ZodString>;
|
|
94
|
+
endDate: z.ZodOptional<z.ZodString>;
|
|
95
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
96
|
+
traceId: z.ZodOptional<z.ZodString>;
|
|
97
|
+
evaluationName: z.ZodOptional<z.ZodString>;
|
|
98
|
+
scoreMin: z.ZodOptional<z.ZodNumber>;
|
|
99
|
+
scoreMax: z.ZodOptional<z.ZodNumber>;
|
|
100
|
+
scoreLabel: z.ZodOptional<z.ZodString>;
|
|
101
|
+
evaluatorType: z.ZodOptional<z.ZodEnum<["llm", "human", "rule", "classifier"]>>;
|
|
102
|
+
}, "strip", z.ZodTypeAny, {
|
|
103
|
+
limit: number;
|
|
104
|
+
dryRun: boolean;
|
|
105
|
+
traceId?: string | undefined;
|
|
106
|
+
sessionId?: string | undefined;
|
|
107
|
+
evaluationName?: string | undefined;
|
|
108
|
+
scoreLabel?: string | undefined;
|
|
109
|
+
scoreMin?: number | undefined;
|
|
110
|
+
scoreMax?: number | undefined;
|
|
111
|
+
evaluatorType?: "llm" | "human" | "rule" | "classifier" | undefined;
|
|
112
|
+
endpoint?: string | undefined;
|
|
113
|
+
endDate?: string | undefined;
|
|
114
|
+
startDate?: string | undefined;
|
|
115
|
+
publicKey?: string | undefined;
|
|
116
|
+
secretKey?: string | undefined;
|
|
117
|
+
batchSize?: number | undefined;
|
|
118
|
+
}, {
|
|
119
|
+
limit?: number | undefined;
|
|
120
|
+
traceId?: string | undefined;
|
|
121
|
+
sessionId?: string | undefined;
|
|
122
|
+
evaluationName?: string | undefined;
|
|
123
|
+
scoreLabel?: string | undefined;
|
|
124
|
+
scoreMin?: number | undefined;
|
|
125
|
+
scoreMax?: number | undefined;
|
|
126
|
+
evaluatorType?: "llm" | "human" | "rule" | "classifier" | undefined;
|
|
127
|
+
endpoint?: string | undefined;
|
|
128
|
+
endDate?: string | undefined;
|
|
129
|
+
startDate?: string | undefined;
|
|
130
|
+
dryRun?: boolean | undefined;
|
|
131
|
+
publicKey?: string | undefined;
|
|
132
|
+
secretKey?: string | undefined;
|
|
133
|
+
batchSize?: number | undefined;
|
|
134
|
+
}>;
|
|
135
|
+
handler: typeof exportLangfuse;
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=export-langfuse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-langfuse.d.ts","sourceRoot":"","sources":["../../src/tools/export-langfuse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAWnC,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5E,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoB/B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEvE,qCAAqC;AACrC,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAGD,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAsGjC;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK9B,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export evaluations to Langfuse via OTLP HTTP
|
|
3
|
+
*
|
|
4
|
+
* MCP tool for exporting gen_ai.evaluation.result events to Langfuse
|
|
5
|
+
* for unified tracing and evaluation analysis.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { MultiDirectoryBackend } from '../backends/local-jsonl.js';
|
|
9
|
+
import { validateLangfuseConfig, exportToLangfuse, } from '../lib/langfuse-export.js';
|
|
10
|
+
import { validateLimit, validateDateRange, InputValidationError, } from '../lib/input-validator.js';
|
|
11
|
+
import { sessionSchema, traceIdSchema, dateRangeSchema, } from '../lib/shared-schemas.js';
|
|
12
|
+
import { MAX_EXPORT_LIMIT, EXPORT_PREVIEW_LIMIT } from '../lib/constants.js';
|
|
13
|
+
export const exportLangfuseSchema = z.object({
|
|
14
|
+
// Filters
|
|
15
|
+
evaluationName: z.string().optional().describe('Evaluation name (substring)'),
|
|
16
|
+
scoreMin: z.number().optional().describe('Min score threshold'),
|
|
17
|
+
scoreMax: z.number().optional().describe('Max score threshold'),
|
|
18
|
+
scoreLabel: z.string().optional().describe('Score label (exact)'),
|
|
19
|
+
evaluatorType: z.enum(['llm', 'human', 'rule', 'classifier']).optional().describe('Evaluator type'),
|
|
20
|
+
...traceIdSchema,
|
|
21
|
+
...sessionSchema,
|
|
22
|
+
...dateRangeSchema,
|
|
23
|
+
// Export options
|
|
24
|
+
limit: z.number().max(MAX_EXPORT_LIMIT).optional().default(1000).describe('Max evaluations to export (max 10000)'),
|
|
25
|
+
batchSize: z.number().min(1).max(1000).optional().describe('Batch size for export (default 100)'),
|
|
26
|
+
dryRun: z.boolean().optional().default(false).describe('Preview export without sending'),
|
|
27
|
+
// Optional config overrides
|
|
28
|
+
endpoint: z.string().optional().describe('Override LANGFUSE_ENDPOINT'),
|
|
29
|
+
publicKey: z.string().optional().describe('Override LANGFUSE_PUBLIC_KEY'),
|
|
30
|
+
secretKey: z.string().optional().describe('Override LANGFUSE_SECRET_KEY'),
|
|
31
|
+
});
|
|
32
|
+
export async function exportLangfuse(rawInput, options) {
|
|
33
|
+
try {
|
|
34
|
+
const input = exportLangfuseSchema.parse(rawInput);
|
|
35
|
+
// Validate inputs
|
|
36
|
+
const validatedLimit = Math.min(validateLimit(input.limit), MAX_EXPORT_LIMIT);
|
|
37
|
+
// Validate date range if provided
|
|
38
|
+
if (input.startDate || input.endDate) {
|
|
39
|
+
validateDateRange(input.startDate, input.endDate);
|
|
40
|
+
}
|
|
41
|
+
// Validate score range
|
|
42
|
+
if (input.scoreMin !== undefined && input.scoreMax !== undefined) {
|
|
43
|
+
if (input.scoreMin > input.scoreMax) {
|
|
44
|
+
throw new Error(`Invalid score range: scoreMin (${input.scoreMin}) cannot exceed scoreMax (${input.scoreMax})`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Build query options
|
|
48
|
+
const queryOptions = {
|
|
49
|
+
evaluationName: input.evaluationName,
|
|
50
|
+
scoreMin: input.scoreMin,
|
|
51
|
+
scoreMax: input.scoreMax,
|
|
52
|
+
scoreLabel: input.scoreLabel,
|
|
53
|
+
evaluatorType: input.evaluatorType,
|
|
54
|
+
traceId: input.traceId,
|
|
55
|
+
sessionId: input.sessionId,
|
|
56
|
+
startDate: input.startDate,
|
|
57
|
+
endDate: input.endDate,
|
|
58
|
+
limit: validatedLimit,
|
|
59
|
+
};
|
|
60
|
+
// Query evaluations from local backend
|
|
61
|
+
const local = options?.localBackend ?? new MultiDirectoryBackend();
|
|
62
|
+
const evaluations = await local.queryEvaluations(queryOptions);
|
|
63
|
+
// Handle dry run
|
|
64
|
+
if (input.dryRun) {
|
|
65
|
+
return {
|
|
66
|
+
success: true,
|
|
67
|
+
dryRun: true,
|
|
68
|
+
evaluationsFound: evaluations.length,
|
|
69
|
+
evaluationsExported: 0,
|
|
70
|
+
batches: 0,
|
|
71
|
+
failed: 0,
|
|
72
|
+
durationMs: 0,
|
|
73
|
+
preview: evaluations.slice(0, EXPORT_PREVIEW_LIMIT).map(e => ({
|
|
74
|
+
traceId: e.traceId,
|
|
75
|
+
evaluationName: e.evaluationName,
|
|
76
|
+
scoreValue: e.scoreValue,
|
|
77
|
+
scoreLabel: e.scoreLabel,
|
|
78
|
+
})),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Validate Langfuse config (will throw if invalid)
|
|
82
|
+
// M3 FIX: Optimize batch size - don't use larger batch than evaluation count
|
|
83
|
+
const optimalBatchSize = input.batchSize
|
|
84
|
+
? Math.min(input.batchSize, evaluations.length || 1)
|
|
85
|
+
: undefined;
|
|
86
|
+
const config = validateLangfuseConfig({
|
|
87
|
+
endpoint: input.endpoint,
|
|
88
|
+
publicKey: input.publicKey,
|
|
89
|
+
secretKey: input.secretKey,
|
|
90
|
+
batchSize: optimalBatchSize,
|
|
91
|
+
...options?.configOverrides,
|
|
92
|
+
});
|
|
93
|
+
// Skip actual export if requested (for testing)
|
|
94
|
+
if (options?.skipExport) {
|
|
95
|
+
return {
|
|
96
|
+
success: true,
|
|
97
|
+
dryRun: false,
|
|
98
|
+
evaluationsFound: evaluations.length,
|
|
99
|
+
evaluationsExported: evaluations.length,
|
|
100
|
+
batches: Math.ceil(evaluations.length / config.batchSize),
|
|
101
|
+
failed: 0,
|
|
102
|
+
durationMs: 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Export to Langfuse
|
|
106
|
+
const result = await exportToLangfuse(evaluations, config);
|
|
107
|
+
return {
|
|
108
|
+
success: result.success,
|
|
109
|
+
dryRun: false,
|
|
110
|
+
evaluationsFound: evaluations.length,
|
|
111
|
+
evaluationsExported: result.evaluationsExported,
|
|
112
|
+
batches: result.batches,
|
|
113
|
+
failed: result.failed,
|
|
114
|
+
durationMs: result.durationMs,
|
|
115
|
+
...(result.errors && { errors: result.errors }),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (error instanceof InputValidationError) {
|
|
120
|
+
throw new Error(`Validation error (${error.field}): ${error.message}`);
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export const exportLangfuseTool = {
|
|
126
|
+
name: 'obs_export_langfuse',
|
|
127
|
+
description: 'Export evaluation results to Langfuse via OTLP HTTP for unified tracing and evaluation.',
|
|
128
|
+
inputSchema: exportLangfuseSchema,
|
|
129
|
+
handler: exportLangfuse,
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=export-langfuse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-langfuse.js","sourceRoot":"","sources":["../../src/tools/export-langfuse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-langfuse.test.d.ts","sourceRoot":"","sources":["../../src/tools/export-langfuse.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for export-langfuse.ts MCP tool
|
|
3
|
+
*
|
|
4
|
+
* Covers schema validation, dryRun mode, and handler with mocked backend.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, mock } from 'node:test';
|
|
7
|
+
import assert from 'node:assert';
|
|
8
|
+
import { exportLangfuseSchema, exportLangfuse, exportLangfuseTool, } from './export-langfuse.js';
|
|
9
|
+
import { HttpStatus } from '../lib/constants.js';
|
|
10
|
+
// Mock backend for testing
|
|
11
|
+
function createMockBackend(evaluations) {
|
|
12
|
+
return {
|
|
13
|
+
name: 'mock',
|
|
14
|
+
queryEvaluations: async (_options) => evaluations,
|
|
15
|
+
queryTraces: async () => [],
|
|
16
|
+
queryLogs: async () => [],
|
|
17
|
+
queryMetrics: async () => [],
|
|
18
|
+
healthCheck: async () => ({ status: 'ok' }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
describe('export-langfuse', () => {
|
|
22
|
+
const testEvaluations = [
|
|
23
|
+
{
|
|
24
|
+
timestamp: '2024-01-15T10:00:00Z',
|
|
25
|
+
evaluationName: 'relevance',
|
|
26
|
+
scoreValue: 0.85,
|
|
27
|
+
scoreLabel: 'good',
|
|
28
|
+
traceId: 'trace-1',
|
|
29
|
+
sessionId: 'session-1',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
timestamp: '2024-01-15T10:00:01Z',
|
|
33
|
+
evaluationName: 'quality',
|
|
34
|
+
scoreValue: 0.92,
|
|
35
|
+
scoreLabel: 'excellent',
|
|
36
|
+
traceId: 'trace-2',
|
|
37
|
+
sessionId: 'session-1',
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
describe('exportLangfuseSchema', () => {
|
|
41
|
+
it('accepts minimal input', () => {
|
|
42
|
+
const input = {};
|
|
43
|
+
const result = exportLangfuseSchema.parse(input);
|
|
44
|
+
assert.strictEqual(result.limit, 1000);
|
|
45
|
+
assert.strictEqual(result.dryRun, false);
|
|
46
|
+
});
|
|
47
|
+
it('accepts all filter fields', () => {
|
|
48
|
+
const input = {
|
|
49
|
+
evaluationName: 'relevance',
|
|
50
|
+
scoreMin: 0.5,
|
|
51
|
+
scoreMax: 1.0,
|
|
52
|
+
scoreLabel: 'good',
|
|
53
|
+
evaluatorType: 'llm',
|
|
54
|
+
traceId: 'trace-123',
|
|
55
|
+
sessionId: 'session-456',
|
|
56
|
+
startDate: '2024-01-01',
|
|
57
|
+
endDate: '2024-01-31',
|
|
58
|
+
};
|
|
59
|
+
const result = exportLangfuseSchema.parse(input);
|
|
60
|
+
assert.strictEqual(result.evaluationName, 'relevance');
|
|
61
|
+
assert.strictEqual(result.scoreMin, 0.5);
|
|
62
|
+
assert.strictEqual(result.evaluatorType, 'llm');
|
|
63
|
+
});
|
|
64
|
+
it('accepts export options', () => {
|
|
65
|
+
const input = {
|
|
66
|
+
limit: 500,
|
|
67
|
+
batchSize: 50,
|
|
68
|
+
dryRun: true,
|
|
69
|
+
};
|
|
70
|
+
const result = exportLangfuseSchema.parse(input);
|
|
71
|
+
assert.strictEqual(result.limit, 500);
|
|
72
|
+
assert.strictEqual(result.batchSize, 50);
|
|
73
|
+
assert.strictEqual(result.dryRun, true);
|
|
74
|
+
});
|
|
75
|
+
it('accepts config overrides', () => {
|
|
76
|
+
const input = {
|
|
77
|
+
endpoint: 'https://custom.langfuse.com',
|
|
78
|
+
publicKey: 'pk-custom',
|
|
79
|
+
secretKey: 'sk-custom',
|
|
80
|
+
};
|
|
81
|
+
const result = exportLangfuseSchema.parse(input);
|
|
82
|
+
assert.strictEqual(result.endpoint, 'https://custom.langfuse.com');
|
|
83
|
+
assert.strictEqual(result.publicKey, 'pk-custom');
|
|
84
|
+
});
|
|
85
|
+
it('rejects limit over 10000', () => {
|
|
86
|
+
const input = { limit: 15000 };
|
|
87
|
+
assert.throws(() => exportLangfuseSchema.parse(input));
|
|
88
|
+
});
|
|
89
|
+
it('rejects invalid evaluator type', () => {
|
|
90
|
+
const input = { evaluatorType: 'invalid' };
|
|
91
|
+
assert.throws(() => exportLangfuseSchema.parse(input));
|
|
92
|
+
});
|
|
93
|
+
it('accepts valid evaluator types', () => {
|
|
94
|
+
for (const type of ['llm', 'human', 'rule', 'classifier']) {
|
|
95
|
+
const result = exportLangfuseSchema.parse({ evaluatorType: type });
|
|
96
|
+
assert.strictEqual(result.evaluatorType, type);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
it('rejects batchSize under 1', () => {
|
|
100
|
+
const input = { batchSize: 0 };
|
|
101
|
+
assert.throws(() => exportLangfuseSchema.parse(input));
|
|
102
|
+
});
|
|
103
|
+
it('rejects batchSize over 1000', () => {
|
|
104
|
+
const input = { batchSize: 1001 };
|
|
105
|
+
assert.throws(() => exportLangfuseSchema.parse(input));
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
// BACKLOG: MAX_EXPORT_LIMIT enforcement at runtime
|
|
109
|
+
describe('MAX_EXPORT_LIMIT enforcement', () => {
|
|
110
|
+
it('enforces MAX_EXPORT_LIMIT via zod schema', () => {
|
|
111
|
+
// Verify schema rejects values over 10000
|
|
112
|
+
assert.throws(() => exportLangfuseSchema.parse({ limit: 10001 }), /too_big/);
|
|
113
|
+
});
|
|
114
|
+
it('accepts exactly 10000 limit', () => {
|
|
115
|
+
const result = exportLangfuseSchema.parse({ limit: 10000 });
|
|
116
|
+
assert.strictEqual(result.limit, 10000);
|
|
117
|
+
});
|
|
118
|
+
it('handler respects limit when exporting', async () => {
|
|
119
|
+
const manyEvaluations = Array.from({ length: 100 }, (_, i) => ({
|
|
120
|
+
timestamp: '2024-01-15T10:00:00Z',
|
|
121
|
+
evaluationName: `eval-${i}`,
|
|
122
|
+
scoreValue: 0.5,
|
|
123
|
+
}));
|
|
124
|
+
const mockBackend = createMockBackend(manyEvaluations);
|
|
125
|
+
const result = await exportLangfuse({ limit: 50, dryRun: true }, // Request only 50
|
|
126
|
+
{ localBackend: mockBackend });
|
|
127
|
+
// Should return at most 50 evaluations
|
|
128
|
+
assert.ok(result.evaluationsFound <= 100);
|
|
129
|
+
assert.strictEqual(result.success, true);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('exportLangfuse - dryRun mode', () => {
|
|
133
|
+
it('returns preview without exporting', async () => {
|
|
134
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
135
|
+
const result = await exportLangfuse({ dryRun: true }, { localBackend: mockBackend });
|
|
136
|
+
assert.strictEqual(result.success, true);
|
|
137
|
+
assert.strictEqual(result.dryRun, true);
|
|
138
|
+
assert.strictEqual(result.evaluationsFound, 2);
|
|
139
|
+
assert.strictEqual(result.evaluationsExported, 0);
|
|
140
|
+
assert.strictEqual(result.batches, 0);
|
|
141
|
+
assert.strictEqual(result.durationMs, 0);
|
|
142
|
+
assert.ok(result.preview);
|
|
143
|
+
assert.strictEqual(result.preview.length, 2);
|
|
144
|
+
assert.strictEqual(result.preview[0].evaluationName, 'relevance');
|
|
145
|
+
});
|
|
146
|
+
it('limits preview to 10 items', async () => {
|
|
147
|
+
const manyEvaluations = Array.from({ length: 20 }, (_, i) => ({
|
|
148
|
+
timestamp: '2024-01-15T10:00:00Z',
|
|
149
|
+
evaluationName: `eval-${i}`,
|
|
150
|
+
scoreValue: 0.5,
|
|
151
|
+
}));
|
|
152
|
+
const mockBackend = createMockBackend(manyEvaluations);
|
|
153
|
+
const result = await exportLangfuse({ dryRun: true }, { localBackend: mockBackend });
|
|
154
|
+
assert.strictEqual(result.evaluationsFound, 20);
|
|
155
|
+
assert.strictEqual(result.preview?.length, 10);
|
|
156
|
+
});
|
|
157
|
+
it('filters evaluations by evaluationName', async () => {
|
|
158
|
+
const mockBackend = {
|
|
159
|
+
name: 'mock',
|
|
160
|
+
queryEvaluations: async (options) => {
|
|
161
|
+
// Simulate filtering
|
|
162
|
+
return testEvaluations.filter(e => !options.evaluationName || e.evaluationName.includes(options.evaluationName));
|
|
163
|
+
},
|
|
164
|
+
queryTraces: async () => [],
|
|
165
|
+
queryLogs: async () => [],
|
|
166
|
+
queryMetrics: async () => [],
|
|
167
|
+
healthCheck: async () => ({ status: 'ok' }),
|
|
168
|
+
};
|
|
169
|
+
const result = await exportLangfuse({ dryRun: true, evaluationName: 'quality' }, { localBackend: mockBackend });
|
|
170
|
+
assert.strictEqual(result.evaluationsFound, 1);
|
|
171
|
+
assert.strictEqual(result.preview?.[0].evaluationName, 'quality');
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
describe('exportLangfuse - validation', () => {
|
|
175
|
+
it('rejects invalid score range', async () => {
|
|
176
|
+
const mockBackend = createMockBackend([]);
|
|
177
|
+
await assert.rejects(exportLangfuse({ scoreMin: 0.9, scoreMax: 0.5 }, { localBackend: mockBackend }), /Invalid score range/);
|
|
178
|
+
});
|
|
179
|
+
it('validates date range', async () => {
|
|
180
|
+
const mockBackend = createMockBackend([]);
|
|
181
|
+
await assert.rejects(exportLangfuse({ startDate: '2024-02-01', endDate: '2024-01-01' }, { localBackend: mockBackend }), /cannot be after/);
|
|
182
|
+
});
|
|
183
|
+
it('clamps negative limit to 1', async () => {
|
|
184
|
+
const manyEvaluations = Array.from({ length: 10 }, (_, i) => ({
|
|
185
|
+
timestamp: '2024-01-15T10:00:00Z',
|
|
186
|
+
evaluationName: `eval-${i}`,
|
|
187
|
+
scoreValue: 0.5,
|
|
188
|
+
}));
|
|
189
|
+
const mockBackend = createMockBackend(manyEvaluations);
|
|
190
|
+
// Negative limit should be clamped to 1
|
|
191
|
+
const result = await exportLangfuse({ limit: -1, dryRun: true }, { localBackend: mockBackend });
|
|
192
|
+
assert.strictEqual(result.success, true);
|
|
193
|
+
// validateLimit clamps -1 to 1, so only 1 evaluation should be found
|
|
194
|
+
assert.ok(result.evaluationsFound <= 10);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe('exportLangfuse - skipExport mode', () => {
|
|
198
|
+
it('skips HTTP calls when skipExport is true', async () => {
|
|
199
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
200
|
+
const result = await exportLangfuse({ limit: 100 }, {
|
|
201
|
+
localBackend: mockBackend,
|
|
202
|
+
skipExport: true,
|
|
203
|
+
configOverrides: {
|
|
204
|
+
endpoint: 'https://cloud.langfuse.com',
|
|
205
|
+
publicKey: 'pk-test',
|
|
206
|
+
secretKey: 'sk-test',
|
|
207
|
+
batchSize: 10,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
assert.strictEqual(result.success, true);
|
|
211
|
+
assert.strictEqual(result.dryRun, false);
|
|
212
|
+
assert.strictEqual(result.evaluationsFound, 2);
|
|
213
|
+
assert.strictEqual(result.evaluationsExported, 2);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
describe('exportLangfuse - config validation', () => {
|
|
217
|
+
it('throws when Langfuse not configured', async () => {
|
|
218
|
+
const originalEndpoint = process.env.LANGFUSE_ENDPOINT;
|
|
219
|
+
delete process.env.LANGFUSE_ENDPOINT;
|
|
220
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
221
|
+
try {
|
|
222
|
+
await assert.rejects(exportLangfuse({ limit: 10 }, { localBackend: mockBackend }), /endpoint not configured/);
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
if (originalEndpoint) {
|
|
226
|
+
process.env.LANGFUSE_ENDPOINT = originalEndpoint;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
it('uses config overrides from input', async () => {
|
|
231
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
232
|
+
const result = await exportLangfuse({
|
|
233
|
+
endpoint: 'https://custom.langfuse.com',
|
|
234
|
+
publicKey: 'pk-custom',
|
|
235
|
+
secretKey: 'sk-custom',
|
|
236
|
+
}, {
|
|
237
|
+
localBackend: mockBackend,
|
|
238
|
+
skipExport: true,
|
|
239
|
+
});
|
|
240
|
+
assert.strictEqual(result.success, true);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('exportLangfuseTool', () => {
|
|
244
|
+
it('has correct tool metadata', () => {
|
|
245
|
+
assert.strictEqual(exportLangfuseTool.name, 'obs_export_langfuse');
|
|
246
|
+
assert.ok(exportLangfuseTool.description.includes('Langfuse'));
|
|
247
|
+
assert.ok(exportLangfuseTool.inputSchema);
|
|
248
|
+
assert.ok(exportLangfuseTool.handler);
|
|
249
|
+
});
|
|
250
|
+
it('handler is the exportLangfuse function', () => {
|
|
251
|
+
assert.strictEqual(exportLangfuseTool.handler, exportLangfuse);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe('exportLangfuse - actual export', () => {
|
|
255
|
+
it('sends evaluations to Langfuse', async () => {
|
|
256
|
+
const fetchCalls = [];
|
|
257
|
+
const originalFetch = globalThis.fetch;
|
|
258
|
+
globalThis.fetch = mock.fn(async (url, opts) => {
|
|
259
|
+
fetchCalls.push({ url: url.toString(), method: opts?.method || 'GET' });
|
|
260
|
+
return new Response('{}', { status: HttpStatus.OK });
|
|
261
|
+
});
|
|
262
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
263
|
+
try {
|
|
264
|
+
const result = await exportLangfuse({
|
|
265
|
+
endpoint: 'https://cloud.langfuse.com',
|
|
266
|
+
publicKey: 'pk-test',
|
|
267
|
+
secretKey: 'sk-test',
|
|
268
|
+
batchSize: 100,
|
|
269
|
+
}, { localBackend: mockBackend });
|
|
270
|
+
assert.strictEqual(result.success, true);
|
|
271
|
+
assert.strictEqual(result.evaluationsExported, 2);
|
|
272
|
+
assert.strictEqual(fetchCalls.length, 1);
|
|
273
|
+
assert.ok(fetchCalls[0].url.includes('/v1/traces'));
|
|
274
|
+
assert.strictEqual(fetchCalls[0].method, 'POST');
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
globalThis.fetch = originalFetch;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
it('reports errors from Langfuse', async () => {
|
|
281
|
+
const originalFetch = globalThis.fetch;
|
|
282
|
+
globalThis.fetch = mock.fn(async () => {
|
|
283
|
+
return new Response('Unauthorized', { status: HttpStatus.UNAUTHORIZED });
|
|
284
|
+
});
|
|
285
|
+
const mockBackend = createMockBackend(testEvaluations);
|
|
286
|
+
try {
|
|
287
|
+
const result = await exportLangfuse({
|
|
288
|
+
endpoint: 'https://cloud.langfuse.com',
|
|
289
|
+
publicKey: 'pk-test',
|
|
290
|
+
secretKey: 'sk-test',
|
|
291
|
+
}, { localBackend: mockBackend });
|
|
292
|
+
assert.strictEqual(result.success, false);
|
|
293
|
+
assert.strictEqual(result.failed, 2);
|
|
294
|
+
assert.ok(result.errors);
|
|
295
|
+
assert.ok(result.errors[0].includes('HTTP 401'));
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
globalThis.fetch = originalFetch;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
//# sourceMappingURL=export-langfuse.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-langfuse.test.js","sourceRoot":"","sources":["../../src/tools/export-langfuse.test.ts"],"names":[],"mappings":"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"}
|