dd-trace 5.80.0 → 5.81.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.
Files changed (213) hide show
  1. package/LICENSE-3rdparty.csv +79 -88
  2. package/ext/tags.d.ts +1 -0
  3. package/ext/tags.js +1 -0
  4. package/index.d.ts +35 -35
  5. package/loader-hook.mjs +10 -3
  6. package/package.json +22 -40
  7. package/packages/datadog-esbuild/index.js +36 -19
  8. package/packages/datadog-instrumentations/index.js +1 -0
  9. package/packages/datadog-instrumentations/src/anthropic.js +12 -0
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +5 -1
  11. package/packages/datadog-instrumentations/src/cucumber.js +2 -2
  12. package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
  13. package/packages/datadog-instrumentations/src/google-genai.js +120 -0
  14. package/packages/datadog-instrumentations/src/graphql.js +20 -0
  15. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  16. package/packages/datadog-instrumentations/src/helpers/instrument.js +10 -0
  17. package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
  18. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
  19. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
  20. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
  21. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
  25. package/packages/datadog-instrumentations/src/langchain.js +3 -109
  26. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  27. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  28. package/packages/datadog-instrumentations/src/playwright.js +45 -16
  29. package/packages/datadog-instrumentations/src/router.js +1 -1
  30. package/packages/datadog-instrumentations/src/selenium.js +3 -1
  31. package/packages/datadog-instrumentations/src/ws.js +35 -17
  32. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  33. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
  34. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  35. package/packages/datadog-plugin-cypress/src/support.js +73 -31
  36. package/packages/datadog-plugin-google-genai/src/index.js +17 -0
  37. package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
  38. package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
  39. package/packages/datadog-plugin-jest/src/util.js +1 -1
  40. package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
  41. package/packages/datadog-plugin-next/src/index.js +11 -3
  42. package/packages/dd-trace/src/aiguard/sdk.js +18 -10
  43. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  44. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  45. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  46. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
  47. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  48. package/packages/dd-trace/src/appsec/reporter.js +0 -4
  49. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
  50. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  51. package/packages/dd-trace/src/config.js +81 -7
  52. package/packages/dd-trace/src/config_defaults.js +14 -2
  53. package/packages/dd-trace/src/datastreams/encoding.js +23 -6
  54. package/packages/dd-trace/src/datastreams/pathway.js +40 -1
  55. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  56. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  57. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
  58. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  59. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  60. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
  61. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  62. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
  63. package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
  64. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
  65. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
  66. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
  67. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
  68. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
  69. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
  70. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  71. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
  72. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  73. package/packages/dd-trace/src/debugger/index.js +1 -1
  74. package/packages/dd-trace/src/encode/span-stats.js +7 -1
  75. package/packages/dd-trace/src/histogram.js +1 -1
  76. package/packages/dd-trace/src/id.js +60 -0
  77. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  78. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  79. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
  80. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
  81. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
  82. package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +48 -6
  83. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
  84. package/packages/dd-trace/src/llmobs/sdk.js +5 -0
  85. package/packages/dd-trace/src/llmobs/span_processor.js +6 -1
  86. package/packages/dd-trace/src/llmobs/tagger.js +4 -0
  87. package/packages/dd-trace/src/opentelemetry/logs/index.js +2 -2
  88. package/packages/dd-trace/src/opentelemetry/logs/logger.js +3 -2
  89. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +5 -3
  90. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +8 -8
  91. package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
  92. package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
  93. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
  94. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
  95. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
  96. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
  97. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
  98. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
  99. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
  100. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
  101. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
  102. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  103. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  104. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  105. package/packages/dd-trace/src/payload-tagging/index.js +2 -2
  106. package/packages/dd-trace/src/plugin_manager.js +4 -2
  107. package/packages/dd-trace/src/plugins/index.js +1 -0
  108. package/packages/dd-trace/src/plugins/util/test.js +3 -3
  109. package/packages/dd-trace/src/plugins/util/url.js +119 -1
  110. package/packages/dd-trace/src/plugins/util/web.js +10 -41
  111. package/packages/dd-trace/src/process-tags/index.js +81 -0
  112. package/packages/dd-trace/src/profiling/config.js +1 -1
  113. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  114. package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
  115. package/packages/dd-trace/src/proxy.js +5 -0
  116. package/packages/dd-trace/src/rate_limiter.js +1 -1
  117. package/packages/dd-trace/src/remote_config/manager.js +1 -1
  118. package/packages/dd-trace/src/ritm.js +1 -1
  119. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  120. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  121. package/packages/dd-trace/src/span_format.js +9 -4
  122. package/packages/dd-trace/src/span_processor.js +8 -3
  123. package/packages/dd-trace/src/span_stats.js +15 -4
  124. package/packages/dd-trace/src/spanleak.js +1 -1
  125. package/packages/dd-trace/src/supported-configurations.json +13 -0
  126. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  127. package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
  128. package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
  129. package/vendor/dist/@datadog/sketches-js/index.js +1 -0
  130. package/vendor/dist/@datadog/source-map/LICENSE +28 -0
  131. package/vendor/dist/@datadog/source-map/index.js +1 -0
  132. package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
  133. package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
  134. package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
  135. package/vendor/dist/@opentelemetry/core/index.js +1 -0
  136. package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
  137. package/vendor/dist/@opentelemetry/resources/index.js +1 -0
  138. package/vendor/dist/astring/LICENSE +19 -0
  139. package/vendor/dist/astring/index.js +1 -0
  140. package/vendor/dist/crypto-randomuuid/index.js +1 -0
  141. package/vendor/dist/escape-string-regexp/LICENSE +9 -0
  142. package/vendor/dist/escape-string-regexp/index.js +1 -0
  143. package/vendor/dist/esquery/LICENSE +24 -0
  144. package/vendor/dist/esquery/index.js +1 -0
  145. package/vendor/dist/ignore/LICENSE +21 -0
  146. package/vendor/dist/ignore/index.js +1 -0
  147. package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
  148. package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
  149. package/vendor/dist/jest-docblock/LICENSE +21 -0
  150. package/vendor/dist/jest-docblock/index.js +1 -0
  151. package/vendor/dist/jsonpath-plus/LICENSE +22 -0
  152. package/vendor/dist/jsonpath-plus/index.js +1 -0
  153. package/vendor/dist/limiter/LICENSE +19 -0
  154. package/vendor/dist/limiter/index.js +1 -0
  155. package/vendor/dist/lodash.sortby/LICENSE +47 -0
  156. package/vendor/dist/lodash.sortby/index.js +1 -0
  157. package/vendor/dist/lru-cache/LICENSE +15 -0
  158. package/vendor/dist/lru-cache/index.js +1 -0
  159. package/vendor/dist/meriyah/LICENSE +7 -0
  160. package/vendor/dist/meriyah/index.js +1 -0
  161. package/vendor/dist/module-details-from-path/LICENSE +21 -0
  162. package/vendor/dist/module-details-from-path/index.js +1 -0
  163. package/vendor/dist/mutexify/promise/LICENSE +21 -0
  164. package/vendor/dist/mutexify/promise/index.js +1 -0
  165. package/vendor/dist/opentracing/LICENSE +201 -0
  166. package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
  167. package/vendor/dist/opentracing/constants.d.ts +61 -0
  168. package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
  169. package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
  170. package/vendor/dist/opentracing/functions.d.ts +20 -0
  171. package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
  172. package/vendor/dist/opentracing/index.d.ts +12 -0
  173. package/vendor/dist/opentracing/index.js +1 -0
  174. package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
  175. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
  176. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
  177. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
  178. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
  179. package/vendor/dist/opentracing/noop.d.ts +8 -0
  180. package/vendor/dist/opentracing/reference.d.ts +33 -0
  181. package/vendor/dist/opentracing/span.d.ts +147 -0
  182. package/vendor/dist/opentracing/span_context.d.ts +26 -0
  183. package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
  184. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
  185. package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
  186. package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
  187. package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
  188. package/vendor/dist/opentracing/tracer.d.ts +127 -0
  189. package/vendor/dist/path-to-regexp/LICENSE +21 -0
  190. package/vendor/dist/path-to-regexp/index.js +1 -0
  191. package/vendor/dist/pprof-format/LICENSE +8 -0
  192. package/vendor/dist/pprof-format/index.js +1 -0
  193. package/vendor/dist/protobufjs/LICENSE +39 -0
  194. package/vendor/dist/protobufjs/index.js +1 -0
  195. package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
  196. package/vendor/dist/protobufjs/minimal/index.js +1 -0
  197. package/vendor/dist/retry/LICENSE +21 -0
  198. package/vendor/dist/retry/index.js +1 -0
  199. package/vendor/dist/rfdc/LICENSE +15 -0
  200. package/vendor/dist/rfdc/index.js +1 -0
  201. package/vendor/dist/semifies/LICENSE +201 -0
  202. package/vendor/dist/semifies/index.js +1 -0
  203. package/vendor/dist/shell-quote/LICENSE +24 -0
  204. package/vendor/dist/shell-quote/index.js +1 -0
  205. package/vendor/dist/source-map/LICENSE +28 -0
  206. package/vendor/dist/source-map/index.js +1 -0
  207. package/vendor/dist/source-map/lib/util/LICENSE +28 -0
  208. package/vendor/dist/source-map/lib/util/index.js +1 -0
  209. package/vendor/dist/source-map/mappings.wasm +0 -0
  210. package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
  211. package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
  212. package/vendor/dist/ttl-set/LICENSE +21 -0
  213. package/vendor/dist/ttl-set/index.js +1 -0
