dd-trace 5.70.0 → 5.72.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 (72) hide show
  1. package/LICENSE-3rdparty.csv +5 -0
  2. package/index.d.ts +110 -1
  3. package/initialize.mjs +7 -1
  4. package/package.json +21 -2
  5. package/packages/datadog-instrumentations/src/anthropic.js +115 -0
  6. package/packages/datadog-instrumentations/src/azure-event-hubs.js +37 -0
  7. package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
  8. package/packages/datadog-instrumentations/src/cucumber.js +7 -7
  9. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  10. package/packages/datadog-instrumentations/src/jest.js +29 -36
  11. package/packages/datadog-instrumentations/src/mocha/main.js +8 -9
  12. package/packages/datadog-instrumentations/src/mocha/utils.js +1 -1
  13. package/packages/datadog-instrumentations/src/mocha/worker.js +2 -2
  14. package/packages/datadog-instrumentations/src/pg.js +1 -1
  15. package/packages/datadog-instrumentations/src/playwright.js +5 -5
  16. package/packages/datadog-instrumentations/src/vitest.js +8 -8
  17. package/packages/datadog-plugin-anthropic/src/index.js +17 -0
  18. package/packages/datadog-plugin-anthropic/src/tracing.js +30 -0
  19. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +73 -27
  20. package/packages/datadog-plugin-azure-event-hubs/src/index.js +15 -0
  21. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +82 -0
  22. package/packages/datadog-plugin-azure-functions/src/index.js +37 -0
  23. package/packages/datadog-plugin-cucumber/src/index.js +3 -3
  24. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -9
  25. package/packages/datadog-plugin-jest/src/util.js +10 -2
  26. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  27. package/packages/datadog-plugin-playwright/src/index.js +2 -2
  28. package/packages/datadog-plugin-vitest/src/index.js +2 -2
  29. package/packages/datadog-plugin-ws/src/server.js +5 -3
  30. package/packages/dd-trace/src/appsec/reporter.js +70 -21
  31. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
  32. package/packages/dd-trace/src/config.js +110 -26
  33. package/packages/dd-trace/src/config_defaults.js +14 -0
  34. package/packages/dd-trace/src/git_properties.js +90 -5
  35. package/packages/dd-trace/src/llmobs/plugins/anthropic.js +282 -0
  36. package/packages/dd-trace/src/llmobs/tagger.js +35 -0
  37. package/packages/dd-trace/src/noop/proxy.js +3 -0
  38. package/packages/dd-trace/src/openfeature/constants/constants.js +51 -0
  39. package/packages/dd-trace/src/openfeature/flagging_provider.js +45 -0
  40. package/packages/dd-trace/src/openfeature/index.js +77 -0
  41. package/packages/dd-trace/src/openfeature/noop.js +101 -0
  42. package/packages/dd-trace/src/openfeature/writers/base.js +181 -0
  43. package/packages/dd-trace/src/openfeature/writers/exposures.js +173 -0
  44. package/packages/dd-trace/src/openfeature/writers/util.js +43 -0
  45. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +100 -0
  46. package/packages/dd-trace/src/opentelemetry/logs/index.js +87 -0
  47. package/packages/dd-trace/src/opentelemetry/logs/logger.js +77 -0
  48. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +126 -0
  49. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +173 -0
  50. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +367 -0
  51. package/packages/dd-trace/src/opentelemetry/protos/common.proto +116 -0
  52. package/packages/dd-trace/src/opentelemetry/protos/logs.proto +226 -0
  53. package/packages/dd-trace/src/opentelemetry/protos/logs_service.proto +78 -0
  54. package/packages/dd-trace/src/opentelemetry/protos/protobuf_loader.js +48 -0
  55. package/packages/dd-trace/src/opentelemetry/protos/resource.proto +45 -0
  56. package/packages/dd-trace/src/plugins/ci_plugin.js +7 -6
  57. package/packages/dd-trace/src/plugins/index.js +2 -0
  58. package/packages/dd-trace/src/plugins/util/test.js +6 -5
  59. package/packages/dd-trace/src/profiling/config.js +21 -1
  60. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -2
  61. package/packages/dd-trace/src/profiling/profiler.js +44 -22
  62. package/packages/dd-trace/src/profiling/profilers/events.js +12 -3
  63. package/packages/dd-trace/src/profiling/profilers/space.js +35 -24
  64. package/packages/dd-trace/src/profiling/profilers/wall.js +14 -6
  65. package/packages/dd-trace/src/proxy.js +22 -1
  66. package/packages/dd-trace/src/remote_config/capabilities.js +2 -0
  67. package/packages/dd-trace/src/remote_config/index.js +3 -0
  68. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
  69. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  70. package/packages/dd-trace/src/supported-configurations.json +18 -0
  71. package/packages/dd-trace/src/telemetry/telemetry.js +13 -1
  72. package/register.js +9 -1
