newrelic 13.19.2 → 13.20.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 (46) hide show
  1. package/NEWS.md +41 -0
  2. package/THIRD_PARTY_NOTICES.md +11 -11
  3. package/lib/collector/remote-method.js +3 -1
  4. package/lib/config/index.js +20 -0
  5. package/lib/context-manager/async-local-context-manager.js +1 -1
  6. package/lib/instrumentation/core/domain.js +2 -13
  7. package/lib/instrumentation/core/globals.js +0 -1
  8. package/lib/instrumentations.js +0 -3
  9. package/lib/llm-events/ai-agent.js +28 -0
  10. package/lib/llm-events/google-genai/chat-completion-message.js +6 -3
  11. package/lib/message-broker-description.js +29 -12
  12. package/lib/metrics/names.js +14 -8
  13. package/lib/subscriber-configs.js +4 -0
  14. package/lib/subscribers/amqplib/consume.js +1 -1
  15. package/lib/subscribers/aws-sdk/config.js +41 -3
  16. package/lib/subscribers/aws-sdk/core-send.js +16 -0
  17. package/lib/subscribers/aws-sdk/middleware/sqs/index.js +10 -13
  18. package/lib/subscribers/azure-functions/azure-handler-base.js +138 -0
  19. package/lib/subscribers/azure-functions/background-handler.js +29 -0
  20. package/lib/subscribers/azure-functions/config.js +44 -0
  21. package/lib/subscribers/azure-functions/http-handler.js +58 -0
  22. package/lib/subscribers/azure-functions/index.js +74 -0
  23. package/lib/subscribers/azure-functions/logger.js +72 -0
  24. package/lib/subscribers/connect/config.js +42 -0
  25. package/lib/subscribers/connect/use.js +31 -0
  26. package/lib/subscribers/google-adk/agent-run-async.js +119 -0
  27. package/lib/subscribers/google-adk/config.js +59 -0
  28. package/lib/subscribers/google-adk/tool-run-async.js +87 -0
  29. package/lib/subscribers/kafkajs/client-constructor.js +349 -0
  30. package/lib/subscribers/kafkajs/config.js +25 -0
  31. package/lib/subscribers/kafkajs/utils/record-data-metrics.js +48 -0
  32. package/lib/subscribers/kafkajs/utils/record-linking-metrics.js +30 -0
  33. package/lib/{instrumentation/kafkajs → subscribers/kafkajs/utils}/record-method-metric.js +3 -2
  34. package/lib/subscribers/langgraph/graph-stream.js +2 -1
  35. package/lib/subscribers/message-consumer-tools.js +161 -0
  36. package/lib/subscribers/message-consumer.js +43 -61
  37. package/lib/subscribers/undici/index.js +5 -7
  38. package/lib/transaction/tracer/index.js +26 -2
  39. package/package.json +2 -2
  40. package/lib/instrumentation/@azure/functions.js +0 -323
  41. package/lib/instrumentation/connect.js +0 -83
  42. package/lib/instrumentation/kafkajs/consumer.js +0 -145
  43. package/lib/instrumentation/kafkajs/index.js +0 -34
  44. package/lib/instrumentation/kafkajs/producer.js +0 -83
  45. package/lib/instrumentation/kafkajs/record-linking-metrics.js +0 -17
  46. package/lib/instrumentation/kafkajs.js +0 -7