@@ -9,6 +9,9 @@ let testManagementAttemptToFixRetries = 0
9
9
  let testManagementTests = {}
10
10
  let isImpactedTestsEnabled = false
11
11
  let isModifiedTest = false
12
+ let isTestIsolationEnabled = false
13
+ // Array of test names that have been retried and the reason
14
+ const retryReasonsByTestName = new Map()
12
15
 
13
16
  // We need to grab the original window as soon as possible,
14
17
  // in case the test changes the origin. If the test does change the origin,
@@ -43,17 +46,20 @@ function getTestProperties (testName) {
43
46
  return { isAttemptToFix, isDisabled, isQuarantined }
44
47
  }
45
48
 
46
- function retryTest (test, suiteTests, numRetries, tags) {
49
+ function getRetriedTests (test, numRetries, tags) {
50
+ const retriedTests = []
47
51
  for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
48
- const clonedTest = test.clone()
49
52
  // TODO: signal in framework logs that this is a retry.
50
53
  // TODO: Change it so these tests are allowed to fail.
51
- // TODO: figure out if reported duration is skewed.
52
- suiteTests.unshift(clonedTest)
54
+ const clonedTest = test.clone()
53
55
  tags.forEach(tag => {
54
- clonedTest[tag] = true
56
+ if (tag) {
57
+ clonedTest[tag] = true
58
+ }
55
59
  })
60
+ retriedTests.push(clonedTest)
56
61
  }
62
+ return retriedTests
57
63
  }
