dd-trace 5.119.0 → 5.121.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.
|
|
@@ -316,6 +316,9 @@ interface Plugins {
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
declare namespace tracer {
|
|
319
|
+
export interface PluginOptions extends Plugins {}
|
|
320
|
+
export type PluginName = keyof PluginOptions;
|
|
321
|
+
|
|
319
322
|
export type SpanOptions = Omit<opentracing.SpanOptions, 'childOf'> & {
|
|
320
323
|
/**
|
|
321
324
|
* Set childOf to 'null' to create a root span without a parent, even when a parent span
|
|
@@ -3908,6 +3911,13 @@ declare namespace tracer {
|
|
|
3908
3911
|
*/
|
|
3909
3912
|
submitEvaluation (spanContext: llmobs.ExportedLLMObsSpan, options: llmobs.EvaluationOptions): void
|
|
3910
3913
|
|
|
3914
|
+
/**
|
|
3915
|
+
* Submits end-user feedback for a span, trace, session, or customer-defined entity.
|
|
3916
|
+
* Exactly one target must be provided in the options.
|
|
3917
|
+
* @param options An object containing the label, metric type, value, submitter and target of the feedback.
|
|
3918
|
+
*/
|
|
3919
|
+
submitFeedback (options: llmobs.FeedbackOptions): void
|
|
3920
|
+
|
|
3911
3921
|
|
|
3912
3922
|
/**
|
|
3913
3923
|
* Annotates all spans, including auto-instrumented spans, with the provided tags created in the context of the callback function.
|
|
@@ -4154,6 +4164,93 @@ declare namespace tracer {
|
|
|
4154
4164
|
metadata?: { [key: string]: any }
|
|
4155
4165
|
}
|
|
4156
4166
|
|
|
4167
|
+
interface FeedbackSubmitter {
|
|
4168
|
+
/**
|
|
4169
|
+
* The identifier of the end user who submitted the feedback.
|
|
4170
|
+
*/
|
|
4171
|
+
id: string,
|
|
4172
|
+
|
|
4173
|
+
/**
|
|
4174
|
+
* The type of submitter, e.g. 'user'.
|
|
4175
|
+
*/
|
|
4176
|
+
type?: string
|
|
4177
|
+
}
|
|
4178
|
+
|
|
4179
|
+
interface FeedbackOptions {
|
|
4180
|
+
/**
|
|
4181
|
+
* The name of the feedback metric
|
|
4182
|
+
*/
|
|
4183
|
+
label: string,
|
|
4184
|
+
|
|
4185
|
+
/**
|
|
4186
|
+
* The type of feedback metric, one of 'categorical', 'score', 'boolean', 'json' or 'text'
|
|
4187
|
+
*/
|
|
4188
|
+
metricType: 'categorical' | 'score' | 'boolean' | 'json' | 'text',
|
|
4189
|
+
|
|
4190
|
+
/**
|
|
4191
|
+
* The value of the feedback metric.
|
|
4192
|
+
* Must be string for 'categorical' and 'text' metrics, number for 'score' metrics, boolean for 'boolean' metrics and a JSON object for 'json' metrics.
|
|
4193
|
+
*/
|
|
4194
|
+
value: string | number | boolean | { [key: string]: any },
|
|
4195
|
+
|
|
4196
|
+
/**
|
|
4197
|
+
* Who submitted the feedback.
|
|
4198
|
+
*/
|
|
4199
|
+
submitter: llmobs.FeedbackSubmitter,
|
|
4200
|
+
|
|
4201
|
+
/**
|
|
4202
|
+
* The span context of the span to attach the feedback to, as returned by `llmobs.exportSpan()`.
|
|
4203
|
+
* Exactly one of `span`, `spanId`, `traceId`, `sessionId` or `feedbackJoinKey` must be provided.
|
|
4204
|
+
*/
|
|
4205
|
+
span?: llmobs.ExportedLLMObsSpan,
|
|
4206
|
+
|
|
4207
|
+
/**
|
|
4208
|
+
* The ID of the span to attach the feedback to.
|
|
4209
|
+
*/
|
|
4210
|
+
spanId?: string,
|
|
4211
|
+
|
|
4212
|
+
/**
|
|
4213
|
+
* The ID of the trace to attach the feedback to.
|
|
4214
|
+
*/
|
|
4215
|
+
traceId?: string,
|
|
4216
|
+
|
|
4217
|
+
/**
|
|
4218
|
+
* The ID of the session to attach the feedback to.
|
|
4219
|
+
*/
|
|
4220
|
+
sessionId?: string,
|
|
4221
|
+
|
|
4222
|
+
/**
|
|
4223
|
+
* A customer-defined key to attach the feedback to.
|
|
4224
|
+
*/
|
|
4225
|
+
feedbackJoinKey?: string,
|
|
4226
|
+
|
|
4227
|
+
/**
|
|
4228
|
+
* An object of string key-value pairs to tag the feedback with.
|
|
4229
|
+
* A `null` or `undefined` value is sent as the string `"null"` or `"undefined"`.
|
|
4230
|
+
*/
|
|
4231
|
+
tags?: { [key: string]: string | null | undefined },
|
|
4232
|
+
|
|
4233
|
+
/**
|
|
4234
|
+
* The name of the ML application
|
|
4235
|
+
*/
|
|
4236
|
+
mlApp?: string,
|
|
4237
|
+
|
|
4238
|
+
/**
|
|
4239
|
+
* The timestamp in milliseconds when the feedback was generated.
|
|
4240
|
+
*/
|
|
4241
|
+
timestampMs?: number,
|
|
4242
|
+
|
|
4243
|
+
/**
|
|
4244
|
+
* Reasoning for the feedback.
|
|
4245
|
+
*/
|
|
4246
|
+
reasoning?: string,
|
|
4247
|
+
|
|
4248
|
+
/**
|
|
4249
|
+
* Whether the feedback passed or failed. Valid values are pass and fail.
|
|
4250
|
+
*/
|
|
4251
|
+
assessment?: 'pass' | 'fail'
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4157
4254
|
interface Document {
|
|
4158
4255
|
/**
|
|
4159
4256
|
* Document text
|
|
@@ -4199,6 +4296,11 @@ declare namespace tracer {
|
|
|
4199
4296
|
* Audio segments attached to the message (e.g. speech input/output)
|
|
4200
4297
|
*/
|
|
4201
4298
|
audioParts?: AudioPart[],
|
|
4299
|
+
|
|
4300
|
+
/**
|
|
4301
|
+
* Images attached to the message (e.g. vision input, generated output)
|
|
4302
|
+
*/
|
|
4303
|
+
imageParts?: ImagePart[],
|
|
4202
4304
|
}
|
|
4203
4305
|
|
|
4204
4306
|
/**
|
|
@@ -4216,6 +4318,43 @@ declare namespace tracer {
|
|
|
4216
4318
|
content: string,
|
|
4217
4319
|
}
|
|
4218
4320
|
|
|
4321
|
+
/**
|
|
4322
|
+
* Represents an image attached to an LLM chat model message, carrying exactly
|
|
4323
|
+
* one of inline `content` or an `attachmentKey`. Supplying neither or both is
|
|
4324
|
+
* rejected by the tagger, and the union keeps both shapes from type-checking.
|
|
4325
|
+
*/
|
|
4326
|
+
type ImagePart = {
|
|
4327
|
+
/**
|
|
4328
|
+
* The MIME type of the image (e.g. "image/png", "image/jpeg")
|
|
4329
|
+
*/
|
|
4330
|
+
mimeType: string,
|
|
4331
|
+
|
|
4332
|
+
/**
|
|
4333
|
+
* The image content as a base64-encoded string
|
|
4334
|
+
*/
|
|
4335
|
+
content: string,
|
|
4336
|
+
|
|
4337
|
+
/**
|
|
4338
|
+
* Explicitly excluded when inline content is present to maintain type safety.
|
|
4339
|
+
*/
|
|
4340
|
+
attachmentKey?: never,
|
|
4341
|
+
} | {
|
|
4342
|
+
/**
|
|
4343
|
+
* The MIME type of the image (e.g. "image/png", "image/jpeg")
|
|
4344
|
+
*/
|
|
4345
|
+
mimeType: string,
|
|
4346
|
+
|
|
4347
|
+
/**
|
|
4348
|
+
* Key of an already-uploaded image, in place of inline content
|
|
4349
|
+
*/
|
|
4350
|
+
attachmentKey: string,
|
|
4351
|
+
|
|
4352
|
+
/**
|
|
4353
|
+
* Explicitly excluded when an attachment key is present to maintain type safety.
|
|
4354
|
+
*/
|
|
4355
|
+
content?: never,
|
|
4356
|
+
}
|
|
4357
|
+
|
|
4219
4358
|
/**
|
|
4220
4359
|
* Represents a single tool call for an LLM chat model message
|
|
4221
4360
|
*/
|
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
|
|