@@ -46,7 +46,7 @@ const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
46
46
  const libraryConfigurationCh = channel('ci:jest:library-configuration')
47
47
  const knownTestsCh = channel('ci:jest:known-tests')
48
48
  const testManagementTestsCh = channel('ci:jest:test-management-tests')
49
- const impactedTestsCh = channel('ci:jest:modified-tests')
49
+ const modifiedFilesCh = channel('ci:jest:modified-files')
50
50
 
51
51
  const itrSkippedSuitesCh = channel('ci:jest:itr:skipped-suites')
52
52
 
@@ -78,7 +78,7 @@ let isTestManagementTestsEnabled = false
78
78
  let testManagementTests = {}
79
79
  let testManagementAttemptToFixRetries = 0
80
80
  let isImpactedTestsEnabled = false
81
- let modifiedTests = {}
81
+ let modifiedFiles = {}
82
82
 
83
83
  const testContexts = new WeakMap()
84
84
  const originalTestFns = new WeakMap()
@@ -89,6 +89,7 @@ const attemptToFixRetriedTestsStatuses = new Map()
89
89
  const wrappedWorkers = new WeakSet()
90
90
  const testSuiteMockedFiles = new Map()
91
91
  const testsToBeRetried = new Set()
92
+ const testSuiteAbsolutePathsWithFastCheck = new Set()
92
93
 
93
94
  const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
94
95
 
@@ -197,10 +198,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
197
198
 
198
199
  if (this.isImpactedTestsEnabled) {
199
200
  try {
200
- const hasImpactedTests = Object.keys(modifiedTests).length > 0
201
- this.modifiedTestsForThisSuite = hasImpactedTests
202
- ? this.getModifiedTestForThisSuite(modifiedTests)
203
- : this.getModifiedTestForThisSuite(this.testEnvironmentOptions._ddModifiedTests)
201
+ const hasImpactedTests = Object.keys(modifiedFiles).length > 0
202
+ this.modifiedFiles = hasImpactedTests ? modifiedFiles : this.testEnvironmentOptions._ddModifiedFiles
204
203
  } catch (e) {
205
204
  log.error('Error parsing impacted tests', e)
206
205
  this.isImpactedTestsEnabled = false
@@ -290,19 +289,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
290
289
  return result
291
290
  }
292
291
 
293
- getModifiedTestForThisSuite (modifiedTests) {
294
- if (this.modifiedTestsForThisSuite) {
295
- return this.modifiedTestsForThisSuite
296
- }
297
- let modifiedTestsForThisSuite = modifiedTests
298
- // If jest is using workers, modified tests are serialized to json.
299
- // If jest runs in band, they are not.
300
- if (typeof modifiedTestsForThisSuite === 'string') {
301
- modifiedTestsForThisSuite = JSON.parse(modifiedTestsForThisSuite)
302
- }
303
- return modifiedTestsForThisSuite
304
- }
305
-
306
292
  // Generic function to handle test retries
307
293
  retryTest ({
308
294
  jestEvent,
@@ -319,9 +305,13 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
319
305
  }
320
306
  }
321
307
 
308
+ getShouldStripSeedFromTestName () {
309
+ return testSuiteAbsolutePathsWithFastCheck.has(this.testSuiteAbsolutePath)
310
+ }
311
+
322
312
  // At the `add_test` event we don't have the test object yet, so we can't use it
323
313
  getTestNameFromAddTestEvent (event, state) {
324
- const describeSuffix = getJestTestName(state.currentDescribeBlock)
314
+ const describeSuffix = getJestTestName(state.currentDescribeBlock, this.getShouldStripSeedFromTestName())
325
315
  return describeSuffix ? `${describeSuffix} ${event.testName}` : event.testName
326
316
  }
327
317
 
@@ -344,7 +334,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
344
334
  })