58
64
 
59
65
  const oldRunTests = Cypress.mocha.getRunner().runTests
@@ -61,45 +67,80 @@ Cypress.mocha.getRunner().runTests = function (suite, fn) {
61
67
  if (!isKnownTestsEnabled && !isTestManagementEnabled && !isImpactedTestsEnabled) {
62
68
  return oldRunTests.apply(this, arguments)
63
69
  }
64
- // We copy the new tests at the beginning of the suite run (runTests), so that they're run
65
- // multiple times.
66
- suite.tests.forEach(test => {
67
- const testName = test.fullTitle()
70
+ // We copy the tests array and add retries to it, then assign it back to suite.tests
71
+ // to avoid modifying the array while iterating over it
72
+ const testsWithRetries = []
68
73
 
74
+ for (let testIndex = 0; testIndex < suite.tests.length; testIndex++) {
75
+ const test = suite.tests[testIndex]
76
+ const testName = test.fullTitle()
69
77
  const { isAttemptToFix } = getTestProperties(testName)
78
+ const isSkipped = test.isPending()
70
79
 
71
- if (isTestManagementEnabled && isAttemptToFix && !test.isPending()) {
72
- test._ddIsAttemptToFix = true
73
- retryTest(test, suite.tests, testManagementAttemptToFixRetries, ['_ddIsAttemptToFix'])
74
- }
75
- if (isImpactedTestsEnabled && isModifiedTest) {
80
+ const isAtemptToFix = isTestManagementEnabled && isAttemptToFix && !isSkipped
81
+ const isModified = isImpactedTestsEnabled && isModifiedTest
82
+ const isNew = isKnownTestsEnabled && !isSkipped && isNewTest(test)
83
+
84
+ // We want is_modified and is_new regardless of the retry reason
85
+ if (isModified) {
76
86
  test._ddIsModified = true
77
- if (isEarlyFlakeDetectionEnabled && !isAttemptToFix) {
78
- retryTest(
79
- test,
80
- suite.tests,
81
- earlyFlakeDetectionNumRetries,
82
- ['_ddIsModified', '_ddIsEfdRetry', isKnownTestsEnabled && isNewTest(test) && '_ddIsNew']
83
- )
84
- }
85
87
  }
86
- if (isKnownTestsEnabled && !test._ddIsNew && !test.isPending() && isNewTest(test)) {
88
+ if (isNew) {
87
89
  test._ddIsNew = true
88
- if (isImpactedTestsEnabled && isModifiedTest) {
89
- test._ddIsModified = true
90
- }
91
- if (isEarlyFlakeDetectionEnabled && !isAttemptToFix && !isModifiedTest) {
92
- retryTest(test, suite.tests, earlyFlakeDetectionNumRetries, ['_ddIsNew', '_ddIsEfdRetry'])
93
- }
94
90
  }
95
- })
91
+
92
+ // Add the original test first
93
+ testsWithRetries.push(test)
94
+
95
+ if (!isTestIsolationEnabled) {
96
+ continue
97
+ }
98
+
99
+ // Then add retries right after it
100
+ let retriedTests = []
101
+ let retryMessage = ''
102
+ if (isAtemptToFix) {
103
+ test._ddIsAttemptToFix = true
104
+ retryMessage = 'because it is an attempt to fix'
105
+ retriedTests = getRetriedTests(test, testManagementAttemptToFixRetries, ['_ddIsAttemptToFix'])
106
+ } else if (isModified && isEarlyFlakeDetectionEnabled) {
107
+ retryMessage = 'to detect flakes because it is modified'
108
+ retriedTests = getRetriedTests(test, earlyFlakeDetectionNumRetries, [
109
+ '_ddIsModified',
110
+ '_ddIsEfdRetry',
111
+ isKnownTestsEnabled && isNewTest(test) && '_ddIsNew'
112
+ ])
113
+ } else if (isNew && isEarlyFlakeDetectionEnabled) {
114
+ retryMessage = 'to detect flakes because it is new'
115
+ retriedTests = getRetriedTests(test, earlyFlakeDetectionNumRetries, ['_ddIsNew', '_ddIsEfdRetry'])
116
+ }
117
+
118
+ testsWithRetries.push(...retriedTests)
119
+
120
+ if (retryMessage) {
121
+ retryReasonsByTestName.set(testName, retryMessage)
122
+ }
123
+ }
124
+
125
+ suite.tests = testsWithRetries
96
126
 
97
127
  return oldRunTests.apply(this, [suite, fn])
98
128
  }
99
129
 
100
130
  beforeEach(function () {
131
+ const testName = Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle()
132
+
133
+ const retryMessage = retryReasonsByTestName.get(testName)
134
+ if (retryMessage) {
135
+ cy.task(
136
+ 'dd:log',
137
+ `Retrying "${testName}" ${retryMessage}`
138
+ )
139
+ retryReasonsByTestName.delete(testName)
140
+ }
141
+
101
142
  cy.task('dd:beforeEach', {
102
- testName: Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle(),
143
+ testName,
103
144
  testSuite: Cypress.mocha.getRootSuite().file
104
145
  }).then(({ traceId, shouldSkip }) => {
105
146
  Cypress.env('traceId', traceId)
@@ -127,6 +168,7 @@ before(function () {
127
168
  testManagementTests = suiteConfig.testManagementTests
128
169
  isImpactedTestsEnabled = suiteConfig.isImpactedTestsEnabled
129
170
  isModifiedTest = suiteConfig.isModifiedTest
171
+ isTestIsolationEnabled = suiteConfig.isTestIsolationEnabled
130
172
  }
131
173
  })
132
174
  })
@@ -0,0 +1,17 @@
1
+ 'use strict'
2
+
3
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
4
+ const GenAiTracingPlugin = require('./tracing')
5
+ const GenAiLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/genai')
6
+
7
+ class GenAiPlugin extends CompositePlugin {
8
+ static id = 'google-genai'
9
+ static get plugins () {
10
+ return {
11
+ llmobs: GenAiLLMObsPlugin,
12
+ tracing: GenAiTracingPlugin
13
+ }
14
+ }
15
+ }
16
+
17
+ module.exports = GenAiPlugin
@@ -0,0 +1,41 @@
1
+ 'use strict'
2
+
3
+ const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
4
+
5
+ class GenAiTracingPlugin extends TracingPlugin {
6
+ static id = 'google-genai'
7
+ static operation = 'request'
8
+ static prefix = 'tracing:apm:google:genai:request'
9
+
10
+ static get type () { return 'web' }
11
+ static get kind () { return 'client' }
12
+
13
+ bindStart (ctx) {
14
+ const { args, methodName } = ctx
15
+
16
+ const inputs = args[0]
17
+ const model = inputs?.model || 'unknown'
18
+
19
+ this.startSpan('google_genai.request', {
20
+ meta: {
21
+ 'resource.name': methodName,
22
+ 'google_genai.request.model': model,
23
+ 'google_genai.request.provider': 'google'
24
+ }
25
+ }, ctx)
26
+
27
+ return ctx.currentStore
28
+ }
29
+
30
+ asyncEnd (ctx) {
31
+ const { span } = ctx.currentStore
32
+ if (!span) return
33
+
34
+ if (ctx.result) {
35
+ span.setTag('google_genai.response.model', ctx.result.modelVersion || ctx.inputs?.model)
36
+ }
37
+ span.finish()
38
+ }
39
+ }
40
+
41
+ module.exports = GenAiTracingPlugin
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
6
  };
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- const visitor_1 = require("graphql/language/visitor");
9
- const printer_1 = require("graphql/language/printer");
10
- const utilities_1 = require("graphql/utilities");
11
- const lodash_sortby_1 = __importDefault(require("lodash.sortby"));
8
+ const ddGlobal = globalThis[Symbol.for('dd-trace')];
9
+ const visitor_1 = ddGlobal.graphql_visitor;
10
+ const printer_1 = ddGlobal.graphql_printer;
11
+ const utilities_1 = ddGlobal.graphql_utilities;
12
+ const lodash_sortby_1 = __importDefault(require("../../../../vendor/dist/lodash.sortby"));
12
13
  function hideLiterals(ast) {
13
14
  return visitor_1.visit(ast, {
14
15
  IntValue(node) {
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { readFileSync } = require('fs')
4
- const { parse } = require('jest-docblock')
4
+ const { parse } = require('../../../vendor/dist/jest-docblock')
5
5
 
6
6
  const { getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
7
7
  const log = require('../../dd-trace/src/log')
@@ -12,6 +12,8 @@ const LangChainHandler = require('./handlers/default')
12
12
  const LangChainLanguageModelHandler = require('./handlers/language_models')
13
13
  const LangChainEmbeddingHandler = require('./handlers/embedding')
14
14
 
15
+ const defaultNs = ['langchain', 'embeddings']
16
+
15
17
  class BaseLangChainTracingPlugin extends TracingPlugin {
16
18
  static id = 'langchain'
17
19
  static operation = 'invoke'
@@ -36,7 +38,9 @@ class BaseLangChainTracingPlugin extends TracingPlugin {
36
38
  const type = ctx.type = this.constructor.lcType
37
39
 
38
40
  // Runnable interfaces have an `lc_namespace` property
39
- const ns = ctx.self.lc_namespace || ctx.namespace
41
+ const ns = ctx.self.lc_namespace || (
42
+ ctx.self.constructor.name === 'OpenAIEmbeddings' ? [...defaultNs, 'openai'] : defaultNs
43
+ )
40
44
 
41
45
  const resourceParts = [...ns, ctx.self.constructor.name]
42
46
  if (type === 'tool') {
@@ -111,13 +115,13 @@ class BaseLLMGeneratePlugin extends BaseLangChainTracingPlugin {
111
115
  class EmbeddingsEmbedQueryPlugin extends BaseLangChainTracingPlugin {
112
116
  static id = 'langchain_embeddings_embed_query'
113
117
  static lcType = 'embedding'
114
- static prefix = 'tracing:apm:@langchain/core:Embeddings_embedQuery'
118
+ static prefix = 'tracing:orchestrion:@langchain/core:Embeddings_embedQuery'
115
119
  }
116
120
 
117
121
  class EmbeddingsEmbedDocumentsPlugin extends BaseLangChainTracingPlugin {
118
122
  static id = 'langchain_embeddings_embed_documents'
119
123
  static lcType = 'embedding'
120
- static prefix = 'tracing:apm:@langchain/core:Embeddings_embedDocuments'
124
+ static prefix = 'tracing:orchestrion:@langchain/core:Embeddings_embedDocuments'
121
125
  }
122
126
 
123
127
  class ToolInvokePlugin extends BaseLangChainTracingPlugin {
@@ -10,10 +10,10 @@ const errorPages = new Set(['/404', '/500', '/_error', '/_not-found', '/_not-fou
10
10
 
11
11
  class NextPlugin extends ServerPlugin {
12
12
  static id = 'next'
13
+ #requestsBySpanId = new WeakMap()
13
14
 
14
15
  constructor (...args) {
15
16
  super(...args)
16
- this._requests = new WeakMap()
17
17
  this.addSub('apm:next:page:load', message => this.pageLoad(message))
18
18
  }
19
19
 
@@ -35,7 +35,9 @@ class NextPlugin extends ServerPlugin {
35
35
 
36
36
  analyticsSampler.sample(span, this.config.measured, true)
37
37
 
38
- this._requests.set(span, req)
38
+ // Store request by span ID to handle cases where child spans are activated
39
+ const spanId = span.context()._spanId
40
+ this.#requestsBySpanId.set(spanId, req)
39
41
 
40
42
  return { ...store, span }
41
43
  }
@@ -89,7 +91,13 @@ class NextPlugin extends ServerPlugin {
89
91
  if (!store) return
90
92
 
91
93
  const span = store.span
92
- const req = this._requests.get(span)
94
+
95
+ const spanId = span.context()._spanId
96
+ const parentSpanId = span.context()._parentId
97
+
98
+ // Try current span first, then parent span.
99
+ // This handles cases where pageLoad runs in a child span context
100
+ const req = this.#requestsBySpanId.get(spanId) ?? this.#requestsBySpanId.get(parentSpanId)
93
101
 
94
102
  // safeguard against missing req in complicated timeout scenarios
95
103
  if (!req) return
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const rfdc = require('../../../../vendor/dist/rfdc')({ proto: false, circles: false })
3
4
  const NoopAIGuard = require('./noop')
4
5
  const executeRequest = require('./client')
5
6
  const {
@@ -22,10 +23,11 @@ const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
22
23
  const ALLOW = 'ALLOW'
23
24
 
24
25
  class AIGuardAbortError extends Error {
25
- constructor (reason) {
26
+ constructor (reason, tags) {
26
27
  super(reason)
27
28
  this.name = 'AIGuardAbortError'
28
29
  this.reason = reason
30
+ this.tags = tags
29
31
  }
30
32
  }
31
33
 
@@ -77,20 +79,26 @@ class AIGuard extends NoopAIGuard {
77
79
  this.#initialized = true
78
80
  }
79
81
 
80
- #truncate (messages) {
82
+ /**
83
+ * Returns a safe copy of the messages to be serialized into the meta struct.
84
+ *
85
+ * - Clones each message so callers cannot mutate the data set in the meta struct.
86
+ * - Truncates the list of messages and `content` fields emitting metrics accordingly.
87
+ */
88
+ #buildMessagesForMetaStruct (messages) {
81
89
  const size = Math.min(messages.length, this.#maxMessagesLength)
82
90
  if (messages.length > size) {
83
91
  appsecMetrics.count(AI_GUARD_TELEMETRY_TRUNCATED, { type: 'messages' }).inc(1)
84
92
  }
85
- const result = messages.slice(-size)
86
-
93
+ const result = []
87
94
  let contentTruncated = false
88
- for (let i = 0; i < size; i++) {
89
- const message = result[i]
95
+ for (let i = messages.length - size; i < messages.length; i++) {
96
+ const message = rfdc(messages[i])
90
97
  if (message.content?.length > this.#maxContentSize) {
91
98
  contentTruncated = true
92
- result[i] = { ...message, content: message.content.slice(0, this.#maxContentSize) }
99
+ message.content = message.content.slice(0, this.#maxContentSize)
93
100
  }
101
+ result.push(message)
94
102
  }
95
103
  if (contentTruncated) {
96
104
  appsecMetrics.count(AI_GUARD_TELEMETRY_TRUNCATED, { type: 'content' }).inc(1)
@@ -139,7 +147,7 @@ class AIGuard extends NoopAIGuard {
139
147
  }
140
148
  }
141
149
  const metaStruct = {
142
- messages: this.#truncate(messages)
150
+ messages: this.#buildMessagesForMetaStruct(messages)
143
151
  }
144
152
  span.meta_struct = {
145
153
  [AI_GUARD_META_STRUCT_KEY]: metaStruct
@@ -192,9 +200,9 @@ class AIGuard extends NoopAIGuard {
192
200
  }
193
201
  if (shouldBlock) {
194
202
  span.setTag(AI_GUARD_BLOCKED_TAG_KEY, 'true')
195
- throw new AIGuardAbortError(reason)
203
+ throw new AIGuardAbortError(reason, tags)
196
204
  }
197
- return { action, reason }
205
+ return { action, reason, tags }
198
206
  })
199
207
  }
200
208
  }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { TTLCache } = require('@isaacs/ttlcache')
3
+ const { TTLCache } = require('../../../../vendor/dist/@isaacs/ttlcache')
4
4
  const web = require('../plugins/util/web')
5
5
  const log = require('../log')
6
6
  const { AUTO_REJECT, USER_REJECT } = require('../../../../ext/priority')
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { LRUCache } = require('lru-cache')
3
+ const { LRUCache } = require('../../../../../vendor/dist/lru-cache')
4
4
  const web = require('../../plugins/util/web')
5
5
  const vulnerabilities = require('./vulnerabilities')
6
6
 
@@ -47,7 +47,7 @@ export async function load (url, context, nextLoad) {
47
47
  passes.push('iast')
48
48
  }
49
49
  } else {
50
- passes = ['orchestrion']
50
+ passes = [] // TODO: Re-enable Orchestrion when viable.
51
51
  }
52
52
  const rewritten = rewriter.rewrite(result.source.toString(), url, passes)
53
53
 
@@ -175,9 +175,8 @@ function enableRewriter (telemetryVerbosity) {
175
175
  shimmer.wrap(Module.prototype, '_compile', compileMethod => getCompileMethodFn(compileMethod))
176
176
  }
177
177
  }
178
+ enableEsmRewriter(telemetryVerbosity)
178
179
  }
179
-
180
- enableEsmRewriter(telemetryVerbosity)
181
180
  } catch (e) {
182
181
  log.error('Error enabling Rewriter', e)
183
182
  }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { LRUCache } = require('lru-cache')
3
+ const { LRUCache } = require('../../../../../vendor/dist/lru-cache')
4
4
  const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
5
5
  const { IAST_ENABLED_TAG_KEY, IAST_JSON_TAG_KEY } = require('./tags')
6
6
  const { keepTrace } = require('../../priority_sampler')
@@ -546,10 +546,6 @@ function finishRequest (req, res, storedResponseHeaders, requestBody) {
546
546
  reportRequestBody(rootSpan, requestBody)
547
547
  }
548
548
 
549
- if (tags['appsec.event'] === 'true' && typeof req.route?.path === 'string') {
550
- newTags['http.endpoint'] = req.route.path
551
- }
552
-
553
549
  rootSpan.addTags(newTags)
554
550
  }
555
551
 
@@ -36,7 +36,7 @@ session.on('Debugger.paused', async ({ params: { hitBreakpoints: [hitBreakpoint]
36
36
 
37
37
  const stack = getStackFromCallFrames(callFrames)
38
38
 
39
- const getLocalState = await getLocalStateForCallFrame(callFrames[0])
39
+ const { processLocalState } = await getLocalStateForCallFrame(callFrames[0])
40
40
 
41
41
  await session.post('Debugger.resume')
42
42
 
@@ -48,17 +48,13 @@ session.on('Debugger.paused', async ({ params: { hitBreakpoints: [hitBreakpoint]
48
48
  version: '0',
49
49
  location: probe.location
50
50
  },
51
+ captures: {
52
+ lines: { [probe.location.lines[0]]: { locals: processLocalState() } }
53
+ },
51
54
  stack,
52
55
  language: 'javascript'
53
56
  }
54
57
 
55
- const state = getLocalState()
56
- if (state) {
57
- snapshot.captures = {
58
- lines: { [probe.location.lines[0]]: { locals: state } }
59
- }
60
- }
61
-
62
58
  breakpointHitChannel.postMessage({ snapshot })
63
59
  })
64
60
 
@@ -14,7 +14,8 @@ function getTestManagementTests ({
14
14
  commitMessage,
15
15
  sha,
16
16
  commitHeadSha,
17
- commitHeadMessage
17
+ commitHeadMessage,
18
+ branch
18
19
  }, done) {
19
20
  const options = {
20
21
  path: '/api/v2/test/libraries/test-management/tests',
@@ -49,7 +50,8 @@ function getTestManagementTests ({
49
50
  attributes: {
50
51
  repository_url: repositoryUrl,
51
52
  commit_message: commitHeadMessage || commitMessage,
52
- sha: commitHeadSha || sha
53
+ sha: commitHeadSha || sha,
54
+ branch
53
55
  }
54
56
  }
55
57
  })