package/NEWS.md CHANGED
@@ -1,3 +1,44 @@
1
+ ### v13.20.0 (2026-05-12)
2
+
3
+ #### Features
4
+
5
+ * Added instrumentation for Google ADK `BaseAgent.runAsync` ([#3905](https://github.com/newrelic/node-newrelic/pull/3905)) ([c6c51d5](https://github.com/newrelic/node-newrelic/commit/c6c51d56d24f59badef2de7b4710b87496080196))
6
+ * Instrument Google ADK `FunctionTool.runAsync` ([#3935](https://github.com/newrelic/node-newrelic/pull/3935)) ([57f9ed7](https://github.com/newrelic/node-newrelic/commit/57f9ed72dd905687a348d7d3bb3dcd39bfeedd53))
7
+ * Updated `@azure/functions` instrumentation to subscriber type ([#3915](https://github.com/newrelic/node-newrelic/pull/3915)) ([227e779](https://github.com/newrelic/node-newrelic/commit/227e779696f6b1e5c267884035b299233cef8cba))
8
+ * Updated how license keys are redacted in logs ([#3945](https://github.com/newrelic/node-newrelic/pull/3945)) ([6289502](https://github.com/newrelic/node-newrelic/commit/6289502ba49d88b8746ac8a42a34e5c2069f0d84))
9
+
10
+ #### Bug fixes
11
+
12
+ * Updated `connect` instrumentation queries to handle file restructure in `<3.4.0` ([#3923](https://github.com/newrelic/node-newrelic/pull/3923)) ([00b615c](https://github.com/newrelic/node-newrelic/commit/00b615c160c7251d1177482cf69a54e14d4d32a5))
13
+ * Updated `tracer.bindFunction` to touch segment if a promise is fulfilled or rejected ([#3967](https://github.com/newrelic/node-newrelic/pull/3967)) ([712db61](https://github.com/newrelic/node-newrelic/commit/712db6197e4a6a07c7f8e7a24d25f52141cfb236))
14
+ * Updated aws sdk v3 instrumentation to handle using `@smithy/smithy-client` 4.13.0+ ([#3965](https://github.com/newrelic/node-newrelic/pull/3965)) ([5e0fe24](https://github.com/newrelic/node-newrelic/commit/5e0fe249b011d6a269ca809827e7fb8f5d457ec9))
15
+
16
+ #### Code refactoring
17
+
18
+ * Removed reliance on `AsyncLocalStorage.enterWith` for undici, domain and `process._fatalException` instrumentation ([#3894](https://github.com/newrelic/node-newrelic/pull/3894)) ([612b449](https://github.com/newrelic/node-newrelic/commit/612b449f25d4a39fca399fa20058c74cd7e2b6c6))
19
+
20
+ #### Documentation
21
+
22
+ * Updated compatibility report ([#3941](https://github.com/newrelic/node-newrelic/pull/3941)) ([214b353](https://github.com/newrelic/node-newrelic/commit/214b3539cffad2397523d88aade40ccec3e3b7d2)) ([#3934](https://github.com/newrelic/node-newrelic/pull/3934)) ([5a962d4](https://github.com/newrelic/node-newrelic/commit/5a962d45485fad2c43001d20301542419279958d)) ([#3909](https://github.com/newrelic/node-newrelic/pull/3909)) ([ad6fa8a](https://github.com/newrelic/node-newrelic/commit/ad6fa8a2aac2e96c4d013c009055e9d757172a58))
23
+
24
+ #### Miscellaneous chores
25
+
26
+ * Added log line when `max_trace_segments` is hit ([#3933](https://github.com/newrelic/node-newrelic/pull/3933)) ([46b9238](https://github.com/newrelic/node-newrelic/commit/46b9238d057c84d63d61c23585b8078a4da453b2))
27
+ * Comment out `assertSegmentDuration` for `client-dynamodb` test ([#3972](https://github.com/newrelic/node-newrelic/pull/3972)) ([590cd3e](https://github.com/newrelic/node-newrelic/commit/590cd3e32e74d8c1c89d56d58bfb314c12050ab4))
28
+ * Fix issue with amqplib tests ([#3969](https://github.com/newrelic/node-newrelic/pull/3969)) ([a770000](https://github.com/newrelic/node-newrelic/commit/a770000447ecc2215b94472fcef022ee0ee7c5fb))
29
+ * Refactored Connect instrumentation to subscriber type ([#3912](https://github.com/newrelic/node-newrelic/pull/3912)) ([e5d87b7](https://github.com/newrelic/node-newrelic/commit/e5d87b7a97138c953cf4016440272c443c304119))
30
+ * Refactored kafkajs instrumentation to subscriber type ([#3958](https://github.com/newrelic/node-newrelic/pull/3958)) ([72e383c](https://github.com/newrelic/node-newrelic/commit/72e383c91ec26cdfd06ebb505b358623df829bd4))
31
+ * Remove `actualTime` vs `segmentDuration` assertion in `memcached` tests ([#3932](https://github.com/newrelic/node-newrelic/pull/3932)) ([98c50e0](https://github.com/newrelic/node-newrelic/commit/98c50e00bbf470cf2aedffe36f499525f0d335fe))
32
+ * Updated `@apm-js-collab/tracing-hooks` to `0.7.0` ([#3949](https://github.com/newrelic/node-newrelic/pull/3949)) ([5c99cd1](https://github.com/newrelic/node-newrelic/commit/5c99cd182796fdacfcfea45467eba6efce12b17d))
33
+
34
+ #### Tests
35
+
36
+ * Added `assertSegmentDuration` custom assertion and added it to `memcached` tests ([#3875](https://github.com/newrelic/node-newrelic/pull/3875)) ([b28d866](https://github.com/newrelic/node-newrelic/commit/b28d86688637ba4f1e74a243539dbea70e925e57))
37
+
38
+ #### Continuous integration
39
+
40
+ * Applied least-privilege model to all workflows to appease CodeQL ([#3961](https://github.com/newrelic/node-newrelic/pull/3961)) ([237d5b9](https://github.com/newrelic/node-newrelic/commit/237d5b9fe93e12e03601372886dc87c576116097))
41
+
1
42
  ### v13.19.2 (2026-04-20)
2
43
 
3
44
  #### Bug fixes
@@ -95,7 +95,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
95
95
 
96
96
  ### @apm-js-collab/tracing-hooks
97
97
 
98
- This product includes source derived from [@apm-js-collab/tracing-hooks](https://github.com/apm-js-collab/tracing-hooks) ([v0.6.0](https://github.com/apm-js-collab/tracing-hooks/tree/v0.6.0)), distributed under the [Apache-2.0 License](https://github.com/apm-js-collab/tracing-hooks/blob/v0.6.0/LICENSE):
98
+ This product includes source derived from [@apm-js-collab/tracing-hooks](https://github.com/apm-js-collab/tracing-hooks) ([v0.7.0](https://github.com/apm-js-collab/tracing-hooks/tree/v0.7.0)), distributed under the [Apache-2.0 License](https://github.com/apm-js-collab/tracing-hooks/blob/v0.7.0/LICENSE):
99
99
 
100
100
  ```
101
101
 
@@ -723,7 +723,7 @@ This product includes source derived from [@grpc/proto-loader](https://github.co
723
723
 
724
724
  ### @newrelic/security-agent
725
725
 
726
- This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v3.0.2](https://github.com/newrelic/csec-node-agent/tree/v3.0.2)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v3.0.2/LICENSE):
726
+ This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v3.0.3](https://github.com/newrelic/csec-node-agent/tree/v3.0.3)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v3.0.3/LICENSE):
727
727
 
728
728
  ```
729
729
  ## New Relic Software License v1.0
@@ -1187,7 +1187,7 @@ This product includes source derived from [@opentelemetry/api](https://github.co
1187
1187
 
1188
1188
  ### @opentelemetry/core
1189
1189
 
1190
- This product includes source derived from [@opentelemetry/core](https://github.com/open-telemetry/opentelemetry-js) ([v2.6.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.6.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.6.1/LICENSE):
1190
+ This product includes source derived from [@opentelemetry/core](https://github.com/open-telemetry/opentelemetry-js) ([v2.7.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.7.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.7.1/LICENSE):
1191
1191
 
1192
1192
  ```
1193
1193
  Apache License
@@ -1605,7 +1605,7 @@ This product includes source derived from [@opentelemetry/exporter-metrics-otlp-
1605
1605
 
1606
1606
  ### @opentelemetry/resources
1607
1607
 
1608
- This product includes source derived from [@opentelemetry/resources](https://github.com/open-telemetry/opentelemetry-js) ([v2.6.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.6.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.6.1/LICENSE):
1608
+ This product includes source derived from [@opentelemetry/resources](https://github.com/open-telemetry/opentelemetry-js) ([v2.7.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.7.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.7.1/LICENSE):
1609
1609
 
1610
1610
  ```
1611
1611
  Apache License
@@ -2023,7 +2023,7 @@ This product includes source derived from [@opentelemetry/sdk-logs](https://gith
2023
2023
 
2024
2024
  ### @opentelemetry/sdk-metrics
2025
2025
 
2026
- This product includes source derived from [@opentelemetry/sdk-metrics](https://github.com/open-telemetry/opentelemetry-js) ([v2.6.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.6.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.6.1/LICENSE):
2026
+ This product includes source derived from [@opentelemetry/sdk-metrics](https://github.com/open-telemetry/opentelemetry-js) ([v2.7.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.7.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.7.1/LICENSE):
2027
2027
 
2028
2028
  ```
2029
2029
  Apache License
@@ -2232,7 +2232,7 @@ This product includes source derived from [@opentelemetry/sdk-metrics](https://g
2232
2232
 
2233
2233
  ### @opentelemetry/sdk-trace-base
2234
2234
 
2235
- This product includes source derived from [@opentelemetry/sdk-trace-base](https://github.com/open-telemetry/opentelemetry-js) ([v2.6.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.6.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.6.1/LICENSE):
2235
+ This product includes source derived from [@opentelemetry/sdk-trace-base](https://github.com/open-telemetry/opentelemetry-js) ([v2.7.1](https://github.com/open-telemetry/opentelemetry-js/tree/v2.7.1)), distributed under the [Apache-2.0 License](https://github.com/open-telemetry/opentelemetry-js/blob/v2.7.1/LICENSE):
2236
2236
 
2237
2237
  ```
2238
2238
  Apache License
@@ -2961,7 +2961,7 @@ SOFTWARE.
2961
2961
 
2962
2962
  ### @aws-sdk/client-s3
2963
2963
 
2964
- This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.1019.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.1019.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.1019.0/LICENSE):
2964
+ This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.1039.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.1039.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.1039.0/LICENSE):
2965
2965
 
2966
2966
  ```
2967
2967
  Apache License
@@ -3170,7 +3170,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
3170
3170
 
3171
3171
  ### @aws-sdk/s3-request-presigner
3172
3172
 
3173
- This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.1019.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.1019.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.1019.0/LICENSE):
3173
+ This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.1039.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.1039.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.1039.0/LICENSE):
3174
3174
 
3175
3175
  ```
3176
3176
  Apache License
@@ -4511,7 +4511,7 @@ Apache License
4511
4511
 
4512
4512
  ### ajv
4513
4513
 
4514
- This product includes source derived from [ajv](https://github.com/ajv-validator/ajv) ([v6.14.0](https://github.com/ajv-validator/ajv/tree/v6.14.0)), distributed under the [MIT License](https://github.com/ajv-validator/ajv/blob/v6.14.0/LICENSE):
4514
+ This product includes source derived from [ajv](https://github.com/ajv-validator/ajv) ([v6.15.0](https://github.com/ajv-validator/ajv/tree/v6.15.0)), distributed under the [MIT License](https://github.com/ajv-validator/ajv/blob/v6.15.0/LICENSE):
4515
4515
 
4516
4516
  ```
4517
4517
  The MIT License (MIT)
@@ -4829,7 +4829,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4829
4829
 
4830
4830
  ### clean-jsdoc-theme
4831
4831
 
4832
- This product includes source derived from [clean-jsdoc-theme](https://github.com/ankitskvmdam/clean-jsdoc-theme) ([v4.3.0](https://github.com/ankitskvmdam/clean-jsdoc-theme/tree/v4.3.0)), distributed under the [MIT License](https://github.com/ankitskvmdam/clean-jsdoc-theme/blob/v4.3.0/LICENSE):
4832
+ This product includes source derived from [clean-jsdoc-theme](https://github.com/ankitskvmdam/clean-jsdoc-theme) ([v4.3.2](https://github.com/ankitskvmdam/clean-jsdoc-theme/tree/v4.3.2)), distributed under the [MIT License](https://github.com/ankitskvmdam/clean-jsdoc-theme/blob/v4.3.2/LICENSE):
4833
4833
 
4834
4834
  ```
4835
4835
  MIT License
@@ -5530,7 +5530,7 @@ SOFTWARE.
5530
5530
 
5531
5531
  ### protobufjs
5532
5532
 
5533
- This product includes source derived from [protobufjs](https://github.com/protobufjs/protobuf.js) ([v7.5.4](https://github.com/protobufjs/protobuf.js/tree/v7.5.4)), distributed under the [BSD-3-Clause License](https://github.com/protobufjs/protobuf.js/blob/v7.5.4/LICENSE):
5533
+ This product includes source derived from [protobufjs](https://github.com/protobufjs/protobuf.js) ([v7.5.6](https://github.com/protobufjs/protobuf.js/tree/v7.5.6)), distributed under the [BSD-3-Clause License](https://github.com/protobufjs/protobuf.js/blob/v7.5.6/LICENSE):
5534
5534
 
5535
5535
  ```
5536
5536
  This license applies to all parts of protobuf.js except those files
@@ -354,7 +354,9 @@ RemoteMethod.prototype._path = function _path({ redactLicenseKey } = {}) {
354
354
  const query = {
355
355
  marshal_format: 'json',
356
356
  protocol_version: this._protocolVersion,
357
- license_key: redactLicenseKey ? 'REDACTED' : this._config.license_key,
357
+ license_key: redactLicenseKey
358
+ ? this._config.redacted_license_key
359
+ : this._config.license_key,
358
360
  method: this.name
359
361
  }
360
362
 
@@ -1470,6 +1470,8 @@ Config.prototype._canonicalize = function _canonicalize() {
1470
1470
  if (this.license_key) {
1471
1471
  this.license_key = this.license_key.trim()
1472
1472
  }
1473
+
1474
+ this.redacted_license_key = redactLicenseKey(this.license_key)
1473
1475
  }
1474
1476
 
1475
1477
  /**
@@ -1727,6 +1729,24 @@ function redactValue(value) {
1727
1729
  return result
1728
1730
  }
1729
1731
 
1732
+ /**
1733
+ * Redact a license key, preserving its original length.
1734
+ * The first 10 characters remain visible; the rest are replaced with '*'.
1735
+ * Keys of 10 or fewer characters are fully redacted.
1736
+ *
1737
+ * @param {string} key the license key to redact
1738
+ * @returns {string} the redacted key
1739
+ */
1740
+ function redactLicenseKey(key) {
1741
+ if (!key) {
1742
+ return ''
1743
+ }
1744
+ if (key.length <= 10) {
1745
+ return '*'.repeat(key.length)
1746
+ }
1747
+ return key.substring(0, 10) + '*'.repeat(key.length - 10)
1748
+ }
1749
+
1730
1750
  /**
1731
1751
  * Get a JSONifiable object containing all settings we want to report to the
1732
1752
  * collector and store in the environment_values table.
@@ -35,7 +35,7 @@ class AsyncLocalContextManager {
35
35
 
36
36
  /**
37
37
  * Set a new active context. Not bound to function execution.
38
- * The AsyncLocalStorage method is considered experimental
38
+ * **Note**: Should only be used in tests
39
39
  *
40
40
  * @param {object} newContext The context to set as active.
41
41
  */
@@ -13,19 +13,8 @@ function initialize(agent, domain, name, shim) {
13
13
 
14
14
  function wrapEmit(shim, original) {
15
15
  return function wrappedEmit(ev) {
16
- const shouldRestoreContext =
17
- ev === 'error' && shim.getActiveSegment() === null && shim.getSegment(this)
18
-
19
- if (!shouldRestoreContext) {
20
- return original.apply(this, arguments)
21
- }
22
-
23
- shim.setActiveSegment(shim.getSegment(this))
24
- try {
25
- return original.apply(this, arguments)
26
- } finally {
27
- shim.setActiveSegment(null)
28
- }
16
+ const ctx = agent.tracer.getContext()
17
+ return agent.tracer.bindFunction(original, ctx).apply(this, arguments)
29
18
  }
30
19
  }
31
20
  }
@@ -27,7 +27,6 @@ function initialize(agent, nodule, name, shim) {
27
27
  !exceptionCallbackRegistered
28
28
  ) {
29
29
  agent.errors.add(null, error)
30
- shim.setActiveSegment(null)
31
30
  }
32
31
  return original.apply(this, arguments)
33
32
  }
@@ -10,14 +10,11 @@ const InstrumentationDescriptor = require('./instrumentation-descriptor')
10
10
  // Return a new copy of this array every time we're called
11
11
  module.exports = function instrumentations() {
12
12
  return {
13
- '@azure/functions': { type: InstrumentationDescriptor.TYPE_GENERIC },
14
13
  '@hapi/hapi': { type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK },
15
14
  '@hapi/vision': { type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK },
16
15
  '@prisma/client': { type: InstrumentationDescriptor.TYPE_DATASTORE },
17
16
  'aws-sdk': { module: './instrumentation/aws-sdk' },
18
- connect: { type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK },
19
17
  fastify: { type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK },
20
- kafkajs: { type: InstrumentationDescriptor.TYPE_MESSAGE },
21
18
  koa: { module: './instrumentation/koa' },
22
19
  mongodb: { type: InstrumentationDescriptor.TYPE_DATASTORE },
23
20
  next: { module: './instrumentation/nextjs' },
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright 2026 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+
8
+ const LlmEvent = require('./event-base')
9
+
10
+ /**
11
+ * Encapsulates a LlmAgent event which represents an
12
+ * AI agent invocation.
13
+ */
14
+ module.exports = class LlmAgent extends LlmEvent {
15
+ /**
16
+ * @param {object} params constructor parameters
17
+ * @param {Agent} params.agent New Relic agent instance
18
+ * @param {object} params.segment Current segment
19
+ * @param {object} params.transaction Current and active transaction
20
+ * @param {string} params.aiAgentName Name of the AI agent
21
+ * @param {string} params.vendor Name of the AI agent vendor e.g. 'langgraph'
22
+ * @param {boolean} [params.error] Set to `true` if an error occurred
23
+ */
24
+ constructor({ agent, segment, transaction, aiAgentName, vendor, error }) {
25
+ super({ agent, segment, transaction, vendor, error })
26
+ this.name = aiAgentName ?? 'agent'
27
+ }
28
+ }
@@ -21,16 +21,19 @@ module.exports = class GoogleGenAiLlmChatCompletionMessage extends LlmChatComple
21
21
  content, role,
22
22
  completionId,
23
23
  isResponse }) {
24
- super({ agent,
24
+ super({
25
+ agent,
25
26
  segment,
26
27
  transaction,
27
28
  vendor: 'gemini',
28
29
  sequence,
29
- content,
30
+ // When sent via Google ADK, the 'content' lives at `content.parts[0].text`
31
+ content: content?.parts?.[0]?.text ?? content,
30
32
  role,
31
33
  completionId,
32
34
  isResponse,
33
- responseModel: response?.modelVersion })
35
+ responseModel: response?.modelVersion
36
+ })
34
37
 
35
38
  this.setTokenCount(agent, request, response)
36
39
  }
@@ -69,6 +69,14 @@ class MessageBrokerDescription {
69
69
  */
70
70
  #destinationType = undefined
71
71
 
72
+ /**
73
+ * When set to `false`, the string "MessageBroker" will be omitted from
74
+ * the start of the {@link #segmentName}.
75
+ *
76
+ * @type {boolean}
77
+ */
78
+ #includeMessageBrokerPrefix = undefined
79
+
72
80
  /**
73
81
  * @param {object} params Constructor parameters.
74
82
  * @param {string} params.libraryName Name of the system being targeted,
@@ -80,6 +88,8 @@ class MessageBrokerDescription {
80
88
  * @param {string} [params.destinationType] Classification name for the target
81
89
  * queue, e.g. `Queue` or `Topic`. Should be one of the `DESTINATION_TYPE_*`
82
90
  * constants.
91
+ * @param {boolean} [params.includeMessageBrokerPrefix] Indicates if the
92
+ * segment name should start with the string "MessageBroker" or not.
83
93
  * @param {string} [params.mode] Indicates the communication mode for the
84
94
  * current action. Should be one of `BROKER_MODE_CONSUME` or
85
95
  * `BROKER_MODE_PRODUCE`.
@@ -88,35 +98,42 @@ class MessageBrokerDescription {
88
98
  libraryName,
89
99
  destinationName = undefined,
90
100
  destinationType = MessageBrokerDescription.DESTINATION_TYPE_EXCHANGE,
91
- mode = MessageBrokerDescription.BROKER_MODE_PRODUCE
101
+ mode = MessageBrokerDescription.BROKER_MODE_PRODUCE,
102
+ includeMessageBrokerPrefix = true
92
103
  }) {
104
+ this.#includeMessageBrokerPrefix = includeMessageBrokerPrefix
93
105
  this.#mode = mode
94
106
  this.#library = libraryName
95
107
  this.#destinationName = destinationName
96
108
  this.#destinationType = destinationType
97
109
 
98
- const upperLibraryName = libraryName.toUpperCase()
99
- switch (upperLibraryName) {
100
- case 'AMQP':
101
- case 'IRONMQ':
102
- case 'KAFKA':
103
- case 'RABBITMQ': {
104
- this.#destinationType = MessageBrokerDescription[`TRANSPORT_TYPE_${upperLibraryName}`]
105
- break
110
+ if (!this.#destinationType) {
111
+ const upperLibraryName = libraryName.toUpperCase()
112
+ switch (upperLibraryName) {
113
+ case 'AMQP':
114
+ case 'IRONMQ':
115
+ case 'KAFKA':
116
+ case 'RABBITMQ': {
117
+ this.#destinationType = MessageBrokerDescription[`TRANSPORT_TYPE_${upperLibraryName}`]
118
+ break
119
+ }
106
120
  }
107
121
  }
108
122
  }
109
123
 
110
124
  get segmentName() {
111
- return [
112
- 'MessageBroker',
125
+ let segments = [
113
126
  this.#library,
114
127
  this.#destinationType,
115
128
  this.#mode,
116
129
  typeof this.#destinationName === 'string'
117
130
  ? `Named/${this.#destinationName}`
118
131
  : 'Temp'
119
- ].join('/')
132
+ ]
133
+ if (this.#includeMessageBrokerPrefix === true) {
134
+ segments = ['MessageBroker', ...segments]
135
+ }
136
+ return segments.join('/')
120
137
  }
121
138
  }
122
139
 
@@ -187,20 +187,20 @@ AI.ANTHROPIC = {
187
187
  COMPLETION: `${AI.COMPLETION}/Anthropic/create`
188
188
  }
189
189
 
190
+ AI.BEDROCK = {
191
+ TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/Bedrock`
192
+ }
193
+
190
194
  AI.GEMINI = {
191
195
  TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/Gemini`,
192
196
  EMBEDDING: `${AI.EMBEDDING}/Gemini/embed_content`,
193
197
  COMPLETION: `${AI.COMPLETION}/Gemini/generate_content`
194
198
  }
195
199
 
196
- AI.OPENAI = {
197
- TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/OpenAI`,
198
- EMBEDDING: `${AI.EMBEDDING}/OpenAI/create`,
199
- COMPLETION: `${AI.COMPLETION}/OpenAI/create`
200
- }
201
-
202
- AI.BEDROCK = {
203
- TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/Bedrock`
200
+ AI.GOOGLE_ADK = {
201
+ TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/GoogleADK`,
202
+ AGENT: `${AI.AGENT}/GoogleADK`,
203
+ TOOL: `${AI.TOOL}/GoogleADK`,
204
204
  }
205
205
 
206
206
  AI.LANGCHAIN = {
@@ -217,6 +217,12 @@ AI.LANGGRAPH = {
217
217
  AGENT: `${AI.AGENT}/LangGraph`
218
218
  }
219
219
 
220
+ AI.OPENAI = {
221
+ TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/OpenAI`,
222
+ EMBEDDING: `${AI.EMBEDDING}/OpenAI/create`,
223
+ COMPLETION: `${AI.COMPLETION}/OpenAI/create`
224
+ }
225
+
220
226
  const MCP = {
221
227
  TRACKING_PREFIX: `${AI.TRACKING_PREFIX}/MCP`,
222
228
  TOOL: `${AI.TOOL}/MCP`,
@@ -11,16 +11,20 @@ const subscribers = {
11
11
  ...require('./subscribers/amqplib/config'),
12
12
  ...require('./subscribers/anthropic-sdk/config'),
13
13
  ...require('./subscribers/aws-sdk/config'),
14
+ ...require('./subscribers/azure-functions/config'),
14
15
  ...require('./subscribers/bluebird/config'),
15
16
  ...require('./subscribers/bunyan/config'),
16
17
  ...require('./subscribers/cassandra-driver/config'),
18
+ ...require('./subscribers/connect/config'),
17
19
  ...require('./subscribers/elasticsearch/config'),
18
20
  ...require('./subscribers/express/config'),
19
21
  ...require('./subscribers/fastify/config'),
22
+ ...require('./subscribers/google-adk/config'),
20
23
  ...require('./subscribers/google-genai/config'),
21
24
  ...require('./subscribers/grpcjs/config'),
22
25
  ...require('./subscribers/ioredis/config'),
23
26
  ...require('./subscribers/iovalkey/config'),
27
+ ...require('./subscribers/kafkajs/config'),
24
28
  ...require('./subscribers/langchain/config'),
25
29
  ...require('./subscribers/langgraph/config'),
26
30
  ...require('./subscribers/mcp-sdk/config'),
@@ -37,7 +37,7 @@ class ConsumeSubscriber extends MessageConsumerSubscriber {
37
37
  this.consumerParameters = getParametersFromMessage.call(this, { channel: data?.self, message })
38
38
  this.headers = message?.properties?.headers
39
39
  this.destination = this.getExchange(message?.fields)
40
- this.queue = queue
40
+ this.consumerParameters.queue = queue
41
41
 
42
42
  super.asyncStart(data)
43
43
  }
@@ -3,13 +3,48 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
+ const coreSendConfig = {
7
+ path: './aws-sdk/core-send.js',
8
+ instrumentations: [
9
+ // CJS
10
+ {
11
+ channelName: 'nr_send',
12
+ module: { name: '@smithy/core', versionRange: '>=3.24.0', filePath: 'dist-cjs/submodules/client/index.js' },
13
+ functionQuery: {
14
+ className: 'Client',
15
+ methodName: 'send',
16
+ kind: 'Sync'
17
+ }
18
+ },
19
+ // ESM
20
+ {
21
+ channelName: 'nr_send',
22
+ module: { name: '@smithy/core', versionRange: '>=3.24.0', filePath: 'dist-es/submodules/client/smithy-client/client.js' },
23
+ functionQuery: {
24
+ className: 'Client',
25
+ methodName: 'send',
26
+ kind: 'Sync'
27
+ }
28
+ }
29
+ ]
30
+ }
31
+
6
32
  const sendConfig = {
7
33
  path: './aws-sdk/send.js',
8
34
  instrumentations: [
9
35
  // CJS
10
36
  {
11
37
  channelName: 'nr_send',
12
- module: { name: '@smithy/smithy-client', versionRange: '>=4.0.0', filePath: 'dist-cjs/index.js' },
38
+ module: { name: '@smithy/smithy-client', versionRange: '>=4.0.0 <4.13.0', filePath: 'dist-cjs/index.js' },
39
+ functionQuery: {
40
+ className: 'Client',
41
+ methodName: 'send',
42
+ kind: 'Sync'
43
+ }
44
+ },
45
+ {
46
+ channelName: 'nr_send',
47
+ module: { name: '@smithy/smithy-client', versionRange: '>=4.0.0 <4.13.0', filePath: 'dist-cjs/index.js' },
13
48
  functionQuery: {
14
49
  className: 'Client',
15
50
  methodName: 'send',
@@ -28,7 +63,7 @@ const sendConfig = {
28
63
  // ESM
29
64
  {
30
65
  channelName: 'nr_send',
31
- module: { name: '@smithy/smithy-client', versionRange: '>=4.0.0', filePath: 'dist-es/index.js' },
66
+ module: { name: '@smithy/smithy-client', versionRange: '>=4.0.0 <4.13.0', filePath: 'dist-es/index.js' },
32
67
  functionQuery: {
33
68
  className: 'Client',
34
69
  methodName: 'send',
@@ -99,5 +134,8 @@ module.exports = {
99
134
  '@aws-sdk/smithy-client':
100
135
  [
101
136
  legacySendConfig
102
- ]
137
+ ],
138
+ '@smithy/core': [
139
+ coreSendConfig
140
+ ]
103
141
  }
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright 2026 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ 'use strict'
6
+ const SmithyClientSendSubscriber = require('./send')
7
+
8
+ /**
9
+ * Extends SmithyClientSendSubscriber to handle the new Client.send in `@smithy/core`
10
+ * package, which newer versions of AWS SDK v3 versions depend on instead of `@smithy/smithy-client`.
11
+ */
12
+ module.exports = class CoreClientSendSubscriber extends SmithyClientSendSubscriber {
13
+ constructor({ agent, logger }) {
14
+ super({ agent, logger, packageName: '@smithy/core' })
15
+ }
16
+ }
@@ -47,7 +47,7 @@ function sqsMiddleware(subscriber, config, next, context) {
47
47
  }
48
48
 
49
49
  subscriber.opaque = true
50
- return function nrSqsMiddleware(...args) {
50
+ return async function nrSqsMiddleware(...args) {
51
51
  const ctx = agent.tracer.getContext()
52
52
  if (!ctx.transaction || ctx.transaction.isActive() === false) {
53
53
  return next(...args)
@@ -84,22 +84,19 @@ function sqsMiddleware(subscriber, config, next, context) {
84
84
  segment.addAttribute('messaging.destination.name', queue)
85
85
 
86
86
  const fn = agent.tracer.bindFunction(next, newCtx, true)
87
- const result = fn(...args)
87
+ const response = await fn(...args)
88
88
  if (mode === MessageBrokerDesc.BROKER_MODE_PRODUCE) {
89
- return result
89
+ return response
90
90
  }
91
91
 
92
92
  // aws-sdk@3 only returns promises from `.send`.
93
- return result
94
- .then((response) => {
95
- const message = response?.output?.Messages?.[0] || {}
96
- const headers = retrieveHeaders({ message })
97
- newCtx.transaction.addDtCatHeaders({
98
- headers,
99
- transport: MessageBrokerDesc.TRANSPORT_TYPE_QUEUE
100
- })
101
- return response
102
- })
93
+ const message = response?.output?.Messages?.[0] || {}
94
+ const headers = retrieveHeaders({ message })
95
+ newCtx.transaction.addDtCatHeaders({
96
+ headers,
97
+ transport: MessageBrokerDesc.TRANSPORT_TYPE_QUEUE
98
+ })
99
+ return response
103
100
  }
104
101
  }
105
102