345
335
  }
346
336
  if (event.name === 'test_start') {
347
- const testName = getJestTestName(event.test)
337
+ const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
348
338
  if (testsToBeRetried.has(testName)) {
349
339
  // This is needed because we're trying tests with the same name
350
340
  this.resetSnapshotState()
@@ -378,7 +368,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
378
368
  this.testSourceFile,
379
369
  testStartLine,
380
370
  testEndLine,
381
- this.modifiedTestsForThisSuite,
371
+ this.modifiedFiles,
382
372
  'jest'
383
373
  )
384
374
  }
@@ -465,7 +455,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
465
455
  this.testSourceFile,
466
456
  testStartLine,
467
457
  testEndLine,
468
- this.modifiedTestsForThisSuite,
458
+ this.modifiedFiles,
469
459
  'jest'
470
460
  )
471
461
  if (isModified && !retriedTestsToNumAttempts.has(testFullName) && this.isEarlyFlakeDetectionEnabled) {
@@ -506,7 +496,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
506
496
  let failedAllTests = false
507
497
  let isAttemptToFix = false
508
498
  if (this.isTestManagementTestsEnabled) {
509
- const testName = getJestTestName(event.test)
499
+ const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
510
500
  isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(testName)
511
501
  if (isAttemptToFix) {
512
502
  if (attemptToFixRetriedTestsStatuses.has(testName)) {
@@ -534,7 +524,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
534
524
  let isEfdRetry = false
535
525
  // We'll store the test statuses of the retries
536
526
  if (this.isKnownTestsEnabled) {
537
- const testName = getJestTestName(event.test)
527
+ const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
538
528
  const isNewTest = retriedTestsToNumAttempts.has(testName)
539
529
  if (isNewTest) {
540
530
  if (newTestsTestStatuses.has(testName)) {
@@ -594,16 +584,17 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
594
584
  }
595
585
  }
596
586
  if (event.name === 'test_skip' || event.name === 'test_todo') {
587
+ const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
597
588
  testSkippedCh.publish({
598
589
  test: {
599
- name: getJestTestName(event.test),
590
+ name: testName,
600
591
  suite: this.testSuite,
601
592
  testSourceFile: this.testSourceFile,
602
593
  displayName: this.displayName,
603
594
  frameworkVersion: jestVersion,
604
595
  testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
605
596
  },
606
- isDisabled: this.testManagementTestsForThisSuite?.disabled?.includes(getJestTestName(event.test))
597
+ isDisabled: this.testManagementTestsForThisSuite?.disabled?.includes(testName)
607
598
  })
608
599
  }
609
600
  }
@@ -831,12 +822,12 @@ function getCliWrapper (isNewJestVersion) {
831
822
  onDone = resolve
832
823
  })
833
824
 
834
- impactedTestsCh.publish({ onDone })
825
+ modifiedFilesCh.publish({ onDone })
835
826
 
836
827
  try {
837
- const { err, modifiedTests: receivedModifiedTests } = await impactedTestsPromise
828
+ const { err, modifiedFiles: receivedModifiedFiles } = await impactedTestsPromise
838
829
  if (!err) {
839
- modifiedTests = receivedModifiedTests
830
+ modifiedFiles = receivedModifiedFiles
840
831
  }
841
832
  } catch (err) {
842
833
  log.error('Jest impacted tests error', err)
@@ -1237,7 +1228,7 @@ addHook({
1237
1228
  _ddIsTestManagementTestsEnabled,
1238
1229
  _ddTestManagementTests,
1239
1230
  _ddTestManagementAttemptToFixRetries,
1240
- _ddModifiedTests,
1231
+ _ddModifiedFiles,
1241
1232
  ...restOfTestEnvironmentOptions
1242
1233
  } = testEnvironmentOptions
1243
1234
 
@@ -1315,6 +1306,10 @@ addHook({
1315
1306
  // To bypass jest's own require engine
1316
1307
  return this._requireCoreModule(moduleName)
1317
1308
  }
1309
+ // This means that `@fast-check/jest` is used in the test file.
1310
+ if (moduleName === '@fast-check/jest') {
1311
+ testSuiteAbsolutePathsWithFastCheck.add(this._testPath)
1312
+ }
1318
1313
  return requireModuleOrMock.apply(this, arguments)
1319
1314
  })
1320
1315
 
@@ -1365,17 +1360,15 @@ function sendWrapper (send) {
1365
1360
 
1366
1361
  const suiteTestManagementTests = testManagementTests?.jest?.suites?.[testSuite]?.tests || {}
1367
1362
 
1368
- const suiteModifiedTests = Object.keys(modifiedTests).length > 0
1369
- ? modifiedTests
1370
- : {}
1371
-
1372
1363
  args[0].config = {
1373
1364
  ...config,
1374
1365
  testEnvironmentOptions: {
1375
1366
  ...config.testEnvironmentOptions,
1376
1367
  _ddKnownTests: suiteKnownTests,
1377
1368
  _ddTestManagementTests: suiteTestManagementTests,
1378
- _ddModifiedTests: suiteModifiedTests
1369
+ // TODO: figure out if we can reduce the size of the modified files object
1370
+ // Can we use `testSuite` (it'd have to be relative to repository root though)
1371
+ _ddModifiedFiles: modifiedFiles
1379
1372
  }
1380
1373
  }
1381
1374
  }
@@ -68,7 +68,7 @@ const skippableSuitesCh = channel('ci:mocha:test-suite:skippable')
68
68
  const mochaGlobalRunCh = channel('ci:mocha:global:run')
69
69
 
70
70
  const testManagementTestsCh = channel('ci:mocha:test-management-tests')
71
- const impactedTestsCh = channel('ci:mocha:modified-tests')
71
+ const modifiedFilesCh = channel('ci:mocha:modified-files')
72
72
  const workerReportTraceCh = channel('ci:mocha:worker-report:trace')
73
73
  const testSessionStartCh = channel('ci:mocha:session:start')
74
74
  const testSessionFinishCh = channel('ci:mocha:session:finish')
@@ -233,12 +233,12 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
233
233
  })
234
234
  }
235
235
 
236
- const onReceivedImpactedTests = ({ err, modifiedTests: receivedModifiedTests }) => {
236
+ const onReceivedImpactedTests = ({ err, modifiedFiles: receivedModifiedFiles }) => {
237
237
  if (err) {
238
- config.modifiedTests = []
238
+ config.modifiedFiles = []
239
239
  config.isImpactedTestsEnabled = false
240
240
  } else {
241
- config.modifiedTests = receivedModifiedTests
241
+ config.modifiedFiles = receivedModifiedFiles
242
242
  }
243
243
  if (config.isSuitesSkippingEnabled) {
244
244
  ctx.onDone = onReceivedSkippableSuites
@@ -260,7 +260,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
260
260
  }
261
261
  if (config.isImpactedTestsEnabled) {
262
262
  ctx.onDone = onReceivedImpactedTests
263
- impactedTestsCh.runStores(ctx, () => {})
263
+ modifiedFilesCh.runStores(ctx, () => {})
264
264
  } else if (config.isSuitesSkippingEnabled) {
265
265
  ctx.onDone = onReceivedSkippableSuites
266
266
  skippableSuitesCh.runStores(ctx, () => {})
@@ -284,7 +284,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
284
284
  testManagementTestsCh.runStores(ctx, () => {})
285
285
  } if (config.isImpactedTestsEnabled) {
286
286
  ctx.onDone = onReceivedImpactedTests
287
- impactedTestsCh.runStores(ctx, () => {})
287
+ modifiedFilesCh.runStores(ctx, () => {})
288
288
  } else if (config.isSuitesSkippingEnabled) {
289
289
  ctx.onDone = onReceivedSkippableSuites
290
290
  skippableSuitesCh.runStores(ctx, () => {})
@@ -321,7 +321,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
321
321
  testManagementTestsCh.runStores(ctx, () => {})
322
322
  } else if (config.isImpactedTestsEnabled) {
323
323
  ctx.onDone = onReceivedImpactedTests
324
- impactedTestsCh.runStores(ctx, () => {})
324
+ modifiedFilesCh.runStores(ctx, () => {})
325
325
  } else if (config.isSuitesSkippingEnabled) {
326
326
  ctx.onDone = onReceivedSkippableSuites
327
327
  skippableSuitesCh.runStores(ctx, () => {})
@@ -696,9 +696,8 @@ addHook({
696
696
  }
697
697
 
698
698
  if (config.isImpactedTestsEnabled) {
699
- const testSuiteImpactedTests = config.modifiedTests || {}
700
699
  newWorkerArgs._ddIsImpactedTestsEnabled = true
701
- newWorkerArgs._ddModifiedTests = testSuiteImpactedTests
700
+ newWorkerArgs._ddModifiedFiles = config.modifiedFiles || {}
702
701
  }
703
702
 
704
703
  // We pass the known tests for the test file to the worker
@@ -446,7 +446,7 @@ function getRunTestsWrapper (runTests, config) {
446
446
  if (config.isImpactedTestsEnabled) {
447
447
  suite.tests.forEach((test) => {
448
448
  isModifiedCh.publish({
449
- modifiedTests: config.modifiedTests,
449
+ modifiedFiles: config.modifiedFiles,
450
450
  file: suite.file,
451
451
  onDone: (isModified) => {
452
452
  if (isModified) {
@@ -36,9 +36,9 @@ addHook({
36
36
  }
37
37
  if (this.options._ddIsImpactedTestsEnabled) {
38
38
  config.isImpactedTestsEnabled = true
39
- config.modifiedTests = this.options._ddModifiedTests
39
+ config.modifiedFiles = this.options._ddModifiedFiles
40
40
  delete this.options._ddIsImpactedTestsEnabled
41
- delete this.options._ddModifiedTests
41
+ delete this.options._ddModifiedFiles
42
42
  }
43
43
  if (this.options._ddIsTestManagementTestsEnabled) {
44
44
  config.isTestManagementTestsEnabled = true
@@ -20,7 +20,7 @@ addHook({ name: 'pg', versions: ['>=8.0.3'], file: 'lib/native/client.js' }, Cli
20
20
  return Client
21
21
  })
22
22
 
23
- addHook({ name: 'pg', versions: ['>=8.0.3 <8.15.0', '>=8.15.0 <9'], file: 'lib/client.js' }, Client => {
23
+ addHook({ name: 'pg', versions: ['>=8.0.3'], file: 'lib/client.js' }, Client => {
24
24
  shimmer.wrap(Client.prototype, 'query', query => wrapQuery(query))
25
25
  return Client
26
26
  })
@@ -21,7 +21,7 @@ const testSessionFinishCh = channel('ci:playwright:session:finish')
21
21
  const libraryConfigurationCh = channel('ci:playwright:library-configuration')
22
22
  const knownTestsCh = channel('ci:playwright:known-tests')
23
23
  const testManagementTestsCh = channel('ci:playwright:test-management-tests')
24
- const impactedTestsCh = channel('ci:playwright:modified-tests')
24
+ const modifiedFilesCh = channel('ci:playwright:modified-files')
25
25
  const isModifiedCh = channel('ci:playwright:test:is-modified')
26
26
 
27
27
  const testSuiteStartCh = channel('ci:playwright:test-suite:start')
@@ -59,7 +59,7 @@ let isTestManagementTestsEnabled = false
59
59
  let testManagementAttemptToFixRetries = 0
60
60
  let testManagementTests = {}
61
61
  let isImpactedTestsEnabled = false
62
- let modifiedTests = {}
62
+ let modifiedFiles = {}
63
63
  const quarantinedOrDisabledTestsAttemptToFix = []
64
64
  let quarantinedButNotAttemptToFixFqns = new Set()
65
65
  let rootDir = ''
@@ -593,11 +593,11 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
593
593
 
594
594
  if (isImpactedTestsEnabled && satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)) {
595
595
  try {
596
- const { err, modifiedTests: receivedModifiedTests } = await getChannelPromise(impactedTestsCh)
596
+ const { err, modifiedFiles: receivedModifiedFiles } = await getChannelPromise(modifiedFilesCh)
597
597
  if (err) {
598
598
  isImpactedTestsEnabled = false
599
599
  } else {
600
- modifiedTests = receivedModifiedTests
600
+ modifiedFiles = receivedModifiedFiles
601
601
  }
602
602
  } catch (err) {
603
603
  isImpactedTestsEnabled = false
@@ -819,7 +819,7 @@ addHook({
819
819
  await Promise.all(allTests.map(async (test) => {
820
820
  const { isModified } = await getChannelPromise(isModifiedCh, {
821
821
  filePath: test._requireFile,
822
- modifiedTests
822
+ modifiedFiles
823
823
  })
824
824
  if (isModified) {
825
825
  test._ddIsModified = true
@@ -32,7 +32,7 @@ const libraryConfigurationCh = channel('ci:vitest:library-configuration')
32
32
  const knownTestsCh = channel('ci:vitest:known-tests')
33
33
  const isEarlyFlakeDetectionFaultyCh = channel('ci:vitest:is-early-flake-detection-faulty')
34
34
  const testManagementTestsCh = channel('ci:vitest:test-management-tests')
35
- const impactedTestsCh = channel('ci:vitest:modified-tests')
35
+ const modifiedFilesCh = channel('ci:vitest:modified-files')
36
36
 
37
37
  const workerReportTraceCh = channel('ci:vitest:worker-report:trace')
38
38
  const workerReportLogsCh = channel('ci:vitest:worker-report:logs')
@@ -92,7 +92,7 @@ function getProvidedContext () {
92
92
  _ddTestManagementTests: testManagementTests,
93
93
  _ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled,
94
94
  _ddIsImpactedTestsEnabled: isImpactedTestsEnabled,
95
- _ddModifiedTests: modifiedTests
95
+ _ddModifiedFiles: modifiedFiles
96
96
  } = globalThis.__vitest_worker__.providedContext
97
97
 
98
98
  return {
@@ -106,7 +106,7 @@ function getProvidedContext () {
106
106
  testManagementTests,
107
107
  isFlakyTestRetriesEnabled,
108
108
  isImpactedTestsEnabled,
109
- modifiedTests
109
+ modifiedFiles
110
110
  }
111
111
  } catch {
112
112
  log.error('Vitest workers could not parse provided context, so some features will not work.')
@@ -121,7 +121,7 @@ function getProvidedContext () {
121
121
  testManagementTests: {},
122
122
  isFlakyTestRetriesEnabled: false,
123
123
  isImpactedTestsEnabled: false,
124
- modifiedTests: {}
124
+ modifiedFiles: {}
125
125
  }
126
126
  }
127
127
  }
@@ -316,14 +316,14 @@ function getSortWrapper (sort, frameworkVersion) {
316
316
  }
317
317
 
318
318
  if (isImpactedTestsEnabled) {
319
- const { err, modifiedTests } = await getChannelPromise(impactedTestsCh)
319
+ const { err, modifiedFiles } = await getChannelPromise(modifiedFilesCh)
320
320
  if (err) {
321
321
  log.error('Could not get modified tests.')
322
322
  } else {
323
323
  try {
324
324
  const workspaceProject = this.ctx.getCoreWorkspaceProject()
325
325
  workspaceProject._provided._ddIsImpactedTestsEnabled = isImpactedTestsEnabled
326
- workspaceProject._provided._ddModifiedTests = modifiedTests
326
+ workspaceProject._provided._ddModifiedFiles = modifiedFiles
327
327
  } catch {
328
328
  log.warn('Could not send modified tests to workers so Impacted Tests will not work.')
329
329
  }
@@ -464,7 +464,7 @@ addHook({
464
464
  testManagementAttemptToFixRetries,
465
465
  testManagementTests,
466
466
  isImpactedTestsEnabled,
467
- modifiedTests
467
+ modifiedFiles
468
468
  } = getProvidedContext()
469
469
 
470
470
  if (isTestManagementTestsEnabled) {
@@ -499,7 +499,7 @@ addHook({
499
499
 
500
500
  if (isImpactedTestsEnabled) {
501
501
  isModifiedCh.publish({
502
- modifiedTests,
502
+ modifiedFiles,
503
503
  testSuiteAbsolutePath: task.file.filepath,
504
504
  onDone: (isImpacted) => {
505
505
  if (isImpacted) {
@@ -0,0 +1,17 @@
1
+ 'use strict'
2
+
3
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
4
+ const AnthropicTracingPlugin = require('./tracing')
5
+ const AnthropicLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/anthropic')
6
+
7
+ class AnthropicPlugin extends CompositePlugin {
8
+ static id = 'anthropic'
9
+ static get plugins () {
10
+ return {
11
+ llmobs: AnthropicLLMObsPlugin,
12
+ tracing: AnthropicTracingPlugin
13
+ }
14
+ }
15
+ }
16
+
17
+ module.exports = AnthropicPlugin
@@ -0,0 +1,30 @@
1
+ 'use strict'
2
+
3
+ const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
4
+
5
+ class AnthropicTracingPlugin extends TracingPlugin {
6
+ static id = 'anthropic'
7
+ static operation = 'request'
8
+ static system = 'anthropic'
9
+ static prefix = 'tracing:apm:anthropic:request'
10
+
11
+ bindStart (ctx) {
12
+ const { resource, options } = ctx
13
+
14
+ this.startSpan('anthropic.request', {
15
+ meta: {
16
+ 'resource.name': `Messages.${resource}`,
17
+ 'anthropic.request.model': options.model
18
+ }
19
+ }, ctx)
20
+
21
+ return ctx.currentStore
22
+ }
23
+
24
+ asyncEnd (ctx) {
25
+ const span = ctx.currentStore?.span
26
+ span?.finish()
27
+ }
28
+ }
29
+
30
+ module.exports = AnthropicTracingPlugin
@@ -53,10 +53,13 @@ function extractTextAndResponseReasonFromStream (chunks, modelProvider, modelNam
53
53
 
54
54
  switch (modelProviderUpper) {
55
55
  case PROVIDER.AMAZON: {
56
- message += body?.outputText
57
-
58
- inputTokens = body?.inputTextTokenCount
59
- outputTokens = body?.totalOutputTextTokenCount
56
+ if (body?.outputText) {
57
+ message += body?.outputText
58
+ inputTokens = body?.inputTextTokenCount
59
+ outputTokens = body?.totalOutputTextTokenCount
60
+ } else if (body?.contentBlockDelta?.delta?.text) {
61
+ message += body.contentBlockDelta.delta.text
62
+ }
60
63
 
61
64
  break
62
65
  }
@@ -155,17 +158,16 @@ class RequestParams {
155
158
  stream = '',
156
159
  n
157
160
  } = {}) {
158
- // stringify prompt as it could be a single prompt as well as a list of message objects
159
- this.prompt = typeof prompt === 'string' ? prompt : JSON.stringify(prompt) || ''
160
- this.temperature = temperature === undefined ? undefined : temperature
161
- this.topP = topP === undefined ? undefined : topP
162
- this.topK = topK === undefined ? undefined : topK
163
- this.maxTokens = maxTokens === undefined ? undefined : maxTokens
161
+ this.prompt = prompt
162
+ this.temperature = temperature
163
+ this.topP = topP
164
+ this.topK = topK
165
+ this.maxTokens = maxTokens
164
166
  this.stopSequences = stopSequences || []
165
167
  this.inputType = inputType || ''
166
168
  this.truncate = truncate || ''
167
169
  this.stream = stream || ''
168
- this.n = n === undefined ? undefined : n
170
+ this.n = n
169
171
  }
170
172
  }
171
173
 
@@ -234,17 +236,48 @@ function extractRequestParams (params, provider) {
234
236
  })
235
237
  }
236
238
  case PROVIDER.AMAZON: {
239
+ const prompt = requestBody.inputText
237
240
  if (modelId.includes('embed')) {
238
- return new RequestParams({ prompt: requestBody.inputText })
241
+ return new RequestParams({ prompt })
242
+ } else if (prompt !== undefined) {
243
+ const textGenerationConfig = requestBody.textGenerationConfig || {}
244
+ return new RequestParams({
245
+ prompt,
246
+ temperature: textGenerationConfig.temperature,
247
+ topP: textGenerationConfig.topP,
248
+ maxTokens: textGenerationConfig.maxTokenCount,
249
+ stopSequences: textGenerationConfig.stopSequences
250
+ })
251
+ } else if (Array.isArray(requestBody.messages)) {
252
+ const inferenceConfig = requestBody.inferenceConfig || {}
253
+ const messages = []
254
+ if (Array.isArray(requestBody.system)) {
255
+ for (const sysMsg of requestBody.system) {
256
+ messages.push({
257
+ content: sysMsg.text,
258
+ role: 'system'
259
+ })
260
+ }
261
+ }
262
+ for (const message of requestBody.messages) {
263
+ const textBlocks = message.content?.filter(block => block.text) || []
264
+ if (textBlocks.length > 0) {
265
+ messages.push({
266
+ content: textBlocks.map(block => block.text).join(''),
267
+ role: message.role
268
+ })
269
+ }
270
+ }
271
+ return new RequestParams({
272
+ prompt: messages,
273
+ temperature: inferenceConfig.temperature,
274
+ topP: inferenceConfig.topP,
275
+ maxTokens: inferenceConfig.maxTokens,
276
+ stopSequences: inferenceConfig.stopSequences
277
+ })
239
278
  }
240
- const textGenerationConfig = requestBody.textGenerationConfig || {}
241
- return new RequestParams({
242
- prompt: requestBody.inputText,
243
- temperature: textGenerationConfig.temperature,
244
- topP: textGenerationConfig.topP,
245
- maxTokens: textGenerationConfig.maxTokenCount,
246
- stopSequences: textGenerationConfig.stopSequences
247
- })
279
+
280
+ return new RequestParams({ prompt })
248
281
  }
249
282
  case PROVIDER.ANTHROPIC: {
250
283
  let prompt = requestBody.prompt
@@ -350,14 +383,27 @@ function extractTextAndResponseReason (response, provider, modelName) {
350
383
  if (modelName.includes('embed')) {
351
384
  return new Generation({ message: body.embedding })
352
385
  }
353
- const results = body.results || []
354
- if (results.length > 0) {
355
- const result = results[0]
386
+ if (body.results) {
387
+ const results = body.results || []
388
+ if (results.length > 0) {
389
+ const result = results[0]
390
+ return new Generation({
391
+ message: result.outputText,
392
+ finishReason: result.completionReason,
393
+ inputTokens: body.inputTextTokenCount,
394
+ outputTokens: result.tokenCount
395
+ })
396
+ }
397
+ } else if (body.output) {
398
+ const output = body.output || {}
356
399
  return new Generation({
357
- message: result.outputText,
358
- finishReason: result.completionReason,
359
- inputTokens: body.inputTextTokenCount,
360
- outputTokens: result.tokenCount
400
+ message: output.message?.content[0]?.text ?? 'Unsupported content type',
401
+ finishReason: body.stopReason,
402
+ role: output.message?.role,
403
+ inputTokens: body.usage?.inputTokens,
404
+ outputTokens: body.usage?.outputTokens,
405
+ cacheReadInputTokenCount: body.usage?.cacheReadInputTokenCount,
406
+ cacheWriteInputTokenCount: body.usage?.cacheWriteInputTokenCount
361
407
  })
362
408
  }
363
409
  break
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+
3
+ const ProducerPlugin = require('./producer')
4
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
5
+
6
+ class AzureEventHubsPlugin extends CompositePlugin {
7
+ static get id () { return 'azure-event-hubs' }
8
+ static get plugins () {
9
+ return {
10
+ producer: ProducerPlugin
11
+ }
12
+ }
13
+ }
14
+
15
+ module.exports = AzureEventHubsPlugin