dd-trace 6.8.0 → 6.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci/diagnose.js +27 -25
- package/ci/init.js +6 -6
- package/ci/runbook.md +114 -20
- package/ci/test-optimization-validation/approval-artifacts.js +36 -3
- package/ci/test-optimization-validation/approval.js +78 -22
- package/ci/test-optimization-validation/blocker-category.js +24 -0
- package/ci/test-optimization-validation/ci-discovery.js +23 -17
- package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
- package/ci/test-optimization-validation/ci-remediation.js +1 -1
- package/ci/test-optimization-validation/cli.js +280 -52
- package/ci/test-optimization-validation/command-blocker.js +159 -20
- package/ci/test-optimization-validation/command-output-policy.js +9 -3
- package/ci/test-optimization-validation/command-runner.js +9 -7
- package/ci/test-optimization-validation/environment.js +4 -2
- package/ci/test-optimization-validation/executable.js +15 -13
- package/ci/test-optimization-validation/execution-lock.js +70 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
- package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +38 -28
- package/ci/test-optimization-validation/generated-test-contract.js +8 -4
- package/ci/test-optimization-validation/generated-verifier.js +24 -17
- package/ci/test-optimization-validation/literal-glob.js +52 -0
- package/ci/test-optimization-validation/manifest-loader.js +3 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +300 -50
- package/ci/test-optimization-validation/manifest-schema.js +80 -17
- package/ci/test-optimization-validation/offline-fixtures.js +13 -4
- package/ci/test-optimization-validation/package-check.js +94 -0
- package/ci/test-optimization-validation/plan-writer.js +183 -10
- package/ci/test-optimization-validation/preflight-runner.js +110 -31
- package/ci/test-optimization-validation/project-build-artifact.js +31 -0
- package/ci/test-optimization-validation/redaction.js +18 -27
- package/ci/test-optimization-validation/report-writer.js +182 -48
- package/ci/test-optimization-validation/result-semantics.js +20 -3
- package/ci/test-optimization-validation/runner-command.js +40 -20
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +59 -5
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
- package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
- package/ci/test-optimization-validation/static-diagnosis.js +10 -3
- package/ci/test-optimization-validation/test-output.js +2 -1
- package/ci/test-optimization-validation/validation-blocker.js +21 -0
- package/ci/vitest-no-worker-init-setup.mjs +140 -42
- package/index.d.ts +140 -1
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +8 -5
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/src/utils.js +16 -1
- package/packages/datadog-instrumentations/src/ai.js +61 -34
- package/packages/datadog-instrumentations/src/bluebird.js +6 -6
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +81 -5
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
- package/packages/datadog-instrumentations/src/cucumber.js +124 -47
- package/packages/datadog-instrumentations/src/dns.js +21 -2
- package/packages/datadog-instrumentations/src/electron.js +1 -0
- package/packages/datadog-instrumentations/src/fastify.js +3 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +629 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +199 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +62 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +37 -6
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +980 -234
- package/packages/datadog-instrumentations/src/mocha/main.js +108 -10
- package/packages/datadog-instrumentations/src/mocha/utils.js +66 -50
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +25 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -18
- package/packages/datadog-instrumentations/src/mysql.js +46 -16
- package/packages/datadog-instrumentations/src/mysql2.js +119 -18
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
- package/packages/datadog-instrumentations/src/pg.js +209 -11
- package/packages/datadog-instrumentations/src/playwright.js +173 -79
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +85 -13
- package/packages/datadog-instrumentations/src/vitest-main.js +528 -72
- package/packages/datadog-instrumentations/src/vitest-util.js +106 -12
- package/packages/datadog-instrumentations/src/vitest-worker.js +382 -40
- package/packages/datadog-instrumentations/src/webdriverio.js +212 -22
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -3
- package/packages/datadog-plugin-cucumber/src/index.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +51 -47
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -22
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +5 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
- package/packages/datadog-plugin-mocha/src/index.js +832 -4
- package/packages/datadog-plugin-mysql/src/index.js +37 -0
- package/packages/datadog-plugin-next/src/index.js +51 -21
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +278 -69
- package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
- package/packages/datadog-plugin-pg/src/index.js +66 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +103 -27
- package/packages/datadog-plugin-ws/src/util.js +2 -1
- package/packages/datadog-shimmer/src/shimmer.js +6 -2
- package/packages/dd-trace/src/aiguard/sdk.js +3 -0
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
- package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
- package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +228 -0
- package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
- package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
- package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +9 -0
- package/packages/dd-trace/src/carrier.js +356 -0
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +27 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +17 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +21 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +5 -0
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +16 -5
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +18 -0
- package/packages/dd-trace/src/datastreams/context.js +6 -1
- package/packages/dd-trace/src/datastreams/manager.js +5 -1
- package/packages/dd-trace/src/datastreams/pathway.js +23 -22
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +33 -25
- package/packages/dd-trace/src/llmobs/experiments/util.js +4 -2
- package/packages/dd-trace/src/llmobs/index.js +34 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +149 -68
- package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
- package/packages/dd-trace/src/llmobs/tagger.js +96 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/util.js +78 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
- package/packages/dd-trace/src/log/channels.js +1 -9
- package/packages/dd-trace/src/log/levels.js +12 -0
- package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +6 -0
- package/packages/dd-trace/src/plugins/util/git.js +6 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +2 -2
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +3 -62
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +397 -74
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +76 -3
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +5 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
- package/packages/dd-trace/src/sampling_rule.js +4 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
- package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
|
@@ -4,6 +4,7 @@ const fs = require('node:fs')
|
|
|
4
4
|
const path = require('path')
|
|
5
5
|
|
|
6
6
|
const { getArtifactId } = require('../artifact-id')
|
|
7
|
+
const { BLOCKER_CATEGORIES } = require('../blocker-category')
|
|
7
8
|
const { buildDatadogEnv, buildOfflineCaptureEnv, runCommand } = require('../command-runner')
|
|
8
9
|
const {
|
|
9
10
|
cleanupGeneratedRuntimeFiles,
|
|
@@ -19,8 +20,10 @@ const { readOfflineOutput } = require('../offline-output')
|
|
|
19
20
|
const { sanitizeForReport, sanitizeString } = require('../redaction')
|
|
20
21
|
const { getGeneratedCommand } = require('../runner-command')
|
|
21
22
|
const { ensureSafeDirectory, writeFileSafely } = require('../safe-files')
|
|
23
|
+
const { getValidationBlockerEvidence } = require('../validation-blocker')
|
|
22
24
|
|
|
23
|
-
const ANSI_PATTERN =
|
|
25
|
+
const ANSI_PATTERN =
|
|
26
|
+
new RegExp(`${String.fromCharCode(27)}${String.raw`\[[\u0030-\u003F]*[\u0020-\u002F]*[\u0040-\u007E]`}`, 'g')
|
|
24
27
|
|
|
25
28
|
function frameworkOutDir (out, framework, scenario) {
|
|
26
29
|
return path.join(out, 'runs', getArtifactId(framework.id), scenario)
|
|
@@ -193,10 +196,11 @@ async function prepareGeneratedScenario (framework, scenarioId) {
|
|
|
193
196
|
function requireGeneratedScenario (framework, scenarioId, scenarioName) {
|
|
194
197
|
const strategy = framework.generatedTestStrategy
|
|
195
198
|
if (strategy?.status === 'not_possible') {
|
|
196
|
-
return
|
|
199
|
+
return incomplete(
|
|
197
200
|
framework,
|
|
198
201
|
scenarioName,
|
|
199
|
-
`
|
|
202
|
+
`The validator cannot create a collectible test for this advanced feature: ${strategy.reason} ` +
|
|
203
|
+
'No conclusion was reached for this advanced feature.',
|
|
200
204
|
getGeneratedStrategySkipEvidence(framework, scenarioName, scenarioId)
|
|
201
205
|
)
|
|
202
206
|
}
|
|
@@ -254,9 +258,9 @@ function getGeneratedStrategySkipEvidence (framework, scenarioName, scenarioId)
|
|
|
254
258
|
reasonCode = 'generated-test-strategy-not-verified'
|
|
255
259
|
}
|
|
256
260
|
|
|
257
|
-
|
|
261
|
+
const evidence = {
|
|
258
262
|
featureEligibility: {
|
|
259
|
-
eligible: false,
|
|
263
|
+
...(reasonCode === 'generated-test-strategy-not-possible' ? {} : { eligible: false }),
|
|
260
264
|
blockedBy: 'generated-test-strategy',
|
|
261
265
|
reason: strategy?.reason,
|
|
262
266
|
reasonCode,
|
|
@@ -265,6 +269,12 @@ function getGeneratedStrategySkipEvidence (framework, scenarioName, scenarioId)
|
|
|
265
269
|
requiredGeneratedScenario: scenarioId,
|
|
266
270
|
},
|
|
267
271
|
}
|
|
272
|
+
if (reasonCode === 'generated-test-strategy-not-possible') {
|
|
273
|
+
evidence.blockerCategory = BLOCKER_CATEGORIES.VALIDATOR_LIMITATION
|
|
274
|
+
evidence.recommendation = 'Report that the selected runner configuration cannot collect validator-generated ' +
|
|
275
|
+
'tests to validator engineering. Basic Reporting remains valid; project setup changes are not required.'
|
|
276
|
+
}
|
|
277
|
+
return evidence
|
|
268
278
|
}
|
|
269
279
|
|
|
270
280
|
function basicEventEvidence (events) {
|
|
@@ -442,6 +452,8 @@ function copy (target, source, key) {
|
|
|
442
452
|
|
|
443
453
|
function summarizeDebugRerun ({ result, events, offline, outDir }) {
|
|
444
454
|
const output = `${result.stdout}\n${result.stderr}`
|
|
455
|
+
const testEvents = eventsOfType(events, 'test')
|
|
456
|
+
const sourceFiles = new Set(testEvents.map(test => test.testSourceFile).filter(Boolean))
|
|
445
457
|
|
|
446
458
|
return {
|
|
447
459
|
ran: true,
|
|
@@ -449,8 +461,12 @@ function summarizeDebugRerun ({ result, events, offline, outDir }) {
|
|
|
449
461
|
commandTimedOut: result.timedOut,
|
|
450
462
|
debugCommandFailed: result.exitCode !== 0 || result.timedOut === true,
|
|
451
463
|
offlineExporterInitialized: offline.initialized,
|
|
464
|
+
settingsLoadedFromCache: offline.inputs.settings?.status === 'loaded',
|
|
452
465
|
artifactDirectory: outDir,
|
|
453
466
|
...basicEventEvidence(events),
|
|
467
|
+
testEventsWithoutSourceFile: testEvents.length - testEvents.filter(test => test.testSourceFile).length,
|
|
468
|
+
testSourceFileCount: sourceFiles.size,
|
|
469
|
+
testSourceFiles: [...sourceFiles].slice(0, 5),
|
|
454
470
|
debugLines: findInterestingLines(output, [
|
|
455
471
|
/dd-trace/i,
|
|
456
472
|
/test optimization/i,
|
|
@@ -541,7 +557,15 @@ function inconclusive (framework, scenario, diagnosis, evidence = {}, outDir, ex
|
|
|
541
557
|
}
|
|
542
558
|
|
|
543
559
|
function error (framework, scenario, err, outDir = err?.artifactDirectory) {
|
|
544
|
-
|
|
560
|
+
const blockerEvidence = getValidationBlockerEvidence(err)
|
|
561
|
+
return result(
|
|
562
|
+
framework,
|
|
563
|
+
scenario,
|
|
564
|
+
blockerEvidence ? 'blocked' : 'error',
|
|
565
|
+
blockerEvidence ? err.message : (err && err.stack ? err.stack : String(err)),
|
|
566
|
+
blockerEvidence || {},
|
|
567
|
+
outDir
|
|
568
|
+
)
|
|
545
569
|
}
|
|
546
570
|
|
|
547
571
|
function result (framework, scenario, status, diagnosis, evidence, outDir, extraArtifacts) {
|
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
getFrameworkDefinitions,
|
|
9
9
|
runDiagnosis,
|
|
10
10
|
} = require('../diagnose')
|
|
11
|
+
const { BLOCKER_CATEGORIES } = require('./blocker-category')
|
|
11
12
|
const { sanitizeForReport } = require('./redaction')
|
|
12
13
|
const { writeFileSafely } = require('./safe-files')
|
|
13
14
|
|
|
@@ -45,6 +46,7 @@ function runStaticDiagnosis ({ manifest, out }) {
|
|
|
45
46
|
function getStaticBlocker (framework, diagnosis) {
|
|
46
47
|
if (!SUPPORTED_FRAMEWORKS.has(framework.framework)) {
|
|
47
48
|
return {
|
|
49
|
+
blockerCategory: BLOCKER_CATEGORIES.VALIDATOR_LIMITATION,
|
|
48
50
|
reason: `Unsupported test framework detected: ${getUnsupportedFrameworkName(framework)}.`,
|
|
49
51
|
recommendation: 'Choose Jest, Mocha, Cucumber, Cypress, Playwright, or Vitest for live validation.',
|
|
50
52
|
}
|
|
@@ -56,6 +58,7 @@ function getStaticBlocker (framework, diagnosis) {
|
|
|
56
58
|
const version = parseVersion(framework.frameworkVersion)
|
|
57
59
|
if (version && !satisfies(version, definition.supportedRange)) {
|
|
58
60
|
return {
|
|
61
|
+
blockerCategory: BLOCKER_CATEGORIES.UNSUPPORTED_VERSION,
|
|
59
62
|
reason:
|
|
60
63
|
`${definition.name} ${version} is not supported. Supported range is ${definition.supportedRange}.`,
|
|
61
64
|
recommendation: definition.recommendation,
|
|
@@ -65,6 +68,7 @@ function getStaticBlocker (framework, diagnosis) {
|
|
|
65
68
|
const staticVersionError = findStaticVersionError(definition, diagnosis, framework, version)
|
|
66
69
|
if (staticVersionError) {
|
|
67
70
|
return {
|
|
71
|
+
blockerCategory: BLOCKER_CATEGORIES.UNSUPPORTED_VERSION,
|
|
68
72
|
reason: staticVersionError.title,
|
|
69
73
|
recommendation: staticVersionError.recommendation || staticVersionError.message,
|
|
70
74
|
}
|
|
@@ -117,8 +121,11 @@ function getExactFrameworkLocations (diagnosis, framework) {
|
|
|
117
121
|
const locations = new Set()
|
|
118
122
|
addRelativeFrameworkLocation(locations, diagnosis, framework.project?.packageJson)
|
|
119
123
|
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
const configFiles = framework.project?.configFiles
|
|
125
|
+
if (configFiles) {
|
|
126
|
+
for (const configFile of configFiles) {
|
|
127
|
+
addRelativeFrameworkLocation(locations, diagnosis, configFile)
|
|
128
|
+
}
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
return locations
|
|
@@ -149,7 +156,7 @@ function normalizeRelativePath (location) {
|
|
|
149
156
|
|
|
150
157
|
function parseVersion (rawVersion) {
|
|
151
158
|
if (typeof rawVersion !== 'string') return null
|
|
152
|
-
const match = rawVersion.match(
|
|
159
|
+
const match = rawVersion.match(/(?<!\d)\d+\.\d+\.\d+/)
|
|
153
160
|
return match ? match[0] : null
|
|
154
161
|
}
|
|
155
162
|
|
|
@@ -4,7 +4,8 @@ const cypressAdapter = require('./framework-adapters/cypress')
|
|
|
4
4
|
const cucumberAdapter = require('./framework-adapters/cucumber')
|
|
5
5
|
const playwrightAdapter = require('./framework-adapters/playwright')
|
|
6
6
|
|
|
7
|
-
const ANSI_PATTERN =
|
|
7
|
+
const ANSI_PATTERN =
|
|
8
|
+
new RegExp(`${String.fromCharCode(27)}${String.raw`\[[\u0030-\u003F]*[\u0020-\u002F]*[\u0040-\u007E]`}`, 'g')
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Extracts the final test count from common JavaScript test-runner summaries.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function createValidationBlocker (message, { kind, recommendation, suppressReport = false }) {
|
|
4
|
+
const error = new Error(message)
|
|
5
|
+
error.validationBlocker = { kind, recommendation }
|
|
6
|
+
error.validationExitCode = 2
|
|
7
|
+
error.suppressReport = suppressReport
|
|
8
|
+
return error
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getValidationBlockerEvidence (error) {
|
|
12
|
+
if (!error?.validationBlocker) return
|
|
13
|
+
return {
|
|
14
|
+
blockerKind: error.validationBlocker.kind,
|
|
15
|
+
domain: 'validator_state',
|
|
16
|
+
recommendation: error.validationBlocker.recommendation,
|
|
17
|
+
validationIncomplete: true,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { createValidationBlocker, getValidationBlockerEvidence }
|
|
@@ -3,17 +3,19 @@ import { afterEach, beforeAll, beforeEach, inject } from 'vitest'
|
|
|
3
3
|
// Instrumentation-less setup for DD_EXPERIMENTAL_TEST_OPT_VITEST_NO_WORKER_INIT.
|
|
4
4
|
// It applies Test Optimization execution changes without initializing dd-trace and also supports Browser Mode.
|
|
5
5
|
const VITEST_NO_WORKER_INIT_ACTIVE_ENV = 'DD_TEST_OPT_VITEST_NO_WORKER_INIT_ACTIVE'
|
|
6
|
+
const SERIALIZED_CONTEXT_PREFIX = '\u0000dd-vitest-context:'
|
|
6
7
|
const providedContext = getProvidedContext()
|
|
7
8
|
const isNoWorkerInitActive = providedContext.isActive ?? getIsNoWorkerInitActive()
|
|
8
9
|
const attemptToFixTests = providedContext.attemptToFixTests || {}
|
|
9
10
|
const attemptToFixRetries = providedContext.attemptToFixRetries || 0
|
|
10
11
|
const disabledTests = providedContext.disabledTests || {}
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
:
|
|
15
|
-
|
|
16
|
-
const
|
|
12
|
+
const efdSuiteAdmissionBrowserCommand = providedContext.efdSuiteAdmissionBrowserCommand
|
|
13
|
+
const earlyFlakeDetectionRetryPolicy = providedContext.earlyFlakeDetectionRetryPolicy || {
|
|
14
|
+
durationRetryCounts: [],
|
|
15
|
+
schedulingRetryCount: 0,
|
|
16
|
+
}
|
|
17
|
+
const earlyFlakeDetectionRetries = earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
18
|
+
const isEfdSuiteAdmissionEnabled = providedContext.isEfdSuiteAdmissionEnabled === true
|
|
17
19
|
const isEarlyFlakeDetectionEnabled = providedContext.isEarlyFlakeDetectionEnabled === true
|
|
18
20
|
const knownTests = providedContext.knownTests || {}
|
|
19
21
|
const modifiedFiles = providedContext.modifiedFiles || {}
|
|
@@ -35,6 +37,7 @@ const earlyFlakeDetectionStartByTask = new WeakMap()
|
|
|
35
37
|
const nextAttemptIndexByTask = new WeakMap()
|
|
36
38
|
const retryAttemptIndexByTask = new WeakMap()
|
|
37
39
|
const usedRumTestExecutionIds = new Set()
|
|
40
|
+
let browserCommands
|
|
38
41
|
let now
|
|
39
42
|
let timeOrigin
|
|
40
43
|
// Use an unfaked monotonic clock in Node and Vitest's parent frame in Browser Mode.
|
|
@@ -49,18 +52,42 @@ if (typeof globalThis.process?.uptime === 'function') {
|
|
|
49
52
|
timeOrigin = Number.isFinite(clock?.timeOrigin) ? clock.timeOrigin : Date.now() - now()
|
|
50
53
|
}
|
|
51
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Requests permission from the Vitest main process to schedule Browser Mode EFD retries for one suite.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} testSuite
|
|
59
|
+
* @param {boolean} hasNewTest
|
|
60
|
+
* @returns {Promise<boolean>}
|
|
61
|
+
*/
|
|
62
|
+
async function requestBrowserEfdSuiteAdmission (testSuite, hasNewTest) {
|
|
63
|
+
try {
|
|
64
|
+
if (!browserCommands) {
|
|
65
|
+
const vitestBrowser = await import('@vitest/browser/context')
|
|
66
|
+
browserCommands = vitestBrowser.commands
|
|
67
|
+
}
|
|
68
|
+
return await browserCommands[efdSuiteAdmissionBrowserCommand](testSuite, hasNewTest) === true
|
|
69
|
+
} catch (error) {
|
|
70
|
+
// Browser Mode setup runs without dd-trace, so the tracer logger is unavailable.
|
|
71
|
+
globalThis.console?.error('Datadog Test Optimization could not request Vitest EFD suite admission.', error)
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
52
76
|
if (isNoWorkerInitActive) {
|
|
53
77
|
// eslint-disable-next-line no-empty-pattern
|
|
54
|
-
beforeAll(function ({}, suite) {
|
|
78
|
+
beforeAll(async function ({}, suite) {
|
|
55
79
|
suite ||= arguments[0]
|
|
56
|
-
|
|
80
|
+
const efdSuiteCandidate = getEarlyFlakeDetectionSuiteCandidate(suite)
|
|
81
|
+
const isEfdSuiteAdmissionAllowed = !efdSuiteCandidate || !isEfdSuiteAdmissionEnabled ||
|
|
82
|
+
await requestBrowserEfdSuiteAdmission(efdSuiteCandidate.testSuite, efdSuiteCandidate.hasNewTest)
|
|
83
|
+
applyExecutionChanges(suite, isEfdSuiteAdmissionAllowed)
|
|
57
84
|
})
|
|
58
85
|
|
|
59
86
|
beforeEach(function ({ onTestFinished, task, skip }) {
|
|
60
87
|
const testSuite = getTestSuite(task)
|
|
61
88
|
const testName = getTestName(task)
|
|
62
89
|
const isAttemptToFixTest = attemptToFixTests[testSuite]?.[testName]
|
|
63
|
-
const isEarlyFlakeDetectionTestAttempt =
|
|
90
|
+
const isEarlyFlakeDetectionTestAttempt = isEarlyFlakeDetectionTask(task)
|
|
64
91
|
const isQuarantinedTest = quarantinedTests[testSuite]?.[testName] && !isAttemptToFixTest
|
|
65
92
|
const attemptIndex = getNextAttemptIndex(task)
|
|
66
93
|
const attemptStart = now()
|
|
@@ -109,27 +136,30 @@ if (isNoWorkerInitActive) {
|
|
|
109
136
|
})
|
|
110
137
|
}
|
|
111
138
|
|
|
112
|
-
function applyExecutionChanges (suite) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
139
|
+
function applyExecutionChanges (suite, isEfdSuiteAdmissionAllowed) {
|
|
140
|
+
const tasks = suite?.tasks
|
|
141
|
+
if (tasks) {
|
|
142
|
+
for (const task of tasks) {
|
|
143
|
+
if (task.type === 'suite') {
|
|
144
|
+
applyExecutionChanges(task, isEfdSuiteAdmissionAllowed)
|
|
145
|
+
continue
|
|
146
|
+
}
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
const testSuite = getTestSuite(task)
|
|
149
|
+
const testName = getTestName(task)
|
|
150
|
+
if (attemptToFixTests[testSuite]?.[testName]) {
|
|
151
|
+
task.retry = 0
|
|
152
|
+
task.repeats = attemptToFixRetries
|
|
153
|
+
task.meta.__ddTestOptAtfRetries = attemptToFixRetries
|
|
154
|
+
} else if (disabledTests[testSuite]?.[testName]) {
|
|
155
|
+
task.mode = 'skip'
|
|
156
|
+
} else if (isEfdSuiteAdmissionAllowed && isEarlyFlakeDetectionTest(testSuite, testName)) {
|
|
157
|
+
task.retry = 0
|
|
158
|
+
task.repeats = earlyFlakeDetectionRetries
|
|
159
|
+
task.meta.__ddTestOptEfdRetries = earlyFlakeDetectionRetries
|
|
160
|
+
}
|
|
161
|
+
wrapRetryCondition(task)
|
|
131
162
|
}
|
|
132
|
-
wrapRetryCondition(task)
|
|
133
163
|
}
|
|
134
164
|
}
|
|
135
165
|
|
|
@@ -331,7 +361,7 @@ function recordTestOptimizationStatus (task, attemptIndex = task.result?.repeatC
|
|
|
331
361
|
|
|
332
362
|
if (attemptToFixTests[testSuite]?.[testName]) {
|
|
333
363
|
recordAttemptToFixStatus(task, attemptIndex, onlyIfNewErrors)
|
|
334
|
-
} else if (
|
|
364
|
+
} else if (isEarlyFlakeDetectionTask(task)) {
|
|
335
365
|
recordEarlyFlakeDetectionStatus(task, attemptIndex, onlyIfNewErrors)
|
|
336
366
|
} else if (task.repeats > 0) {
|
|
337
367
|
recordManualRepeatStatus(task, attemptIndex)
|
|
@@ -380,7 +410,7 @@ function recordEarlyFlakeDetectionStatus (task, attemptIndex, onlyIfNewErrors) {
|
|
|
380
410
|
earlyFlakeDetectionRetriesByTask.set(task, retryCount)
|
|
381
411
|
task.repeats = retryCount
|
|
382
412
|
task.meta.__ddTestOptEfdRetries = retryCount
|
|
383
|
-
if (retryCount === 0
|
|
413
|
+
if (retryCount === 0) {
|
|
384
414
|
task.meta.__ddTestOptEfdAbortReason = 'slow'
|
|
385
415
|
}
|
|
386
416
|
}
|
|
@@ -508,7 +538,7 @@ function getFinalAttemptIndex (task) {
|
|
|
508
538
|
if (attemptToFixTests[testSuite]?.[testName]) {
|
|
509
539
|
return getAttemptToFixRetryCount(task)
|
|
510
540
|
}
|
|
511
|
-
if (
|
|
541
|
+
if (isEarlyFlakeDetectionTask(task)) {
|
|
512
542
|
return getEarlyFlakeDetectionRetryCountForTask(task)
|
|
513
543
|
}
|
|
514
544
|
|
|
@@ -606,7 +636,7 @@ function prepareEarlyFlakeDetectionAttempt (task, attemptIndex) {
|
|
|
606
636
|
earlyFlakeDetectionRetriesByTask.set(task, retryCount)
|
|
607
637
|
task.repeats = retryCount
|
|
608
638
|
task.meta.__ddTestOptEfdRetries = retryCount
|
|
609
|
-
if (retryCount === 0
|
|
639
|
+
if (retryCount === 0) {
|
|
610
640
|
task.meta.__ddTestOptEfdAbortReason = 'slow'
|
|
611
641
|
}
|
|
612
642
|
}
|
|
@@ -633,16 +663,10 @@ function prepareEarlyFlakeDetectionAttempt (task, attemptIndex) {
|
|
|
633
663
|
}
|
|
634
664
|
|
|
635
665
|
function getEarlyFlakeDetectionRetryCount (task) {
|
|
636
|
-
if (!hasEarlyFlakeDetectionSlowRetries) {
|
|
637
|
-
return earlyFlakeDetectionRetries
|
|
638
|
-
}
|
|
639
|
-
|
|
640
666
|
const executionStart = earlyFlakeDetectionStartByTask.get(task)
|
|
641
667
|
const duration = executionStart === undefined ? task.result?.duration ?? 0 : now() - executionStart
|
|
642
|
-
for (const {
|
|
643
|
-
if (duration <
|
|
644
|
-
return earlyFlakeDetectionSlowRetries[key] ?? 0
|
|
645
|
-
}
|
|
668
|
+
for (const { durationLimitMs, retryCount } of earlyFlakeDetectionRetryPolicy.durationRetryCounts) {
|
|
669
|
+
if (duration < durationLimitMs) return retryCount
|
|
646
670
|
}
|
|
647
671
|
return 0
|
|
648
672
|
}
|
|
@@ -675,6 +699,64 @@ function isEarlyFlakeDetectionTest (testSuite, testName) {
|
|
|
675
699
|
return !testsForSuite.includes(testName)
|
|
676
700
|
}
|
|
677
701
|
|
|
702
|
+
/**
|
|
703
|
+
* Returns whether Datadog admitted this task for EFD retries.
|
|
704
|
+
*
|
|
705
|
+
* @param {object} task
|
|
706
|
+
* @returns {boolean}
|
|
707
|
+
*/
|
|
708
|
+
function isEarlyFlakeDetectionTask (task) {
|
|
709
|
+
return task.meta.__ddTestOptEfdRetries !== undefined
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Returns suite admission data when a collected suite contains an EFD candidate.
|
|
714
|
+
*
|
|
715
|
+
* @param {object} suite
|
|
716
|
+
* @returns {{ hasNewTest: boolean, testSuite: string }|undefined}
|
|
717
|
+
*/
|
|
718
|
+
function getEarlyFlakeDetectionSuiteCandidate (suite) {
|
|
719
|
+
const tasks = suite?.tasks
|
|
720
|
+
if (!tasks) return
|
|
721
|
+
|
|
722
|
+
let candidate
|
|
723
|
+
for (const task of tasks) {
|
|
724
|
+
if (task.type === 'suite') {
|
|
725
|
+
const nestedCandidate = getEarlyFlakeDetectionSuiteCandidate(task)
|
|
726
|
+
if (nestedCandidate) {
|
|
727
|
+
candidate ||= nestedCandidate
|
|
728
|
+
candidate.hasNewTest ||= nestedCandidate.hasNewTest
|
|
729
|
+
}
|
|
730
|
+
continue
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (task.mode === 'skip' || task.mode === 'todo') continue
|
|
734
|
+
|
|
735
|
+
const testSuite = getTestSuite(task)
|
|
736
|
+
const testName = getTestName(task)
|
|
737
|
+
if (attemptToFixTests[testSuite]?.[testName] || disabledTests[testSuite]?.[testName]) continue
|
|
738
|
+
if (!isEarlyFlakeDetectionTest(testSuite, testName)) continue
|
|
739
|
+
|
|
740
|
+
candidate ||= {
|
|
741
|
+
hasNewTest: false,
|
|
742
|
+
testSuite,
|
|
743
|
+
}
|
|
744
|
+
candidate.hasNewTest ||= isNewTest(testSuite, testName)
|
|
745
|
+
}
|
|
746
|
+
return candidate
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Returns whether a collected test is absent from the known-tests response.
|
|
751
|
+
*
|
|
752
|
+
* @param {string} testSuite
|
|
753
|
+
* @param {string} testName
|
|
754
|
+
* @returns {boolean}
|
|
755
|
+
*/
|
|
756
|
+
function isNewTest (testSuite, testName) {
|
|
757
|
+
return !(knownTests[testSuite] || []).includes(testName)
|
|
758
|
+
}
|
|
759
|
+
|
|
678
760
|
function isModifiedTest (testSuite) {
|
|
679
761
|
return modifiedFiles[testSuite]?.length > 0
|
|
680
762
|
}
|
|
@@ -716,12 +798,28 @@ function getIsNoWorkerInitActive () {
|
|
|
716
798
|
|
|
717
799
|
function getProvidedContext () {
|
|
718
800
|
try {
|
|
719
|
-
return inject('_ddVitestWorkerSetup')
|
|
801
|
+
return parseProvidedContextValue(inject('_ddVitestWorkerSetup'))
|
|
720
802
|
} catch {
|
|
721
803
|
try {
|
|
722
|
-
return globalThis.__vitest_worker__.providedContext._ddVitestWorkerSetup
|
|
804
|
+
return parseProvidedContextValue(globalThis.__vitest_worker__.providedContext._ddVitestWorkerSetup)
|
|
723
805
|
} catch {
|
|
724
806
|
return {}
|
|
725
807
|
}
|
|
726
808
|
}
|
|
727
809
|
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Restore context serialized to keep Vitest's inline browser bootstrap script valid.
|
|
813
|
+
*
|
|
814
|
+
* @param {object|string|undefined} value
|
|
815
|
+
* @returns {object}
|
|
816
|
+
*/
|
|
817
|
+
function parseProvidedContextValue (value) {
|
|
818
|
+
if (typeof value !== 'string' || !value.startsWith(SERIALIZED_CONTEXT_PREFIX)) return value || {}
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
return JSON.parse(value.slice(SERIALIZED_CONTEXT_PREFIX.length))
|
|
822
|
+
} catch {
|
|
823
|
+
return {}
|
|
824
|
+
}
|
|
825
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -71,7 +71,7 @@ interface Tracer extends opentracing.Tracer {
|
|
|
71
71
|
* @param plugin The name of a built-in plugin.
|
|
72
72
|
* @param config Configuration options. Can also be `false` to disable the plugin.
|
|
73
73
|
*/
|
|
74
|
-
use<P extends
|
|
74
|
+
use<P extends tracer.PluginName> (plugin: P, config?: tracer.PluginOptions[P] | boolean): this;
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Returns a reference to the current scope.
|
|
@@ -314,6 +314,9 @@ interface Plugins {
|
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
declare namespace tracer {
|
|
317
|
+
export interface PluginOptions extends Plugins {}
|
|
318
|
+
export type PluginName = keyof PluginOptions;
|
|
319
|
+
|
|
317
320
|
export type SpanOptions = Omit<opentracing.SpanOptions, 'childOf'> & {
|
|
318
321
|
/**
|
|
319
322
|
* Set childOf to 'null' to create a root span without a parent, even when a parent span
|
|
@@ -3711,6 +3714,13 @@ declare namespace tracer {
|
|
|
3711
3714
|
*/
|
|
3712
3715
|
submitEvaluation (spanContext: llmobs.ExportedLLMObsSpan, options: llmobs.EvaluationOptions): void
|
|
3713
3716
|
|
|
3717
|
+
/**
|
|
3718
|
+
* Submits end-user feedback for a span, trace, session, or customer-defined entity.
|
|
3719
|
+
* Exactly one target must be provided in the options.
|
|
3720
|
+
* @param options An object containing the label, metric type, value, submitter and target of the feedback.
|
|
3721
|
+
*/
|
|
3722
|
+
submitFeedback (options: llmobs.FeedbackOptions): void
|
|
3723
|
+
|
|
3714
3724
|
|
|
3715
3725
|
/**
|
|
3716
3726
|
* Annotates all spans, including auto-instrumented spans, with the provided tags created in the context of the callback function.
|
|
@@ -3957,6 +3967,93 @@ declare namespace tracer {
|
|
|
3957
3967
|
metadata?: { [key: string]: any }
|
|
3958
3968
|
}
|
|
3959
3969
|
|
|
3970
|
+
interface FeedbackSubmitter {
|
|
3971
|
+
/**
|
|
3972
|
+
* The identifier of the end user who submitted the feedback.
|
|
3973
|
+
*/
|
|
3974
|
+
id: string,
|
|
3975
|
+
|
|
3976
|
+
/**
|
|
3977
|
+
* The type of submitter, e.g. 'user'.
|
|
3978
|
+
*/
|
|
3979
|
+
type?: string
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3982
|
+
interface FeedbackOptions {
|
|
3983
|
+
/**
|
|
3984
|
+
* The name of the feedback metric
|
|
3985
|
+
*/
|
|
3986
|
+
label: string,
|
|
3987
|
+
|
|
3988
|
+
/**
|
|
3989
|
+
* The type of feedback metric, one of 'categorical', 'score', 'boolean', 'json' or 'text'
|
|
3990
|
+
*/
|
|
3991
|
+
metricType: 'categorical' | 'score' | 'boolean' | 'json' | 'text',
|
|
3992
|
+
|
|
3993
|
+
/**
|
|
3994
|
+
* The value of the feedback metric.
|
|
3995
|
+
* Must be string for 'categorical' and 'text' metrics, number for 'score' metrics, boolean for 'boolean' metrics and a JSON object for 'json' metrics.
|
|
3996
|
+
*/
|
|
3997
|
+
value: string | number | boolean | { [key: string]: any },
|
|
3998
|
+
|
|
3999
|
+
/**
|
|
4000
|
+
* Who submitted the feedback.
|
|
4001
|
+
*/
|
|
4002
|
+
submitter: llmobs.FeedbackSubmitter,
|
|
4003
|
+
|
|
4004
|
+
/**
|
|
4005
|
+
* The span context of the span to attach the feedback to, as returned by `llmobs.exportSpan()`.
|
|
4006
|
+
* Exactly one of `span`, `spanId`, `traceId`, `sessionId` or `feedbackJoinKey` must be provided.
|
|
4007
|
+
*/
|
|
4008
|
+
span?: llmobs.ExportedLLMObsSpan,
|
|
4009
|
+
|
|
4010
|
+
/**
|
|
4011
|
+
* The ID of the span to attach the feedback to.
|
|
4012
|
+
*/
|
|
4013
|
+
spanId?: string,
|
|
4014
|
+
|
|
4015
|
+
/**
|
|
4016
|
+
* The ID of the trace to attach the feedback to.
|
|
4017
|
+
*/
|
|
4018
|
+
traceId?: string,
|
|
4019
|
+
|
|
4020
|
+
/**
|
|
4021
|
+
* The ID of the session to attach the feedback to.
|
|
4022
|
+
*/
|
|
4023
|
+
sessionId?: string,
|
|
4024
|
+
|
|
4025
|
+
/**
|
|
4026
|
+
* A customer-defined key to attach the feedback to.
|
|
4027
|
+
*/
|
|
4028
|
+
feedbackJoinKey?: string,
|
|
4029
|
+
|
|
4030
|
+
/**
|
|
4031
|
+
* An object of string key-value pairs to tag the feedback with.
|
|
4032
|
+
* A `null` or `undefined` value is sent as the string `"null"` or `"undefined"`.
|
|
4033
|
+
*/
|
|
4034
|
+
tags?: { [key: string]: string | null | undefined },
|
|
4035
|
+
|
|
4036
|
+
/**
|
|
4037
|
+
* The name of the ML application
|
|
4038
|
+
*/
|
|
4039
|
+
mlApp?: string,
|
|
4040
|
+
|
|
4041
|
+
/**
|
|
4042
|
+
* The timestamp in milliseconds when the feedback was generated.
|
|
4043
|
+
*/
|
|
4044
|
+
timestampMs?: number,
|
|
4045
|
+
|
|
4046
|
+
/**
|
|
4047
|
+
* Reasoning for the feedback.
|
|
4048
|
+
*/
|
|
4049
|
+
reasoning?: string,
|
|
4050
|
+
|
|
4051
|
+
/**
|
|
4052
|
+
* Whether the feedback passed or failed. Valid values are pass and fail.
|
|
4053
|
+
*/
|
|
4054
|
+
assessment?: 'pass' | 'fail'
|
|
4055
|
+
}
|
|
4056
|
+
|
|
3960
4057
|
interface Document {
|
|
3961
4058
|
/**
|
|
3962
4059
|
* Document text
|
|
@@ -4002,6 +4099,11 @@ declare namespace tracer {
|
|
|
4002
4099
|
* Audio segments attached to the message (e.g. speech input/output)
|
|
4003
4100
|
*/
|
|
4004
4101
|
audioParts?: AudioPart[],
|
|
4102
|
+
|
|
4103
|
+
/**
|
|
4104
|
+
* Images attached to the message (e.g. vision input, generated output)
|
|
4105
|
+
*/
|
|
4106
|
+
imageParts?: ImagePart[],
|
|
4005
4107
|
}
|
|
4006
4108
|
|
|
4007
4109
|
/**
|
|
@@ -4019,6 +4121,43 @@ declare namespace tracer {
|
|
|
4019
4121
|
content: string,
|
|
4020
4122
|
}
|
|
4021
4123
|
|
|
4124
|
+
/**
|
|
4125
|
+
* Represents an image attached to an LLM chat model message, carrying exactly
|
|
4126
|
+
* one of inline `content` or an `attachmentKey`. Supplying neither or both is
|
|
4127
|
+
* rejected by the tagger, and the union keeps both shapes from type-checking.
|
|
4128
|
+
*/
|
|
4129
|
+
type ImagePart = {
|
|
4130
|
+
/**
|
|
4131
|
+
* The MIME type of the image (e.g. "image/png", "image/jpeg")
|
|
4132
|
+
*/
|
|
4133
|
+
mimeType: string,
|
|
4134
|
+
|
|
4135
|
+
/**
|
|
4136
|
+
* The image content as a base64-encoded string
|
|
4137
|
+
*/
|
|
4138
|
+
content: string,
|
|
4139
|
+
|
|
4140
|
+
/**
|
|
4141
|
+
* Explicitly excluded when inline content is present to maintain type safety.
|
|
4142
|
+
*/
|
|
4143
|
+
attachmentKey?: never,
|
|
4144
|
+
} | {
|
|
4145
|
+
/**
|
|
4146
|
+
* The MIME type of the image (e.g. "image/png", "image/jpeg")
|
|
4147
|
+
*/
|
|
4148
|
+
mimeType: string,
|
|
4149
|
+
|
|
4150
|
+
/**
|
|
4151
|
+
* Key of an already-uploaded image, in place of inline content
|
|
4152
|
+
*/
|
|
4153
|
+
attachmentKey: string,
|
|
4154
|
+
|
|
4155
|
+
/**
|
|
4156
|
+
* Explicitly excluded when an attachment key is present to maintain type safety.
|
|
4157
|
+
*/
|
|
4158
|
+
content?: never,
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4022
4161
|
/**
|
|
4023
4162
|
* Represents a single tool call for an LLM chat model message
|
|
4024
4163
|
*/
|
package/init.js
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
// JSON string after --require has already run so we extract them
|
|
5
|
-
// manually if present.
|
|
6
|
-
var pm2EnvStr = process.env.pm2_env
|
|
7
|
-
if (typeof pm2EnvStr === 'string') {
|
|
8
|
-
try {
|
|
9
|
-
var pm2Config = JSON.parse(pm2EnvStr)
|
|
10
|
-
var pm2Keys = Object.keys(pm2Config)
|
|
11
|
-
for (var i = 0; i < pm2Keys.length; i++) {
|
|
12
|
-
var k = pm2Keys[i]
|
|
13
|
-
var v = pm2Config[k]
|
|
14
|
-
if (v != null) {
|
|
15
|
-
process.env[k] = String(v)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
} catch (e) {}
|
|
19
|
-
}
|
|
3
|
+
require('./packages/dd-trace/src/guardrails/apply-pm2-env')
|
|
20
4
|
|
|
21
5
|
var guard = require('./packages/dd-trace/src/guardrails')
|
|
22
6
|
|