dd-trace 6.16.0 → 6.18.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 +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +208 -0
- package/package.json +17 -16
- package/packages/datadog-esbuild/src/utils.js +0 -2
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +77 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +27 -38
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -6
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +24 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +111 -26
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +55 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +28 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +20 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +165 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -26
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +51 -12
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +6 -20
- package/packages/datadog-instrumentations/src/playwright.js +280 -56
- package/packages/datadog-instrumentations/src/{azure-cosmos.js → postgres.js} +1 -1
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/undici.js +7 -3
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +121 -30
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
- package/packages/datadog-instrumentations/src/webdriverio.js +44 -47
- package/packages/datadog-instrumentations/src/ws.js +41 -2
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
- package/packages/datadog-plugin-cucumber/src/index.js +9 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +211 -85
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/index.js +3 -1
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +12 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +38 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +81 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +9 -0
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-shimmer/src/shimmer.js +14 -10
- package/packages/datadog-turbopack/index.js +4 -7
- package/packages/datadog-turbopack/src/loader.js +6 -18
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/agent/info.js +5 -4
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +2 -2
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +88 -82
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +31 -30
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +150 -10
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
- package/packages/dd-trace/src/debugger/devtools_client/config.js +4 -1
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +41 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +21 -7
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +51 -3
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/constants.js +2 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +17 -13
- package/packages/dd-trace/src/evp_proxy/discovery.js +14 -11
- package/packages/dd-trace/src/evp_proxy/path.js +21 -9
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +33 -4
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +647 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +158 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +39 -11
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/configuration_source.js +4 -1
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -3
- package/packages/dd-trace/src/openfeature/index.js +6 -6
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +90 -23
- package/packages/dd-trace/src/openfeature/writers/exposures.js +4 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +104 -37
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/opentracing/tracer.js +3 -3
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugin_manager.js +27 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +26 -20
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +23 -47
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/send-data.js +2 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/tracer.js +5 -4
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/datadog-instrumentations/src/bullmq.js +0 -11
- package/packages/datadog-instrumentations/src/langchain.js +0 -7
- package/packages/datadog-instrumentations/src/langgraph.js +0 -7
- package/packages/datadog-instrumentations/src/mercurius.js +0 -11
|
@@ -9,6 +9,7 @@ const { keepTrace } = require('../priority_sampler')
|
|
|
9
9
|
const { extractIp } = require('../plugins/util/ip_extractor')
|
|
10
10
|
const { AI_GUARD } = require('../standalone/product')
|
|
11
11
|
const telemetryMetrics = require('../telemetry/metrics')
|
|
12
|
+
const { truncateString } = require('../util')
|
|
12
13
|
const { normalizeRedactionReplacements, redactMessages } = require('./redaction')
|
|
13
14
|
const TAGS = require('./tags')
|
|
14
15
|
|
|
@@ -96,7 +97,6 @@ function parseEvaluationResponse (body) {
|
|
|
96
97
|
*
|
|
97
98
|
* @param {boolean} block
|
|
98
99
|
* @param {{ action: string, blockingEnabled: boolean }} evaluation
|
|
99
|
-
* @returns {boolean}
|
|
100
100
|
*/
|
|
101
101
|
function shouldBlockEvaluation (block, evaluation) {
|
|
102
102
|
return block && evaluation.blockingEnabled && evaluation.action !== ALLOW
|
|
@@ -158,9 +158,9 @@ class EvaluationReporter {
|
|
|
158
158
|
*/
|
|
159
159
|
constructor (config) {
|
|
160
160
|
this.#config = config
|
|
161
|
-
this.#maxMessagesLength = config.
|
|
162
|
-
this.#maxContentSize = config.
|
|
163
|
-
this.#redactionEnabled = config.
|
|
161
|
+
this.#maxMessagesLength = config.aiguard.DD_AI_GUARD_MAX_MESSAGES_LENGTH
|
|
162
|
+
this.#maxContentSize = config.aiguard.DD_AI_GUARD_MAX_CONTENT_SIZE
|
|
163
|
+
this.#redactionEnabled = config.aiguard.DD_AI_GUARD_REDACTION_ENABLED
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
/**
|
|
@@ -211,7 +211,6 @@ class EvaluationReporter {
|
|
|
211
211
|
*
|
|
212
212
|
* @param {EvaluationReport} report
|
|
213
213
|
* @param {string} errorType
|
|
214
|
-
* @returns {void}
|
|
215
214
|
*/
|
|
216
215
|
fail (report, errorType) {
|
|
217
216
|
report.metaStruct.messages = this.#buildMessagesForMetaStruct(report.messages, report.telemetryTags)
|
|
@@ -224,7 +223,6 @@ class EvaluationReporter {
|
|
|
224
223
|
*
|
|
225
224
|
* @param {EvaluationReport} report
|
|
226
225
|
* @param {EvaluationOutcome} outcome
|
|
227
|
-
* @returns {void}
|
|
228
226
|
*/
|
|
229
227
|
finish (report, outcome) {
|
|
230
228
|
const { result, redaction, shouldBlock } = outcome
|
|
@@ -299,14 +297,13 @@ class EvaluationReporter {
|
|
|
299
297
|
* Truncates text in a cloned message to one shared content-size limit.
|
|
300
298
|
*
|
|
301
299
|
* @param {{ content?: string|ContentPart[] }} message
|
|
302
|
-
* @returns {boolean}
|
|
303
300
|
*/
|
|
304
301
|
#truncateMessageContent (message) {
|
|
305
302
|
const { content } = message
|
|
306
303
|
if (typeof content === 'string') {
|
|
307
304
|
if (content.length <= this.#maxContentSize) return false
|
|
308
305
|
|
|
309
|
-
message.content = content
|
|
306
|
+
message.content = truncateString(content, this.#maxContentSize)
|
|
310
307
|
return true
|
|
311
308
|
}
|
|
312
309
|
|
|
@@ -319,7 +316,7 @@ class EvaluationReporter {
|
|
|
319
316
|
if (typeof text !== 'string') continue
|
|
320
317
|
|
|
321
318
|
if (text.length > remainingContentSize) {
|
|
322
|
-
part.text = text
|
|
319
|
+
part.text = truncateString(text, remainingContentSize)
|
|
323
320
|
truncated = true
|
|
324
321
|
remainingContentSize = 0
|
|
325
322
|
} else {
|
|
@@ -333,7 +330,6 @@ class EvaluationReporter {
|
|
|
333
330
|
* Returns whether a message represents a tool call or tool output.
|
|
334
331
|
*
|
|
335
332
|
* @param {Message} message
|
|
336
|
-
* @returns {boolean}
|
|
337
333
|
*/
|
|
338
334
|
#isToolCall (message) {
|
|
339
335
|
return Boolean(message.tool_calls || message.tool_call_id)
|
|
@@ -370,7 +366,6 @@ class EvaluationReporter {
|
|
|
370
366
|
* Adds missing client IP tags to the service entry span.
|
|
371
367
|
*
|
|
372
368
|
* @param {Span} rootSpan
|
|
373
|
-
* @returns {void}
|
|
374
369
|
*/
|
|
375
370
|
#setRootSpanClientIpTags (rootSpan) {
|
|
376
371
|
const currentTags = rootSpan.context().getTags()
|
|
@@ -411,7 +406,6 @@ class EvaluationReporter {
|
|
|
411
406
|
*
|
|
412
407
|
* @param {Span} guardSpan
|
|
413
408
|
* @param {Span} rootSpan
|
|
414
|
-
* @returns {void}
|
|
415
409
|
*/
|
|
416
410
|
#copyServiceEntryTagsToGuardSpan (guardSpan, rootSpan) {
|
|
417
411
|
const rootTags = rootSpan.context().getTags()
|
|
@@ -17,8 +17,8 @@ function enable (tracer, config) {
|
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
19
|
aiguard = new AIGuard(tracer, config)
|
|
20
|
-
const block = config.
|
|
21
|
-
const analyzeStreamResponses = config.DD_AI_GUARD_ANALYZE_STREAM_RESPONSES_ENABLED
|
|
20
|
+
const block = config.aiguard.DD_AI_GUARD_BLOCK !== false
|
|
21
|
+
const analyzeStreamResponses = config.aiguard.DD_AI_GUARD_ANALYZE_STREAM_RESPONSES_ENABLED
|
|
22
22
|
|
|
23
23
|
incomingHttpRequestStart.subscribe(onIncomingHttpRequestStart)
|
|
24
24
|
integrations.enable(aiguard, block, analyzeStreamResponses)
|
|
@@ -17,7 +17,7 @@ function enable (aiguard, block, analyzeStreamResponses) {
|
|
|
17
17
|
if (isEnabled) return
|
|
18
18
|
|
|
19
19
|
anthropic.enable(aiguard, block)
|
|
20
|
-
openai.enable(aiguard, block)
|
|
20
|
+
openai.enable(aiguard, block, analyzeStreamResponses)
|
|
21
21
|
vercelAi.enable(aiguard, block, analyzeStreamResponses)
|
|
22
22
|
|
|
23
23
|
isEnabled = true
|
|
@@ -7,6 +7,8 @@ const {
|
|
|
7
7
|
getChatCompletionsOutputMessages,
|
|
8
8
|
getResponsesInputMessages,
|
|
9
9
|
getResponsesOutputMessages,
|
|
10
|
+
getStreamedChatCompletionsOutputMessages,
|
|
11
|
+
getStreamedResponsesOutputMessages,
|
|
10
12
|
} = require('../messages/openai')
|
|
11
13
|
const { decode } = require('../messages/utils')
|
|
12
14
|
const { SOURCE_AUTO } = require('../tags')
|
|
@@ -18,18 +20,21 @@ const responsesInterceptChannel = channel('dd-trace:openai:responses:intercept')
|
|
|
18
20
|
let isEnabled = false
|
|
19
21
|
let aiguard
|
|
20
22
|
let opts
|
|
23
|
+
let analyzeStreamResponses
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Subscribes AI Guard to the OpenAI interception channels.
|
|
24
27
|
*
|
|
25
28
|
* @param {object} aiguardInstance
|
|
26
29
|
* @param {boolean} block
|
|
30
|
+
* @param {boolean} analyzeStreams
|
|
27
31
|
*/
|
|
28
|
-
function enable (aiguardInstance, block) {
|
|
32
|
+
function enable (aiguardInstance, block, analyzeStreams) {
|
|
29
33
|
if (isEnabled) return
|
|
30
34
|
|
|
31
35
|
aiguard = aiguardInstance
|
|
32
36
|
opts = { block, source: SOURCE_AUTO, integration: 'openai' }
|
|
37
|
+
analyzeStreamResponses = analyzeStreams
|
|
33
38
|
|
|
34
39
|
chatCompletionsInterceptChannel.subscribe(onChatCompletions)
|
|
35
40
|
responsesInterceptChannel.subscribe(onResponses)
|
|
@@ -45,6 +50,7 @@ function disable () {
|
|
|
45
50
|
|
|
46
51
|
aiguard = undefined
|
|
47
52
|
opts = undefined
|
|
53
|
+
analyzeStreamResponses = undefined
|
|
48
54
|
isEnabled = false
|
|
49
55
|
}
|
|
50
56
|
|
|
@@ -52,7 +58,6 @@ function onChatCompletions (ctx) {
|
|
|
52
58
|
const inputMessages = getChatCompletionsInputMessages(ctx.arguments?.[0])
|
|
53
59
|
if (!inputMessages?.length) return
|
|
54
60
|
|
|
55
|
-
// `parse` and `asResponse` are both wrapped, and either may run more than once per call.
|
|
56
61
|
let inputEvaluation
|
|
57
62
|
ctx.beforeResult = () => {
|
|
58
63
|
if (!isEnabled) return
|
|
@@ -60,18 +65,27 @@ function onChatCompletions (ctx) {
|
|
|
60
65
|
return inputEvaluation
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
const isStream = ctx.arguments[0].stream
|
|
69
|
+
if (isStream && !analyzeStreamResponses) return
|
|
70
|
+
|
|
64
71
|
let outputEvaluation
|
|
65
72
|
ctx.onResult = body => {
|
|
66
73
|
if (!isEnabled) return body
|
|
67
74
|
|
|
75
|
+
if (isStream) {
|
|
76
|
+
outputEvaluation ??= interceptStream(body, chunks => {
|
|
77
|
+
return getStreamedChatCompletionsOutputMessages(chunks)
|
|
78
|
+
.map(message => [...inputMessages, message])
|
|
79
|
+
}, ctx)
|
|
80
|
+
return outputEvaluation
|
|
81
|
+
}
|
|
82
|
+
|
|
68
83
|
const conversations = decode(
|
|
69
84
|
() => getChatCompletionsOutputMessages(body).map(message => [...inputMessages, message]),
|
|
70
85
|
null,
|
|
71
86
|
'AIGuard: unable to decode OpenAI response body: %s'
|
|
72
87
|
)
|
|
73
|
-
if (conversations
|
|
74
|
-
if (conversations.length === 0) return body
|
|
88
|
+
if (!conversations?.length) return body
|
|
75
89
|
|
|
76
90
|
outputEvaluation ??= evaluate(ctx, aiguard, conversations, opts)
|
|
77
91
|
return outputEvaluation.then(() => body)
|
|
@@ -89,21 +103,81 @@ function onResponses (ctx) {
|
|
|
89
103
|
return inputEvaluation
|
|
90
104
|
}
|
|
91
105
|
|
|
106
|
+
const isStream = ctx.arguments[0].stream
|
|
107
|
+
if (isStream && !analyzeStreamResponses) return
|
|
108
|
+
|
|
92
109
|
let outputEvaluation
|
|
93
110
|
ctx.onResult = body => {
|
|
94
111
|
if (!isEnabled) return body
|
|
95
112
|
|
|
113
|
+
if (isStream) {
|
|
114
|
+
outputEvaluation ??= interceptStream(body, chunks => {
|
|
115
|
+
const outputMessages = getStreamedResponsesOutputMessages(chunks)
|
|
116
|
+
return outputMessages.length ? [[...inputMessages, ...outputMessages]] : []
|
|
117
|
+
}, ctx)
|
|
118
|
+
return outputEvaluation
|
|
119
|
+
}
|
|
120
|
+
|
|
96
121
|
const outputMessages = decode(
|
|
97
122
|
() => getResponsesOutputMessages(body),
|
|
98
123
|
null,
|
|
99
124
|
'AIGuard: unable to decode OpenAI response body: %s'
|
|
100
125
|
)
|
|
101
|
-
if (outputMessages
|
|
102
|
-
if (!outputMessages.length) return body
|
|
126
|
+
if (!outputMessages?.length) return body
|
|
103
127
|
|
|
104
128
|
outputEvaluation ??= evaluate(ctx, aiguard, [[...inputMessages, ...outputMessages]], opts)
|
|
105
129
|
return outputEvaluation.then(() => body)
|
|
106
130
|
}
|
|
107
131
|
}
|
|
108
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Uses the OpenAI SDK's stream splitting support to evaluate one branch and return the other.
|
|
135
|
+
*
|
|
136
|
+
* @param {object} stream
|
|
137
|
+
* @param {(chunks: Array<object>) => Array<Array<object>>} getConversations
|
|
138
|
+
* @param {object} ctx
|
|
139
|
+
* @returns {object|Promise<object>}
|
|
140
|
+
*/
|
|
141
|
+
function interceptStream (stream, getConversations, ctx) {
|
|
142
|
+
if (typeof stream?.tee !== 'function') return stream
|
|
143
|
+
|
|
144
|
+
let branches
|
|
145
|
+
try {
|
|
146
|
+
branches = stream.tee()
|
|
147
|
+
} catch {
|
|
148
|
+
return stream
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [evaluationStream, resultStream] = branches
|
|
152
|
+
return drainStream(evaluationStream).then(chunks => {
|
|
153
|
+
if (!isEnabled) return resultStream
|
|
154
|
+
const conversations = decode(
|
|
155
|
+
() => getConversations(chunks),
|
|
156
|
+
null,
|
|
157
|
+
'AIGuard: unable to decode the streamed OpenAI response: %s'
|
|
158
|
+
)
|
|
159
|
+
if (!conversations?.length) return resultStream
|
|
160
|
+
return evaluate(ctx, aiguard, conversations, opts).then(() => resultStream)
|
|
161
|
+
}, () => resultStream)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @param {object} stream
|
|
166
|
+
* @returns {Promise<Array<object>>}
|
|
167
|
+
*/
|
|
168
|
+
function drainStream (stream) {
|
|
169
|
+
const chunks = []
|
|
170
|
+
const iterator = stream[Symbol.asyncIterator]()
|
|
171
|
+
|
|
172
|
+
function readAll () {
|
|
173
|
+
return iterator.next().then(({ done, value }) => {
|
|
174
|
+
if (done) return chunks
|
|
175
|
+
chunks.push(value)
|
|
176
|
+
return readAll()
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return readAll()
|
|
181
|
+
}
|
|
182
|
+
|
|
109
183
|
module.exports = { enable, disable }
|
|
@@ -220,7 +220,6 @@ function partsToContent (parts, hasImages) {
|
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
222
|
* @param {Array<object>} parts
|
|
223
|
-
* @returns {boolean}
|
|
224
223
|
*/
|
|
225
224
|
function hasImageParts (parts) {
|
|
226
225
|
return parts.some(part => part.type === 'image_url')
|
|
@@ -267,7 +266,6 @@ function convertAnthropicToolResultContent (content) {
|
|
|
267
266
|
|
|
268
267
|
/**
|
|
269
268
|
* @param {unknown} content
|
|
270
|
-
* @returns {string}
|
|
271
269
|
*/
|
|
272
270
|
function convertServerToolResultContent (content) {
|
|
273
271
|
if (typeof content === 'string') return content || '[tool result]'
|
|
@@ -195,6 +195,68 @@ function getResponsesOutputMessages (body) {
|
|
|
195
195
|
return convertOpenAIResponseItemsToMessages(body?.output, 'assistant')
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Combines streamed chat completion deltas into regular output messages.
|
|
200
|
+
*
|
|
201
|
+
* @param {Array<object>} chunks
|
|
202
|
+
* @returns {Array<object>}
|
|
203
|
+
*/
|
|
204
|
+
function getStreamedChatCompletionsOutputMessages (chunks) {
|
|
205
|
+
const messages = new Map()
|
|
206
|
+
|
|
207
|
+
for (const chunk of chunks) {
|
|
208
|
+
if (!Array.isArray(chunk?.choices)) continue
|
|
209
|
+
for (const choice of chunk.choices) {
|
|
210
|
+
const delta = choice.delta
|
|
211
|
+
if (!delta) continue
|
|
212
|
+
|
|
213
|
+
const index = choice.index ?? 0
|
|
214
|
+
const message = messages.get(index) ?? { role: 'assistant' }
|
|
215
|
+
messages.set(index, message)
|
|
216
|
+
|
|
217
|
+
if (typeof delta.role === 'string') message.role = delta.role
|
|
218
|
+
if (typeof delta.content === 'string') message.content = (message.content ?? '') + delta.content
|
|
219
|
+
if (typeof delta.refusal === 'string') message.refusal = (message.refusal ?? '') + delta.refusal
|
|
220
|
+
|
|
221
|
+
if (delta.function_call) {
|
|
222
|
+
const functionCall = message.function_call ??= {}
|
|
223
|
+
functionCall.name ??= delta.function_call.name
|
|
224
|
+
if (typeof delta.function_call.arguments === 'string') {
|
|
225
|
+
functionCall.arguments = (functionCall.arguments ?? '') + delta.function_call.arguments
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!Array.isArray(delta.tool_calls)) continue
|
|
230
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
231
|
+
const toolCalls = message.tool_calls ??= []
|
|
232
|
+
const toolCall = toolCalls[toolCallDelta.index ?? 0] ??= { function: {} }
|
|
233
|
+
toolCall.id ??= toolCallDelta.id
|
|
234
|
+
toolCall.type ??= toolCallDelta.type
|
|
235
|
+
toolCall.function.name ??= toolCallDelta.function?.name
|
|
236
|
+
if (typeof toolCallDelta.function?.arguments === 'string') {
|
|
237
|
+
toolCall.function.arguments = (toolCall.function.arguments ?? '') + toolCallDelta.function.arguments
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const choices = [...messages.values()].map(message => {
|
|
244
|
+
if (message.tool_calls) message.tool_calls = message.tool_calls.filter(Boolean)
|
|
245
|
+
return { message }
|
|
246
|
+
})
|
|
247
|
+
return getChatCompletionsOutputMessages({ choices })
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Gets output messages from the final response snapshot in a Responses API stream.
|
|
252
|
+
*
|
|
253
|
+
* @param {Array<object>} chunks
|
|
254
|
+
* @returns {Array<object>}
|
|
255
|
+
*/
|
|
256
|
+
function getStreamedResponsesOutputMessages (chunks) {
|
|
257
|
+
return getResponsesOutputMessages(chunks.at(-1)?.response)
|
|
258
|
+
}
|
|
259
|
+
|
|
198
260
|
/**
|
|
199
261
|
* Converts one OpenAI reusable prompt variable value to message content.
|
|
200
262
|
*
|
|
@@ -348,7 +410,6 @@ function openAIResponseImageContentPart (part) {
|
|
|
348
410
|
* Extracts a stable text marker from an OpenAI file content part.
|
|
349
411
|
*
|
|
350
412
|
* @param {{file_id?: string|null, file_url?: string, filename?: string, file_data?: string}} part
|
|
351
|
-
* @returns {string}
|
|
352
413
|
*/
|
|
353
414
|
function openAIResponseFileContentPart (part) {
|
|
354
415
|
return part.file_id ?? part.file_url ?? part.filename ?? FILE_FALLBACK
|
|
@@ -362,5 +423,7 @@ module.exports = {
|
|
|
362
423
|
convertOpenAIResponsePromptToMessages,
|
|
363
424
|
getResponsesInputMessages,
|
|
364
425
|
getResponsesOutputMessages,
|
|
426
|
+
getStreamedChatCompletionsOutputMessages,
|
|
427
|
+
getStreamedResponsesOutputMessages,
|
|
365
428
|
openAIResponseContentToMessageContent,
|
|
366
429
|
}
|
|
@@ -49,7 +49,6 @@ function parsePath (path) {
|
|
|
49
49
|
* Reports whether a parsed path targets an allowed message string.
|
|
50
50
|
*
|
|
51
51
|
* @param {Array<{ name: string, index: number|undefined }>} segments
|
|
52
|
-
* @returns {boolean}
|
|
53
52
|
*/
|
|
54
53
|
function isRedactablePath (segments) {
|
|
55
54
|
const first = segments[0]
|
|
@@ -30,7 +30,7 @@ class AIGuard extends NoopAIGuard {
|
|
|
30
30
|
this.#tracer = tracer
|
|
31
31
|
this.#client = new AIGuardClient(config)
|
|
32
32
|
this.#reporter = new EvaluationReporter(config)
|
|
33
|
-
this.#redactionEnabled = config.
|
|
33
|
+
this.#redactionEnabled = config.aiguard.DD_AI_GUARD_REDACTION_ENABLED
|
|
34
34
|
this.#meta = { service: config.service, env: config.env }
|
|
35
35
|
this.#initialized = true
|
|
36
36
|
}
|
|
@@ -215,7 +215,6 @@ function compileRoute (route, parse, makeMatcher) {
|
|
|
215
215
|
* @param {number} g
|
|
216
216
|
* @param {Map<number, number>} groupParent
|
|
217
217
|
* @param {Set<number>} present
|
|
218
|
-
* @returns {boolean}
|
|
219
218
|
*/
|
|
220
219
|
function groupActive (g, groupParent, present) {
|
|
221
220
|
while (g !== 0) {
|
|
@@ -229,7 +228,6 @@ function groupActive (g, groupParent, present) {
|
|
|
229
228
|
* URL-encode chars outside the RFC-1103 static alphabet [A-Za-z0-9.-~_]. The 'u' flag iterates whole
|
|
230
229
|
* codepoints so surrogate pairs encode as correct multi-byte UTF-8.
|
|
231
230
|
* @param {string} str
|
|
232
|
-
* @returns {string}
|
|
233
231
|
*/
|
|
234
232
|
function encodeStaticSegment (str) {
|
|
235
233
|
return str.replaceAll(/[^A-Za-z0-9.\-~_]/gu, c => {
|
|
@@ -246,7 +244,6 @@ function encodeStaticSegment (str) {
|
|
|
246
244
|
/**
|
|
247
245
|
* URL-encode the 6 characters not allowed in a normalized param name (/?#+{}).
|
|
248
246
|
* @param {string} name
|
|
249
|
-
* @returns {string}
|
|
250
247
|
*/
|
|
251
248
|
function encodeParamName (name) {
|
|
252
249
|
return name.replaceAll(/[/?#+{}]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'))
|
|
@@ -256,7 +253,6 @@ function encodeParamName (name) {
|
|
|
256
253
|
* Render the normalized route for a given set of present optional groups.
|
|
257
254
|
* @param {CompiledRoute} compiled
|
|
258
255
|
* @param {Set<number>} present
|
|
259
|
-
* @returns {string}
|
|
260
256
|
*/
|
|
261
257
|
function renderRoute (compiled, present) {
|
|
262
258
|
const { segments, groupParent } = compiled
|
|
@@ -367,7 +363,6 @@ function resolvePresence (compiled, params) {
|
|
|
367
363
|
* Stable bitmask key for a present-group set (group ids are small, route-local).
|
|
368
364
|
* @param {number[]} optionalGroups
|
|
369
365
|
* @param {Set<number>} present
|
|
370
|
-
* @returns {number}
|
|
371
366
|
*/
|
|
372
367
|
function presenceBitmask (optionalGroups, present) {
|
|
373
368
|
let mask = 0
|
|
@@ -122,7 +122,6 @@ function sampleRequest (req, res, record = false) {
|
|
|
122
122
|
*
|
|
123
123
|
* @param {string|undefined} route
|
|
124
124
|
* @param {boolean} record
|
|
125
|
-
* @returns {boolean}
|
|
126
125
|
*/
|
|
127
126
|
function isRoutelessRecord (route, record) {
|
|
128
127
|
return record && route === undefined
|
|
@@ -130,7 +129,6 @@ function isRoutelessRecord (route, record) {
|
|
|
130
129
|
|
|
131
130
|
/**
|
|
132
131
|
* @param {number|string} statusCode
|
|
133
|
-
* @returns {boolean}
|
|
134
132
|
*/
|
|
135
133
|
function isNotFound (statusCode) {
|
|
136
134
|
return Number(statusCode) === 404
|
|
@@ -141,7 +139,6 @@ function isNotFound (statusCode) {
|
|
|
141
139
|
* @param {string|undefined} route A route string, an empty string (still a valid route), or
|
|
142
140
|
* `undefined`
|
|
143
141
|
* @param {number|string} statusCode
|
|
144
|
-
* @returns {string}
|
|
145
142
|
*/
|
|
146
143
|
function buildSamplingKey (method, route, statusCode) {
|
|
147
144
|
return method + (route ?? '') + statusCode
|
|
@@ -176,7 +173,6 @@ function getRouteOrEndpoint (context, statusCode) {
|
|
|
176
173
|
* regardless of the APM sampling decision.
|
|
177
174
|
*
|
|
178
175
|
* @param {DatadogSpan} rootSpan
|
|
179
|
-
* @returns {boolean}
|
|
180
176
|
*/
|
|
181
177
|
function isRejected (rootSpan) {
|
|
182
178
|
if (asmStandaloneEnabled) return false
|
|
@@ -204,9 +204,9 @@ function handleResults (actions, req, res, rootSpan, abortController) {
|
|
|
204
204
|
* @param {import('../../config/config-base')} [config] - Tracer configuration
|
|
205
205
|
*/
|
|
206
206
|
function setTemplates (config) {
|
|
207
|
-
templates.html.body = config?.appsec?.
|
|
208
|
-
templates.json.body = config?.appsec?.
|
|
209
|
-
templates.graphqlJson.body = config?.appsec?.
|
|
207
|
+
templates.html.body = config?.appsec?.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
|
|
208
|
+
templates.json.body = config?.appsec?.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
|
|
209
|
+
templates.graphqlJson.body = config?.appsec?.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON
|
|
210
210
|
|
|
211
211
|
for (const type of Object.keys(templates)) {
|
|
212
212
|
const template = templates[type]
|
|
@@ -102,7 +102,6 @@ function recordResponseBodyIgnored (req, tag) {
|
|
|
102
102
|
/**
|
|
103
103
|
* @param {import('http').IncomingMessage} originatingReq inbound request (for metrics).
|
|
104
104
|
* @param {import('http').IncomingMessage} res downstream response.
|
|
105
|
-
* @returns {boolean} whether downstream response body should be collected for AppSec.
|
|
106
105
|
*/
|
|
107
106
|
function evaluateResponseBodyCollection (originatingReq, res) {
|
|
108
107
|
const maxBytes = config.appsec.DD_API_SECURITY_MAX_DOWNSTREAM_BODY_BYTES
|
|
@@ -131,7 +130,6 @@ function evaluateResponseBodyCollection (originatingReq, res) {
|
|
|
131
130
|
* Probabilistic gate for downstream response body capture (rate + per-request cap).
|
|
132
131
|
* Only used from {@link planResponseBodyCollection}; does not increment {@link bodyAnalysisCount}.
|
|
133
132
|
* @param {import('http').IncomingMessage} req originating server request.
|
|
134
|
-
* @returns {boolean}
|
|
135
133
|
*/
|
|
136
134
|
function shouldSampleBody (req) {
|
|
137
135
|
globalRequestCounter = (globalRequestCounter + 1n) & UINT64_MAX
|
|
@@ -150,7 +148,6 @@ function shouldSampleBody (req) {
|
|
|
150
148
|
|
|
151
149
|
/**
|
|
152
150
|
* @param {import('http').IncomingMessage} res downstream HTTP response.
|
|
153
|
-
* @returns {boolean}
|
|
154
151
|
*/
|
|
155
152
|
function isRedirectResponse (res) {
|
|
156
153
|
const location = res.headers?.location || ''
|
|
@@ -271,7 +268,6 @@ function incrementDownstreamAnalysisCount (req) {
|
|
|
271
268
|
/**
|
|
272
269
|
* Returns the HTTP method to use for a downstream request, defaulting to GET.
|
|
273
270
|
* @param {string} method method supplied in the outgoing request options.
|
|
274
|
-
* @returns {string} validated HTTP method.
|
|
275
271
|
*/
|
|
276
272
|
function getMethod (method) {
|
|
277
273
|
return typeof method === 'string' && method ? method : 'GET'
|
|
@@ -351,6 +347,7 @@ module.exports = {
|
|
|
351
347
|
disable,
|
|
352
348
|
planResponseBodyCollection,
|
|
353
349
|
incrementDownstreamAnalysisCount,
|
|
350
|
+
extractMimeType,
|
|
354
351
|
extractRequestData,
|
|
355
352
|
extractResponseData,
|
|
356
353
|
}
|
|
@@ -31,7 +31,7 @@ let isEnabled = false
|
|
|
31
31
|
function enable (config, _tracer) {
|
|
32
32
|
if (isEnabled) return
|
|
33
33
|
|
|
34
|
-
iastTelemetry.configure(config, config.iast?.
|
|
34
|
+
iastTelemetry.configure(config, config.iast?.DD_IAST_TELEMETRY_VERBOSITY)
|
|
35
35
|
enableFsPlugin(IAST_MODULE)
|
|
36
36
|
enableAllAnalyzers(config)
|
|
37
37
|
enableTaintTracking(config.iast, iastTelemetry.verbosity)
|
|
@@ -73,7 +73,7 @@ const OPERATIONS = {
|
|
|
73
73
|
},
|
|
74
74
|
name: REPORT_VULNERABILITY,
|
|
75
75
|
initialTokenBucketSize () {
|
|
76
|
-
return typeof config.
|
|
76
|
+
return typeof config.DD_IAST_MAX_CONTEXT_OPERATIONS === 'number' ? config.DD_IAST_MAX_CONTEXT_OPERATIONS : 2
|
|
77
77
|
},
|
|
78
78
|
initContext: function (context) {
|
|
79
79
|
context.tokens[REPORT_VULNERABILITY] = this.initialTokenBucketSize()
|
|
@@ -146,8 +146,8 @@ function _resetGlobalContext () {
|
|
|
146
146
|
|
|
147
147
|
function acquireRequest (rootSpan) {
|
|
148
148
|
if (availableRequest > 0 && rootSpan) {
|
|
149
|
-
const sampling = config && typeof config.
|
|
150
|
-
? config.
|
|
149
|
+
const sampling = config && typeof config.DD_IAST_REQUEST_SAMPLING === 'number'
|
|
150
|
+
? config.DD_IAST_REQUEST_SAMPLING
|
|
151
151
|
: 30
|
|
152
152
|
if (rootSpan.context().toSpanId().slice(-2) <= sampling) {
|
|
153
153
|
availableRequest--
|
|
@@ -158,7 +158,7 @@ function acquireRequest (rootSpan) {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
function releaseRequest () {
|
|
161
|
-
if (availableRequest < config.
|
|
161
|
+
if (availableRequest < config.DD_IAST_MAX_CONCURRENT_REQUESTS) {
|
|
162
162
|
availableRequest++
|
|
163
163
|
}
|
|
164
164
|
}
|
|
@@ -174,7 +174,7 @@ function initializeRequestContext (iastContext) {
|
|
|
174
174
|
|
|
175
175
|
function configure (cfg) {
|
|
176
176
|
config = cfg
|
|
177
|
-
availableRequest = config.
|
|
177
|
+
availableRequest = config.DD_IAST_MAX_CONCURRENT_REQUESTS
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
function startGlobalContext () {
|
|
@@ -20,7 +20,7 @@ module.exports = {
|
|
|
20
20
|
kafkaContextPlugin.enable(config)
|
|
21
21
|
kafkaConsumerPlugin.enable(config)
|
|
22
22
|
|
|
23
|
-
setMaxTransactions(config.
|
|
23
|
+
setMaxTransactions(config.DD_IAST_MAX_CONCURRENT_REQUESTS)
|
|
24
24
|
},
|
|
25
25
|
disableTaintTracking () {
|
|
26
26
|
disableTaintOperations()
|
|
@@ -30,7 +30,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
|
|
|
30
30
|
configure (config) {
|
|
31
31
|
super.configure(config)
|
|
32
32
|
|
|
33
|
-
let rowsToTaint = this.iastConfig?.
|
|
33
|
+
let rowsToTaint = this.iastConfig?.DD_IAST_DB_ROWS_TO_TAINT
|
|
34
34
|
if (typeof rowsToTaint !== 'number') {
|
|
35
35
|
rowsToTaint = 1
|
|
36
36
|
}
|
|
@@ -97,7 +97,7 @@ function getPrepareStackTraceAccessor () {
|
|
|
97
97
|
|
|
98
98
|
function getCompileMethodFn (compileMethod) {
|
|
99
99
|
let delegate = function (content, filename) {
|
|
100
|
-
if (isDdTrace(filename) || !isPrivateModule(filename) || !config.iast?.
|
|
100
|
+
if (isDdTrace(filename) || !isPrivateModule(filename) || !config.iast?.DD_IAST_ENABLED) {
|
|
101
101
|
return compileMethod.apply(this, [content, filename])
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -163,7 +163,7 @@ function shimPrepareStackTrace () {
|
|
|
163
163
|
|
|
164
164
|
function enableRewriter (telemetryVerbosity) {
|
|
165
165
|
try {
|
|
166
|
-
if (config.iast?.
|
|
166
|
+
if (config.iast?.DD_IAST_ENABLED) {
|
|
167
167
|
const rewriter = getRewriter(telemetryVerbosity)
|
|
168
168
|
if (rewriter) {
|
|
169
169
|
shimPrepareStackTrace()
|
|
@@ -218,7 +218,7 @@ let enableEsmRewriter = function (telemetryVerbosity) {
|
|
|
218
218
|
telemetryVerbosity,
|
|
219
219
|
chainSourceMap: isFlagPresent('--enable-source-maps'),
|
|
220
220
|
orchestrionConfig,
|
|
221
|
-
iastEnabled: config?.iast?.
|
|
221
|
+
iastEnabled: config?.iast?.DD_IAST_ENABLED,
|
|
222
222
|
},
|
|
223
223
|
})
|
|
224
224
|
} catch (e) {
|